您的位置:首页 >聚焦 >

第七届XCTF国际联赛的分站赛SUSCTF|WP

2022-03-05 18:48:23    来源:程序员客栈

本文来自“白帽子社区知识星球”

作者:白帽子社区

白帽子社区知识星球加入星球,共同进步01Web

fxxkcors

访问report

创建一个html表单来访问修改权限的api,将我们的权限改为管理权限。

<script> var a=document.getElementById("sss"); a.submit();</script>

在report中填入文件url并submit,因为admin will view your report soon,故可以触发该文件达到修改权限的目的

正常登录即可发现我们的权限已经修改

02MISC

checkin

根据提示访问官方Discord,然后私聊Bot

发送>flag之后,官方会发送flag,不过会马上消失,手脚麻利点快速截图就可以了

Tanner

参考:https://zhuanlan.zhihu.com/p/148228662

得到矩阵

然后使用脚本爆破码字即可

import hashlibi = 0sum = 0while i <= 0b1111111111:c = str(bin(i)[2:]).zfill(10)[::-1]if (int(c[0]) ^ int(c[1]) ^ int(c[2]) ^ int(c[3]) == 0) and \(int(c[0]) ^ int(c[4]) ^ int(c[5]) ^ int(c[6]) == 0) and \(int(c[1]) ^ int(c[4]) ^ int(c[7]) ^ int(c[8]) == 0) and \(int(c[2]) ^ int(c[5]) ^ int(c[7]) ^ int(c[9]) == 0) and \(int(c[3]) ^ int(c[6]) ^ int(c[8]) ^ int(c[9]) == 0):sum += int(c, 2)i += 1print(sum)print(bin(sum))s = str(bin(sum)[2:])HASH = hashlib.sha256(s.encode()).hexdigest()print(s)print("SUSCTF{"+HASH+"}")PS C:\Users\Administrator\Downloads> python .\code.py327360b111111111100000111111111100000SUSCTF{c17019990bf57492cddf24f3cc3be588507b2d567934a101d4de2fa6d606b5c1}

AUDIO

同一首歌,响度不同,分析波形猜测fromfriends.wav添加了东西

利用AodbeAudition打开,建立多轨,全选中fromfriends.wav,反向,然后调整响度,使得fromfriends.wav的波形尽量和原声相同,这样就会抵消掉大部分原声相同的波形

导出多轨

查看多轨的频谱图,即可发现摩斯码

... ..- ... -.-. - ..-. -- .- ... - . .-. --- ..-. .- ..- -.. .. ---

利用在线站转换:http://www.zhongguosou.com/zonghe/moErSiCodeConverter.aspx

SUSCTFMASTEROFAUDIO

得到flag

SUSCTF{MASTEROFAUDIO}

misound

首先,附件听起来是SSTV,不过有很多间断处,导致直接转换成图像并不清晰

Rdll_dx.wav存在LSB隐写,使用SlientEye可解出

207 359 220 224 352 315 359 374 290 310 277 507 391 513 423 392 508 383 440 322 420 427 503 460 295 318 245 302 407 414 410 130 369 317

Audacity打开查看频谱可发现间断出存在字母

AnEWmuLTiPLyis_etimes_wiLLbEcomE_B

使用Audacity手工去掉间断部分,缝合干净一点,转换:https://github.com/colaclanth/sstv

Dotsies-writing解码:https://www.dcode.fr/dotsies-writing

NQHFEAOUUUSHLMCJQRFLFNMKHQAOLDWBBI

但是这里的解法并没有用到这串代码,利用flag前缀做一个测试,发现与hint字符串的ascii相乘,然后除数字列表对应的数字,会得到一个固定的数字26

那么就可以反推flag

num_list = [207, 359, 220, 224, 352, 315, 359, 374, 290, 310, 277, 507, 391, 513, 423, 392, 508, 383, 440, 322, 420, 427, 503, 460, 295, 318, 245, 302, 407, 414, 410, 130, 369, 317]chars = "AnEWmuLTiPLyis_etimes_wiLLbEcomE_B"code = "NQHFEAOUUUSHLMCJQRFLFNMKHQAOLDWBBI"# prefix_flag = "SUSCTF{"# for i in range(len(prefix_flag)):# res = ord(prefix_flag[i]) * ord(chars[i]) / num_list[i]# print(res)for i in range(len(chars)):flag = round((num_list[i] * 26) / ord(chars[i]))print(chr(flag), end="")PS C:\Users\Administrator\Downloads\misound> python .\exp.pySUSCTF{tHe_matter_iS_unremArkab1e}

03Reverse

DigitalCircuits

下载附件得到exe,ida64打开发现py字样得知该文件是从py打包的。使用pyinstxtractor.py+uncompyle6-pyc反编译基本套路将py代码还原

# uncompyle6 version 3.8.0# Python bytecode 3.7.0 (3394)# Decompiled from: Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]# Embedded file name: DigitalCircuits.py# Compiled at: 1995-09-28 00:18:56# Size of source mod 2**32: 257 bytesimport timedef f1(a, b):    if a == "1":        if b == "1":            return "1"    return "0"def f2(a, b):    if a == "0":        if b == "0":            return "0"    return "1"def f3(a):    if a == "1":        return "0"    if a == "0":        return "1"def f4(a, b):    return f2(f1(a, f3(b)), f1(f3(a), b))def f5(x, y, z):    s = f4(f4(x, y), z)    c = f2(f1(x, y), f1(z, f2(x, y)))    return (s, c)def f6(a, b):    ans = ""    z = "0"    a = a[::-1]    b = b[::-1]    for i in range(32):        ans += f5(a[i], b[i], z)[0]        z = f5(a[i], b[i], z)[1]    return ans[::-1]def f7(a, n):    return a[n:] + "0" * ndef f8(a, n):    return n * "0" + a[:-n]def f9(a, b):    ans = ""    for i in range(32):        ans += f4(a[i], b[i])    return ansdef f10(v0, v1, k0, k1, k2, k3):    s = "00000000000000000000000000000000"    d = "10011110001101110111100110111001"    for i in range(32):        s = f6(s, d)        v0 = f6(v0, f9(f9(f6(f7(v1, 4), k0), f6(v1, s)), f6(f8(v1, 5), k1)))        v1 = f6(v1, f9(f9(f6(f7(v0, 4), k2), f6(v0, s)), f6(f8(v0, 5), k3)))    return v0 + v1k0 = "0100010001000101".zfill(32)k1 = "0100000101000100".zfill(32)k2 = "0100001001000101".zfill(32)k3 = "0100010101000110".zfill(32)flag = input("please input flag:")if flag[0:7] != "SUSCTF{" or flag[(-1)] != "}":    print("Error!!!The formate of flag is SUSCTF{XXX}")    time.sleep(5)    exit(0)flagstr = flag[7:-1]if len(flagstr) != 24:    print("Error!!!The length of flag 24")    time.sleep(5)    exit(0)else:    res = ""    for i in range(0, len(flagstr), 8):        v0 = flagstr[i:i + 4]        v0 = bin(ord(flagstr[i]))[2:].zfill(8) + bin(ord(flagstr[(i + 1)]))[2:].zfill(8) + bin(ord(flagstr[(i + 2)]))[2:].zfill(8) + bin(ord(flagstr[(i + 3)]))[2:].zfill(8)        v1 = bin(ord(flagstr[(i + 4)]))[2:].zfill(8) + bin(ord(flagstr[(i + 5)]))[2:].zfill(8) + bin(ord(flagstr[(i + 6)]))[2:].zfill(8) + bin(ord(flagstr[(i + 7)]))[2:].zfill(8)        res += f10(v0, v1, k0, k1, k2, k3)    if res == "001111101000100101000111110010111100110010010100010001100011100100110001001101011000001110001000001110110000101101101000100100111101101001100010011100110110000100111011001011100110010000100111":        print("True")    else:        print("False")time.sleep(5)

结合题目DigitalCircuits审计代码得知,此程序为用数字电路逻辑的方式编写的tea加密,直接逆代码得到flag

from Crypto.Util.number import long_to_bytes, bytes_to_long# 与操作def f1(a, b):    if a == "1":        if b == "1":            return "1"    return "0"# 或操作def f2(a, b):    if a == "0":        if b == "0":            return "0"    return "1"# 非操作def f3(a):    if a == "1":        return "0"    if a == "0":        return "1"# 异或  同0异1def f4(a, b):    return f2(f1(a, f3(b)), f1(f3(a), b))# s:三个数同0异1 c:有两个以上1出1def f5(x, y, z):    s = f4(f4(x, y), z)    c = f2(f1(x, y), f1(z, f2(x, y)))    return (s, c)# 全加器def f6(a, b):    ans = ""    z = "0"    # a反向    a = a[::-1]    # b反向    b = b[::-1]    # 从高位到低位    for i in range(32):        ans += f5(a[i], b[i], z)[0]        z = f5(a[i], b[i], z)[1]    # 低位到高位    return ans[::-1]# 逻辑左移def f7(a, n):    return a[n:] + "0" * n# 逻辑右移def f8(a, n):    return n * "0" + a[:-n]# 两个32位字符串异或def f9(a, b):    ans = ""    for i in range(32):        ans += f4(a[i], b[i])    return ans# tea加密def f10(v0, v1, k0, k1, k2, k3):    s = "00000000000000000000000000000000"    d = "10011110001101110111100110111001"    for i in range(32):        s = f6(s, d)        v0 = f6(v0, f9(f9(f6(f7(v1, 4), k0), f6(v1, s)), f6(f8(v1, 5), k1)))        v1 = f6(v1, f9(f9(f6(f7(v0, 4), k2), f6(v0, s)), f6(f8(v0, 5), k3)))    return v0 + v1# f1与 f2或 f3非 f4异或 f5 f6# 全减器def re_f6(a, b):    ans = ""    z = "0"    # a反向    a = a[::-1]    # b反向    b = b[::-1]    # 低位到高位    for i in range(32):        ans += f5(a[i], b[i], z)[0]        z = f2(f1(f3(a[i]), f2(b[i], z)), f1(b[i], z))    # ans反向    return ans[::-1]re_s = ["11000110111011110011011100100000", "00101000101101111011110101100111", "10001010100000000100001110101110",        "11101100010010001100100111110101", "01001110000100010101000000111100", "10101111110110011101011010000011",        "00010001101000100101110011001010", "01110011011010101110001100010001", "11010101001100110110100101011000",        "00110110111110111110111110011111", "10011000110001000111010111100110", "11111010100011001111110000101101",        "01011100010101011000001001110100", "10111110000111100000100010111011", "00011111111001101000111100000010",        "10000001101011110001010101001001", "11100011011101111001101110010000", "01000101010000000010000111010111",        "10100111000010001010100000011110", "00001000110100010010111001100101", "01101010100110011011010010101100",        "11001100011000100011101011110011", "00101110001010101100000100111010", "10001111111100110100011110000001",        "11110001101110111100110111001000", "01010011100001000101010000001111", "10110101010011001101101001010110",        "00010111000101010110000010011101", "01111000110111011110011011100100", "11011010101001100110110100101011",        "00111100011011101111001101110010", "10011110001101110111100110111001"]# f1与 f2或 f3非 f4异或 f5 f6# tea解密def re_f10(v0, v1, k0, k1, k2, k3):    s = "11000110111011110011011100100000"    d = "10011110001101110111100110111001"    for i in range(32):        s = re_s[i]        v1 = re_f6(v1, f9(f9(f6(f7(v0, 4), k2), f6(v0, s)), f6(f8(v0, 5), k3)))        v0 = re_f6(v0, f9(f9(f6(f7(v1, 4), k0), f6(v1, s)), f6(f8(v1, 5), k1)))    return v0 + v1k0 = "0100010001000101".zfill(32)k1 = "0100000101000100".zfill(32)k2 = "0100001001000101".zfill(32)k3 = "0100010101000110".zfill(32)m = ["00111110100010010100011111001011",     "11001100100101000100011000111001",     "00110001001101011000001110001000",     "00111011000010110110100010010011",     "11011010011000100111001101100001",     "00111011001011100110010000100111", ]a = ""for i in range(0, 6, 2):    v0 = m[i]    v1 = m[i + 1]    a += re_f10(v0, v1, k0, k1, k2, k3)print(a)t = int(a, 2)print(b"SUSCTF{" + long_to_bytes(t) + b"}")# b"SUSCTF{XBvfaEdQvbcrxPBh8AOcJ6gA}"

如果觉得本文不错的话,欢迎加入知识星球,星球内部设立了多个技术版块,目前涵盖“WEB安全”、“内网渗透”、“CTF技术区”、“漏洞分析”、“工具分享”五大类,还可以与嘉宾大佬们接触,在线答疑、互相探讨。

▼扫码关注白帽子社区公众号&加入知识星球▼

关键词: 管理权限 同一首歌 就可以了

相关阅读