2024 ISCTF逆向方向部分wp
1438911687251843 发表于 江西 CTF 236浏览 · 2024-11-15 09:44

Ezre

加密部分

加密逻辑很简单,没什么好说的

a = list('QKEMK{7JB5_i5_W3SllD_3z_W3}')
b = 'ISCTF'
for i in range(len(a)):
    v7 = ord(a[i])
    if 'A' <= chr(v7) <= 'Z':
        v7 = (v7 - ord(b[i%5])) % 26 + ord('A')
    a[i] = chr(v7)
print(''.join(a))

ISCTF{7HI5_i5_R3AllY_3z_R3}

你知道elf文件吗

使用ubuntu24运行,报错

看这个报错猜测只能在较低版本linux下运行,使用ubuntu20运行

《回忆安魂曲》--第二章:当记忆被割裂

ida反编译不了,所有函数都爆红,但是看汇编并没有花指令,汇编很正常,果断开始调试

先随便输入,直到进入check函数

注意到每一个函数都有一个很明显的特点,就是先把子函数存入寄存器,然后再一个一个调用

直接F4进入第一个子函数

检测输入长度为36位,重新开始调试,随便输入36位字符串

在右边的寄存器栏可以看到输入的字符串存在堆中

一路F8,直到看到enc函数,看名字是加密函数,F7步入看逻辑

发现key,继续调试

发现变量ans,继续调试

第一轮循环中,运行到这里

fun3:

分析:第1行将轮数[rbp-58h]存入eax,第3行将对应轮数的key即[rbp - 45h]存入eax,第4行将轮数和key相加,第7行将和与[rbp-46h]的内容异或

fun1:

注意到,在enc的子函数fun1中[rbp-46h]被赋值过

分析:第1行将轮数存入eax,第2行轮数加102,第3行可以观察到是输入的flag与al异或,第4行异或82,后面的汇编很简单就不分析了

fun2:

发现结果仍然不对,看fun2,发现这里第1行还加了个6

按照这样循环

最后在这里比较

还原加密逻辑

flag = ''
key = ''
for i in range(len(flag)):
    ret1 = i + 102
    ret1 ^= flag[i]
    ret1 ^= 82
    ret2 = i + ord(key[i])
    ans = (ret1 & 0xff) + 6 ^ ret2

解密脚本

ans = [
    234,  12,  26,  17, 246,  44,  29,  62,  23,  53,
    49,  41, 244,  57,  57, 211, 195,  45,   0,  16,
    48,  61, 204,   0, 211, 192,  75, 198,  17, 199,
    41,  62, 186,  96, 144,  52
]
key = 'i_can_reverse_but_i_can_not_have_you'

for i in range(36):
    enc1 = ((ans[i] ^ i + ord(key[i])) - 6) & 0xff
    enc2 = enc1 ^ 82 ^ i + 102
    print(chr(enc2),end='')

《回忆安魂曲》--第三章:逃不出的黑墙

30*30迷宫,上下左右对应lvoe,起点为P,终点为E

maze = list('###############################P#...............#...#.......#.#####.###.#####.#.###.#####.#.....#...#.#.....#...#.#...#.#####.#.###.#.#######.#.#.###.#C..#.#.#...#.#...#...#.#.#...#.#.#.#.#.###.#.#.#.###.#.#.#.#.#.#.#.#...#...#.#.......#.#.#.###.#.###.#####.#########.###.#...#...#.....#.#.......#...#.#.#####.#####.#.#.#####.###.#...#...#...#...#...#...#.#...#.###.#.###.#.#######.#.#.#.#.#...#.#.#...#.#...#...#...#.#.###.#.#.#####.#.#.#.#######.###.#...#.....#...#.#.#...#.....#.#########.#####.#.###.#.###.#.#.....#.#...#...#...#...#.#.#.#.#.#.#.###.#.#####.###.#.#.#...#.#...#.#...#...#...#...#.#.###.###.#.#####.#.###.###.#.#...#.#.#.......#.#...#.#...#.#####.#.#######.#.#####.#.###.#...#.#.......#.#...#...#.#..E#.#.#.#.#######.###.#.#####.#.#.#...#.............#.....#.#.#.###############.#######.#.#.#.........#...#...#.....#...#.#.#######.#.#.#####.#.#######.#.......#...#.......#.........')

for i in range(len(maze)):
    if maze[i] == '#':
        maze[i] = 1
    elif maze[i] == '.':
        maze[i] == 0
    elif maze[i] == 'E':
        maze[i] = 2

visited = [0] * (30 * 30)  # 记录访问过的点

def BFS(maze, x, y):
    queue = [(x, y, '')]  # 设置队列
    while queue:
        x, y, path = queue.pop(0)
        if 30 > x >= 0 and 30 > y >= 0 and visited[x * 30 + y] != 1 and maze[x * 30 + y] != 1:
            visited[x * 30 + y] = 1
            queue.append((x - 1, y, path + 'l'))
            queue.append((x, y - 1, path + 'v'))
            queue.append((x + 1, y, path + 'o'))
            queue.append((x, y + 1, path + 'e'))
        else:
            continue
        if maze[x * 30 + y] == 2:   # 终点
            return path

flag = BFS(maze, 1, 1)      # 起点坐标,行/列
print(flag)

然后MD5加密一下就行

py不好,会被ban

python编译的exe文件,先用pyinstxtractor.py解包,然后在解包的文件夹里面发现了main.pyc文件,用DIE查成分,发现是用3.12版本编译的,这就用不了uncompyle6了,用pycdc也反编译不完全,只好用pycdas解出pyc字节码

[Code]
    File Name: main.py
    Object Name: <module>
    Qualified Name: <module>
    Arg Count: 0
    Pos Only Arg Count: 0
    KW Only Arg Count: 0
    Stack Size: 2
    Flags: 0x00000000
    [Names]
        'verify'
        'main'
        '__name__'
    [Locals+Names]
    [Constants]
        [Code]
            File Name: main.py
            Object Name: verify
            Qualified Name: verify
            Arg Count: 3
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 9
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'range'
                'reverse'
                'len'
            [Locals+Names]
                'o0000'
                'len2'
                'language2'
                'enc'
                'i'
                'ii'
                'iii'
                'iiii'
            [Constants]
                None
                (
                    25
                    85
                    88
                    62
                    105
                    93
                    110
                    124
                    1
                    97
                    46
                    47
                    75
                    5
                    116
                    48
                    2
                    25
                )
                1
                False
                True
            [Disassembly]
                0       RESUME                          0
                2       BUILD_LIST                      0
                4       LOAD_CONST                      1: (25, 85, 88, 62, 105, 93, 110, 124, 1, 97, 46, 47, 75, 5, 116, 48, 2, 25)
                6       LIST_EXTEND                     1
                8       STORE_FAST                      3: enc
                10      LOAD_GLOBAL                     1: NULL + range
                20      LOAD_FAST                       1: len2
                22      LOAD_CONST                      2: 1
                24      BINARY_OP                       10 (-)
                28      CALL                            1
                36      GET_ITER
                38      FOR_ITER                        19 (to 78)
                42      STORE_FAST                      4: i
                44      LOAD_FAST                       0: o0000
                46      LOAD_FAST                       4: i
                48      BINARY_SUBSCR
                52      LOAD_FAST                       0: o0000
                54      LOAD_FAST                       4: i
                56      LOAD_CONST                      2: 1
                58      BINARY_OP                       0 (+)
                62      BINARY_SUBSCR
                66      BINARY_OP                       12 (^)
                70      LOAD_FAST                       0: o0000
                72      LOAD_FAST                       4: i
                74      STORE_SUBSCR
                78      JUMP_BACKWARD                   21 (to 38)
                80      END_FOR
                82      LOAD_FAST                       0: o0000
                84      LOAD_ATTR                       3: reverse
                104     CALL                            0
                112     POP_TOP
                114     LOAD_GLOBAL                     1: NULL + range
                124     LOAD_FAST                       1: len2
                126     LOAD_CONST                      2: 1
                128     BINARY_OP                       10 (-)
                132     CALL                            1
                140     GET_ITER
                142     FOR_ITER                        19 (to 182)
                146     STORE_FAST                      5: ii
                148     LOAD_FAST                       0: o0000
                150     LOAD_FAST                       5: ii
                152     BINARY_SUBSCR
                156     LOAD_FAST                       0: o0000
                158     LOAD_FAST                       5: ii
                160     LOAD_CONST                      2: 1
                162     BINARY_OP                       0 (+)
                166     BINARY_SUBSCR
                170     BINARY_OP                       12 (^)
                174     LOAD_FAST                       0: o0000
                176     LOAD_FAST                       5: ii
                178     STORE_SUBSCR
                182     JUMP_BACKWARD                   21 (to 142)
                184     END_FOR
                186     LOAD_GLOBAL                     1: NULL + range
                196     LOAD_FAST                       1: len2
                198     CALL                            1
                206     GET_ITER
                208     FOR_ITER                        30 (to 270)
                212     STORE_FAST                      6: iii
                214     LOAD_FAST                       0: o0000
                216     LOAD_FAST                       6: iii
                218     COPY                            2
                220     COPY                            2
                222     BINARY_SUBSCR
                226     LOAD_FAST                       2: language2
                228     LOAD_FAST                       6: iii
                230     LOAD_GLOBAL                     5: NULL + len
                240     LOAD_FAST                       2: language2
                242     CALL                            1
                250     BINARY_OP                       6 (%)
                254     BINARY_SUBSCR
                258     BINARY_OP                       25 (^=)
                262     SWAP                            3
                264     SWAP                            2
                266     STORE_SUBSCR
                270     JUMP_BACKWARD                   32 (to 208)
                272     END_FOR
                274     LOAD_GLOBAL                     1: NULL + range
                284     LOAD_FAST                       1: len2
                286     CALL                            1
                294     GET_ITER
                296     FOR_ITER                        15 (to 328)
                300     STORE_FAST                      7: iiii
                302     LOAD_FAST                       0: o0000
                304     LOAD_FAST                       7: iiii
                306     BINARY_SUBSCR
                310     LOAD_FAST                       3: enc
                312     LOAD_FAST                       7: iiii
                314     BINARY_SUBSCR
                318     COMPARE_OP                      55 (!=)
                322     POP_JUMP_IF_TRUE                1 (to 326)
                324     JUMP_BACKWARD                   15 (to 296)
                326     POP_TOP
                328     RETURN_CONST                    3: False
                330     END_FOR
                332     RETURN_CONST                    4: True
        [Code]
            File Name: main.py
            Object Name: main
            Qualified Name: main
            Arg Count: 0
            Pos Only Arg Count: 0
            KW Only Arg Count: 0
            Stack Size: 6
            Flags: 0x00000003 (CO_OPTIMIZED | CO_NEWLOCALS)
            [Names]
                'print'
                'input'
                'len'
                'ord'
                'verify'
            [Locals+Names]
                'language'
                'OO000'
                'language1'
                'OOO00'
                'len1'
                'itemm'
                'item'
            [Constants]
                None
                'Y0u k0nw what is the best language in the world???'
                ''
                'is_.py_not_py'
                'goOo0od!!!'
                'So,th3n???'
                True
                'very goOo0od!!!'
                'What a pity!!!T_T'
                'NoOo0o!!!T_T'
            [Disassembly]
                0       RESUME                          0
                2       LOAD_GLOBAL                     1: NULL + print
                12      LOAD_CONST                      1: 'Y0u k0nw what is the best language in the world???'
                14      CALL                            1
                22      POP_TOP
                24      LOAD_GLOBAL                     3: NULL + input
                34      CALL                            0
                42      STORE_FAST                      0: language
                44      BUILD_LIST                      0
                46      STORE_FAST                      1: OO000
                48      BUILD_LIST                      0
                50      STORE_FAST                      2: language1
                52      LOAD_CONST                      2: ''
                54      STORE_FAST                      3: OOO00
                56      LOAD_FAST                       0: language
                58      LOAD_CONST                      3: 'is_.py_not_py'
                60      COMPARE_OP                      40 (==)
                64      POP_JUMP_IF_FALSE               130 (to 326)
                66      LOAD_GLOBAL                     1: NULL + print
                76      LOAD_CONST                      4: 'goOo0od!!!'
                78      CALL                            1
                86      POP_TOP
                88      LOAD_GLOBAL                     1: NULL + print
                98      LOAD_CONST                      5: 'So,th3n???'
                100     CALL                            1
                108     POP_TOP
                110     LOAD_GLOBAL                     3: NULL + input
                120     CALL                            0
                128     STORE_FAST                      3: OOO00
                130     LOAD_GLOBAL                     5: NULL + len
                140     LOAD_FAST                       3: OOO00
                142     CALL                            1
                150     STORE_FAST                      4: len1
                152     LOAD_FAST                       0: language
                154     GET_ITER
                156     LOAD_FAST_AND_CLEAR             5: itemm
                158     SWAP                            2
                160     BUILD_LIST                      0
                162     SWAP                            2
                164     FOR_ITER                        13 (to 192)
                168     STORE_FAST                      5: itemm
                170     LOAD_GLOBAL                     7: NULL + ord
                180     LOAD_FAST                       5: itemm
                182     CALL                            1
                190     LIST_APPEND                     2
                192     JUMP_BACKWARD                   15 (to 164)
                194     END_FOR
                196     STORE_FAST                      2: language1
                198     STORE_FAST                      5: itemm
                200     LOAD_FAST                       3: OOO00
                202     GET_ITER
                204     LOAD_FAST_AND_CLEAR             6: item
                206     SWAP                            2
                208     BUILD_LIST                      0
                210     SWAP                            2
                212     FOR_ITER                        13 (to 240)
                216     STORE_FAST                      6: item
                218     LOAD_GLOBAL                     7: NULL + ord
                228     LOAD_FAST                       6: item
                230     CALL                            1
                238     LIST_APPEND                     2
                240     JUMP_BACKWARD                   15 (to 212)
                242     END_FOR
                244     STORE_FAST                      1: OO000
                246     STORE_FAST                      6: item
                248     LOAD_GLOBAL                     9: NULL + verify
                258     LOAD_FAST                       1: OO000
                260     LOAD_FAST                       4: len1
                262     LOAD_FAST                       2: language1
                264     CALL                            3
                272     LOAD_CONST                      6: True
                274     IS_OP                           0 (is)
                276     POP_JUMP_IF_FALSE               12 (to 302)
                278     LOAD_GLOBAL                     1: NULL + print
                288     LOAD_CONST                      7: 'very goOo0od!!!'
                290     CALL                            1
                298     POP_TOP
                300     RETURN_CONST                    0: None
                302     LOAD_GLOBAL                     1: NULL + print
                312     LOAD_CONST                      8: 'What a pity!!!T_T'
                314     CALL                            1
                322     POP_TOP
                324     RETURN_CONST                    0: None
                326     LOAD_GLOBAL                     1: NULL + print
                336     LOAD_CONST                      9: 'NoOo0o!!!T_T'
                338     CALL                            1
                346     POP_TOP
                348     RETURN_CONST                    0: None
                350     SWAP                            2
                352     POP_TOP
                354     SWAP                            2
                356     STORE_FAST                      5: itemm
                358     RERAISE                         0
                360     SWAP                            2
                362     POP_TOP
                364     SWAP                            2
                366     STORE_FAST                      6: item
                368     RERAISE                         0
        '__main__'
        None
    [Disassembly]
        0       RESUME                          0
        2       LOAD_CONST                      0: <CODE> verify
        4       MAKE_FUNCTION                   0
        6       STORE_NAME                      0: verify
        8       LOAD_CONST                      1: <CODE> main
        10      MAKE_FUNCTION                   0
        12      STORE_NAME                      1: main
        14      LOAD_NAME                       2: __name__
        16      LOAD_CONST                      2: '__main__'
        18      COMPARE_OP                      40 (==)
        22      POP_JUMP_IF_FALSE               8 (to 40)
        24      PUSH_NULL
        26      LOAD_NAME                       1: main
        28      CALL                            0
        36      POP_TOP
        38      RETURN_CONST                    3: None
        40      RETURN_CONST                    3: None

手k出加密逻辑

def verify(o0000, len2, language2):
    enc = [25, 85, 88, 62, 105, 93, 110, 124, 1, 97, 46, 47, 75, 5, 116, 48, 2, 25]

    for i in range(len2 - 1):
        o0000[i] = o0000[i] ^ o0000[i + 1]
    o0000.reverse()

    for ii in range(len2 - 1):
        o0000[ii] = o0000[ii] ^ o0000[ii + 1]

    for iii in range(len(o0000)):
        o0000[iii] = o0000[iii] ^ ord(language2[iii % len(language2)])

    for iiii in range(len(o0000)):
        if o0000[iiii] != enc[iiii]:
            return False

    return True

def main():
    print("Y0u k0nw what is the best language in the world???")
    language = input()

    OO000 = []
    language1 = []
    OOO00 = ""

    if language == "is_.py_not_py":
        print("goOo0od!!!")
        print("So,th3n???")
        OOO00 = input()

        len1 = len(OOO00)

        for itemm in language:
            language1.append(ord(itemm))

        for item in OOO00:
            OO000.append(ord(item))

        if verify(OO000, len1, language1):
            print("very goOo0od!!!")
        else:
            print("What a pity!!!T_T")
    else:
        print("NoOo0o!!!T_T")

if __name__ == "__main__":
    main()

解密脚本:

enc = [25, 85, 88, 62, 105, 93, 110, 124, 1, 97, 46, 47, 75, 5, 116, 48, 2, 25]
lg = 'is_.py_not_py'
lg = [ord(i)for i in lg]

for i in range(len(enc)):
    enc[i] ^= lg[i%len(lg)]
ret1 = enc[-1]
for i in range(len(enc)-1,-1,-1):
    enc[i-1] ^= enc[i]
enc[-1] = ret1

enc.reverse()
ret2 = enc[-1]
for i in range(len(enc)-1,-1,-1):
    enc[i - 1] ^= enc[i]
enc[-1] = ret2

print(''.join([chr(i)for i in enc]))

Y0u_r3@l1y_knOw_py

找啊找

DIE查壳,UPX壳,提示modified,用010editor打开检查upx特征码

四个都被改成APK了,改回UPX,工具脱壳成功

ida反编译

加密逻辑非常简单,只需要注意一个地方。对27行的unk_40040交叉引用,会跳到另一个函数func,这里对unk_40040重新赋值

先大小写转换,然后所有值异或57,写脚本逆向

enc = [
    0x50, 0x4A, 0x5A, 0x4D, 0x5F, 0x42, 0x7E, 0x76, 0x76, 0x5D,
    0x18, 0x18, 0x08, 0x4A, 0x56, 0x66, 0x60, 0x56, 0x4C, 0x66,
    0x5F, 0x08, 0x57, 0x5D, 0x66, 0x08, 0x6D, 0x66, 0x54, 0x79,
    0x50, 0x57, 0x18, 0x18, 0x79, 0x44
]

for i in range(len(enc)):
    enc[i] ^= 57
    if enc[i] > 96 and enc[i] <= 122:
        enc[i] -= 32
    elif enc[i] > 64 and enc[i] <= 90:
        enc[i] += 32

print(''.join([chr(i)for i in enc]))

ISCTF{gooD!!1SO_yOU_F1ND_1t_M@IN!!@}

0 条评论
某人
表情
可输入 255