逆向ctf-2020湖湘杯Re_03

样本链接:https://pan.baidu.com/s/14o1QOjYVtOspZd9koT4JCg 
提取码:jwrp 

一、获取题目压缩包,解压后发现是一个为ReMe.exe的可执行文件,但是奇怪的是在exeinfope中查询结果为:

很明显了,不是PE文件,看图标猜测为python打包的exe文件。既然如此就对exe文件进行反编译操作,因为是使用pyinstaller生成的exe文件,所以对于python打包的exe文件反编译操作流程为,首先下载pyinstxtractor.py文件并放到ReMe.exe文件夹中,之后在命令行中运行 python pyinstxtractor.py Reme.exe进行反编译得到一个ReMe.exe_extracted文件夹,如图:

当执行到这里时,进入文件夹找到:

对于ReMe和struct这两个没有后缀的文件,就是我们要得到的文件。但是目前ReMe文件缺失pyc文件相对应的头部信息,所以使用十六进制查看器WinHex打开两个文件:

对于打开后的结果进行对比后发现,struct文件比ReMe文件在头部多出:

42 0D 0D 0A 00 00 00 00 70 79 69 30 10 01 00 00

这样一段,将这一部分以十六进制数值复制出来,copy到ReMe文件地址00000000处(就是开始),对复制好的ReMe文件进行后缀的修改变为ReMe.pyc文件。到这一步就可以选择网上pyc文件反编译或者使用uncompyle6进行反编译(说一下,我在做这道题时用网上反编译一直报错,不能完整反编译出来),如果没有安装uncompyle6,就执行cmd命令:pip install uncompyle,反编译命令为:

uncompyle6 ReMe.pyc > ReMe.py

执行后,在ReMe.exe_extracted文件夹中会发现ReMe.py这个文件,打开发现:

# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 16:30:00) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: ReMe.py
# Compiled at: 1995-09-28 00:18:56
# Size of source mod 2**32: 272 bytes
import sys, hashlib
check = [
 'e5438e78ec1de10a2693f9cffb930d23',
 '08e8e8855af8ea652df54845d21b9d67',
 'a905095f0d801abd5865d649a646b397',
 'bac8510b0902185146c838cdf8ead8e0',
 'f26f009a6dc171e0ca7a4a770fecd326',
 'cffd0b9d37e7187483dc8dd19f4a8fa8',
 '4cb467175ab6763a9867b9ed694a2780',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'cffd0b9d37e7187483dc8dd19f4a8fa8',
 'fd311e9877c3db59027597352999e91f',
 '49733de19d912d4ad559736b1ae418a7',
 '7fb523b42413495cc4e610456d1f1c84',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'acb465dc618e6754de2193bf0410aafe',
 'bc52c927138231e29e0b05419e741902',
 '515b7eceeb8f22b53575afec4123e878',
 '451660d67c64da6de6fadc66079e1d8a',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'fe86104ce1853cb140b7ec0412d93837',
 'acb465dc618e6754de2193bf0410aafe',
 'c2bab7ea31577b955e2c2cac680fb2f4',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'f077b3a47c09b44d7077877a5aff3699',
 '620741f57e7fafe43216d6aa51666f1d',
 '9e3b206e50925792c3234036de6a25ab',
 '49733de19d912d4ad559736b1ae418a7',
 '874992ac91866ce1430687aa9f7121fc']

def func(num):
    result = []
    while num != 1:
        num = num * 3 + 1 if num % 2 else num // 2  #满足求余==0时执行num//2反之执行num*3+1
        result.append(num)

    return result


if __name__ == '__main__':
    print('Your input is not the FLAG!')
    inp = input()
    if len(inp) != 27:
        print('length error!')
        sys.exit(-1)
    for i, ch in enumerate(inp):
        ret_list = func(ord(ch))
        s = ''
        for idx in range(len(ret_list)):
            s += str(ret_list[idx])  # 将数组第idx个放入
            s += str(ret_list[(len(ret_list) - idx - 1)])#将数组倒序len(数组)-idx-1放入

        md5 = hashlib.md5()
        md5.update(s.encode('utf-8'))
        if md5.hexdigest() != check[i]: #判断对第i轮字符生成数组的md5值与check[i]的值
            sys.exit(i)

    md5 = hashlib.md5()
    md5.update(inp.encode('utf-8')) #想输出到这,前面每一轮加密后的字符串必须都要对应相等check中的值
    print('You win!')
    print('flag{' + md5.hexdigest() + '}')
# okay decompiling ReMe.pyc

对于这个加密方式采用爆破就能直接解出,思路为每一轮都遍历0x20-0x7f之间的数(设为j),采用func函数生成数组并md5加密,并与check【轮数】对比,相等就将遍历的数j进行字符转换并存起来。代码如下;

import sys, hashlib
check = [
 'e5438e78ec1de10a2693f9cffb930d23',
 '08e8e8855af8ea652df54845d21b9d67',
 'a905095f0d801abd5865d649a646b397',
 'bac8510b0902185146c838cdf8ead8e0',
 'f26f009a6dc171e0ca7a4a770fecd326',
 'cffd0b9d37e7187483dc8dd19f4a8fa8',
 '4cb467175ab6763a9867b9ed694a2780',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'cffd0b9d37e7187483dc8dd19f4a8fa8',
 'fd311e9877c3db59027597352999e91f',
 '49733de19d912d4ad559736b1ae418a7',
 '7fb523b42413495cc4e610456d1f1c84',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'acb465dc618e6754de2193bf0410aafe',
 'bc52c927138231e29e0b05419e741902',
 '515b7eceeb8f22b53575afec4123e878',
 '451660d67c64da6de6fadc66079e1d8a',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'fe86104ce1853cb140b7ec0412d93837',
 'acb465dc618e6754de2193bf0410aafe',
 'c2bab7ea31577b955e2c2cac680fb2f4',
 '8e50684ac9ef90dfdc6b2e75f2e23741',
 'f077b3a47c09b44d7077877a5aff3699',
 '620741f57e7fafe43216d6aa51666f1d',
 '9e3b206e50925792c3234036de6a25ab',
 '49733de19d912d4ad559736b1ae418a7',
 '874992ac91866ce1430687aa9f7121fc']


def func(num):
    result = []
    print(num)
    while num != 1:
        num = num * 3 + 1 if num % 2 else num // 2
        result.append(num)
    print(result)

    return result
flag = ''

for i in range(27):
    for j in range(0x20, 0x7f):
        ret_list = func(j)
        s = ''
        print(ret_list)
        for idx in range(len(ret_list)):
            s += str(ret_list[idx])
            s += str(ret_list[(len(ret_list) - idx - 1)])
            print(s)
        md5 = hashlib.md5()
        md5.update(s.encode('utf-8'))
        if md5.hexdigest() == check[i]:
            flag += chr(j)
            break
print(flag)

执行后的结果为:

flag{My_M@th_3X+1_R3v_Te5t}

但是题目要求提交还需要放到ReMe.exe中运行得到:

也就是题目要求了。

flag{0584cfa2ce502951ef5606f6b99fc921}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值