menu 牢记自己是菜
i春秋 第二届春秋欢乐赛 登山者
4033 浏览 | 2020-03-29 | 阅读时间: 约 3 分钟 | 分类: 春秋实验室 | 标签:
请注意,本文编写于 1486 天前,最后修改于 1486 天前,其中某些信息可能已经过时。

0x1 题目描述

攀登者题目链接
这道算是里程碑式的题目(对于我自己),这样应该是我做出来第一道使用IDA静态调试与OD动态调试相结合的题目。加深了对OD与IDA之间练习的理解。并且让我意识到了一个很严重的问题,信息安全方向,也是一个比较吃算法的一个方向,这一道题目使用的bp的算法题目。这叫我想起来Xctf的一道图论题,也是在你完成代码分析之后需要你写出一个图论的算法才可以还原falg。(不要问我拿到图论题的题解在哪里,不会算法,没写)这时候就想起自己当时参加ACM被算法支配的恐惧。话不多说,让我们来看一看这一道隐藏在信息安全里面的算法题目吧。


0x2 静态分析

首先查壳,检查一下是否有什么加密或者壳,有一说一我觉得这里面都成这样了,还整个壳就有点不人道了哈。

进行一下静态分析,很容易就定位到了关键的静态代码,看一下逻辑(C++写的代码是真的难看),发现一个chek函数验证了一个字符串v3,而v3与v5有关。检查几个相关函数后,找到一处超级大的循环,一开始我以为是内部啥函数自己生成的一个循环。看了好久才反应过来,这好象是一个矩阵的构造,rand函数有种子,所以应该是一个固定的矩阵。

继续分析,发现一个string,后面还有一个加密的算法,是将这个字符串进行了打乱。来分析程序逻辑:总共是1014个位,1个字符决定6个01,那么我们的输入长度是1014/6=169个,要逆向得到原来的字符串,首先需要处理矩阵,然后使用dp得到最大值的地方,然后6个01为一组,得到一个字符。于是我们的任务就相当明确了,我们需要使用动态调试将矩阵搞出来,然后将打乱后的字符串也dump出来。

0x3 动态分析

打开OD,在IDA中定位构造矩阵的内存地址,与循环构造的函数的地址。ctrl+G输入调用的地址,跳转到目标地址,下一个硬件断点,运行程序,右键在数据中跟踪,显示在内存中。运行,查看内存变化,通过内存变化计算出1024次后改变的地址。


找到内存地址后,我们右键,二进制,二进制复制,然后弄到txt中去。
之后就是那个打乱的字符串,同样的道理,IDA内获得地址,OD监视追踪。找到循环位置,循环64次。观察寄存器也行,通用观察内存空间也行,导出数据。


导出数据,下面就是我们的脚本阶段了。

0x4 dp算法

但是在写代码的时候练(抄)了很多,所以还是有一点了解的。不过多介绍了,直接上脚本。

'''
f = open('matrix.txt','r')
a = [[0 for i in range(1020)] for i in range(1020)]
index = 0
while True:
    line = f.readline()
    line = line.replace(' ','')
    line = line.replace('\n','')
    s = line[6:8] + line[4:6] + line[2:4] + line[0:2]
    a[index/1014][index%1014]=int(s,16)
    index += 1
    s = line[22:24] + line[20:22] + line[18:20] + line[16:18]
    a[index/1014][index%1014]=int(s,16)
    index += 1
    s = line[38:40] + line[36:38] + line[34:36] + line[32:34]
    a[index/1014][index%1014]=int(s,16)
    index += 1
    s = line[54:56] + line[52:54] + line[50:52] + line[48:50]
    a[index/1014][index%1014]=int(s,16)
    index += 1
    #if index % 100000 == 0:
    #    print index
    if index >= 1014 * 1014:
        break
f.close()
dp = [[0 for i in range(1020)] for i in range(1020)]
choose = [[0 for i in range(1020)] for i in range(1020)]
dp[0][0] = a[0][0]
for i in xrange(1,1014):
    dp[i][0] = dp[i-1][0] + a[i][0]
    for j in xrange(1,i+1):
        dp[i][j] = max(dp[i-1][j-1],dp[i-1][j]) + a[i][j]
        if dp[i-1][j-1] > dp[i-1][j]:
            choose[i][j] = 1
        else:
            choose[i][j] = 0
Max = 0
Pos = 0
for i in range(0,1014):
    if dp[1013][i] > Max:
        Max = dp[1013][i]
        Pos = i
print Max
step = [0 for i in range(1020)]
i = 1013
while (i > 0):
    step[i] = choose[i][Pos]
    Pos -= choose[i][Pos]
    i -= 1
for i in range(0,1014):
    print step[i],',',
'''
step = [0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 0 , 1 , 0]
print len(step)
 
temp = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
num = [0x2f,0x10,0x12,0x19,0,0x2,0xE,0x15,0x1,0x3E,0x30,0x0A,0x38,0x7,0x27,0x37,
       0x21,0x0B,0x17,0x16,0x2D,0x22,0x3A,0x32,0x11,0x1F,0x3D,0x36,0x33,0x3,0x2A,
       0x34,0x05,0x31,0x23,0x25,0x1D,0x2E,0x1B,0x13,0x24,0x20,0x1A,0x0F,0x2B,0x18,
       0x3F,0x0D,0x06,0x1E,0x35,0x14,0x3C,0x0C,0x09,0x2C,0x08,0x39,0x04,0x28,0x29,
       0x26,0x1C,0x3B]
flag = ''
for i in range(0,1014,6):
    number = step[i] * 32 + step[i+1] * 16 + step[i+2] * 8 + step[i+3] * 4 + step[i+4] * 2 + step[i+5]
    for pos in range(0,64):
        if number==num[pos]:
            flag += temp[pos]
print flag
 
string = 'EIFd6gwN42LR1vGrBYCnzHTStDqm+kxZpQVioj9O78es3UlAKhXcfybPM5W/0aJu'
print hex(string.find('A'))

最后进行一次测试


0x5 总结

这次的题目可能没有什么,但是对于我来说这是一里程碑的一次,因为完成了静态与动态调试第一次相结合。终于不是一个只会F5的菜鸡了,变成了一个会静态调试和动态调试的菜鸡了。继续努力吧。这道题之后我觉得我可以在去挑战一下Xctf中的那道图论的题目了。

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!