第一步 查壳
如图,无壳,ELF文件
第二步 IDA
64位IDA,无法直定位到主函数F5,所以使用,查找关键字符串定位主函数大法Shift+F12
发现这些关键字符串,双击上图蓝色字符串,
然后交叉引用Ctrl+X跟踪
来到流程图,直接F5大法
进来又是一代对数据,我直接全部手动转化为了字符
然后下面的一堆函数,进入菜狗模式,借鉴大佬的猜测
进入第一个函数sub_4406E0,发现很难理解此函数是干嘛的,但通过主程序,我们可以猜测,该函数的作用应该是读取我们的输入。同理,根据if语句中的v15[i] ^ i) != v14[i],我们也可以猜测函数sub_424BA0是读取长度的。这样,continue前的逻辑就分析出来。
果然,做ctf就得是要大胆猜测呀,继续分析,如图注释所示
涉及数组寻址方式数据结构之——数组 - 知乎 (zhihu.com)
所以,为了防止程序跳转,所以得知,正确数据应该是,v14数组内存里的数据(也即是上面第一次出现的一堆我手动转化的字符)去异或它的下标。
代码部分
v17[1] = 111
v17[2] = 100
v17[3] = 108
v17[4] = 62
v17[5] = 81
v17[6] = 110
v17[7] = 98
v17[8] = 40
v17[9] = 111
v17[10] = 99
v17[11] = 121
v17[12] = 127
v17[13] = 121
v17[14] = 46
v17[15] = 105
v17[16] = 127
v17[17] = 100
v17[18] = 96
v17[19] = 51
v17[20] = 119
v17[21] = 125
v17[22] = 119
v17[23] = 101
v17[24] = 107
v17[25] = 57
v17[26] = 123
v17[27] = 105
v17[28] = 121
v17[29] = 61
v17[30] = 126
v17[31] = 121
v17[32] = 76
v17[33] = 64
v17[34] = 69
v17[35] = 67
flag=""
for i in range(36):
flag+=chr(v17[i]^i)
print(flag)
得到运行结果是
Info:The first four chars are `flag`
那么问题还没有结束,所以继续往下看,前面还是类似上面的前面,输入然后判断,重点是点进入令人头大的sub_400E44
函数,但是有经验的就会知道,还记得上面第二张截图那一大片绿色的字符串吗,底下有一串abcdefghijklmn
数组字符串,这在sub_400E44
函数中同样也出现了,可以直接点击跟踪,所以可以猜测sub_400E44
函数就是base64加密。而且还加密了十次。
sub_400E44函数
(手动狗头,这是大佬的代码:)也可以直接手动用工具解密:
import base64
lis ="Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=="
for i in range(10):
lis = base64.b64decode(lis)
print(lis)
这是一个i春秋的论坛页面,被迫学习了,主动防御,这是什么天坑题目,直接没思路,看大佬wp
我们需要其他的线索,联想到第一个提示信息,翻译说前四个字符是"flag",发现下面标黄的地方还有一段字符串byte_6CC0A0
根据后面的交叉引用跟踪进去看,sub_400D35
函数--看我的注释很令人头大,但重点看if
发现此函数的逻辑就是将byte_6CC0A0字符串进行异或,还可以发现if语句中,有判断是否等于‘f’和‘g’的条件,根据已有信息猜测这个字符数组就是‘flag’。v12和v15是一样的一个数组,HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()、BYTE1()、BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。所以可以知道v15这个数组就只有四个字符而且和byte_6CC0A0
前4个字符异或后就==字符“flag”。
然后我们来说说交叉引用Ctrl+X
对sub_400D35函数进行交叉引用;发现来自.fini段的调用;
而.fini段的解释是
此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。
“oh my god 又是什么新知识增加了”
编写算法
enc = [0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
key = ""
flag = ""
en = "flag"
for i in range(4):
key+=chr(enc[i]^ord(en[i]))
print(key)
for j in range(len(enc)):
flag+=chr(enc[j]^ord(key[j%4]))
print(flag)
结果如图,这题真费劲
得出
key为&YA1
flag为flag{Act1ve_Defen5e_Test}
总结
最后,声明下我借鉴得大佬的文章:
(29条消息) 2019 红帽杯 easyRE_[2019红帽杯]easyre_mishixiaodai的博客-CSDN博客
(29条消息) BUUCTF-re-[2019红帽杯]easyRE_T1M@的博客-CSDN博客
2019 红帽杯 Re WP - Hk_Mayfly - 博客园 (cnblogs.com)
(29条消息) re学习笔记(25)BUUCTF-re-[2019红帽杯]easyRE_buuctf re题_Forgo7ten的博客-CSDN博客
再写是因为自己再复现了一遍,希望加深印象,增强理解
如有错误,欢迎感谢支出,并参与讨论。
借鉴引用注明出处,谢谢理解!