170818 逆向-南邮CTF(WxyVM2)

来源:互联网 发布:淘宝电商 编辑:程序博客网 时间:2024/05/18 13:47

1625-5 王子昂 总结《2017年8月18日》 【连续第320天总结】
A. 南邮CTF-WxyVM2
B.
上次没做完的正巧在52破解论坛上看到有人发问了,就摸过来再做做看
跟WxyVM1比较像,不过感觉这题相比VM来说更像花指令~
首先看源码分析,先验证长度为25,然后进行了一大片的加减异或操作,最后与内存中的一个字符串进行比较
上次乍一看大片的加减异或操作不好处理,也没想到怎么将指令dump下来逆操作
这次仔细的分析一下发现大部分的操作都是无意义的:
这里写图片描述
仔细观察,输入在0x694100处,单位为byte,长度为25
也就是说,输入的字符串固定在0x694100-0x694118内,大片的dword操作都是超出这个范围的,它们没有意义
最后的比较字符串位于0x694060处,单位为dword,长度为25,是不变的字符串,直接IDC脚本dump出来即可
那么关键在于如何提取有意义的操作:
我是直接全选IDC反编译出来的命令,掐头去尾,以“;”作为分隔符得到命令集合的列表,然后分析特征:无意义的操作开头为dowrd,所需要的操作开头为byte(另外还有一些自加自减操作需要另外处理)
遍历列表,将有意义的保存下来,然后再分析提取被操作数(即下标)、操作命令和操作数
确认正向测验的脚本结果与动态调试中所查看到的内存无误,说明思路和脚本都正确,将命令加减颠倒,处理字符串改为直接dump出来的结果即可
附上python脚本:

def arr(list, s):  # 分析字符串,将被操作数、命令、操作数分别放入数组    tmp = [0, ‘’, 0]    tmp[0] = int(s[9], 10) * 16 + int(s[10], 16)#被操作数下标    tmp[1] = s[12]#操作符    tmp[2] = s[15:]#操作数    if (len(tmp[2]) == 0):#提取失败,为自增/减类型(++byte_xxx型)        tmp[0] = int(s[11], 10) * 16 + int(s[12], 16)        # print(i,tmp[0])        tmp[1] = s[0]        tmp[2] = '1'    if (tmp[2][0] is '0'):#操作数为十六进制        tmp[2] = int(tmp[2][2:-1], 16)    else:        if (tmp[2][-1] is 'u'): tmp[2] = tmp[2][:-1]#操作数末尾去除'u'        tmp[2] = int(tmp[2], 10)    list.append(tmp)def positive(list):#正向操作函数    ori = input("Please input the flag(25):")    flag = []    # 提取ASCII并进行操作    for i in ori:        flag.append(ord(i))    for i in list:        n = flag[i[0]]        if (i[1] is '+'):            n = n + i[2]        if (i[1] is '-'):            n = n - i[2]        if (i[1] is '^'):            n = n ^ i[2]        flag[i[0]] = n % 256#操作单位为字节,解决溢出    return flagdef negative(list, ori):#逆向还原函数    flag = ""    for i in list[::-1]:        n = ori[i[0]]        if (i[1] is '+'):            n = n - i[2]        if (i[1] is '-'):            n = n + i[2]        if (i[1] is '^'):            n = n ^ i[2]        ori[i[0]] = n % 256    for i in ori:        flag = flag + chr(i)    return flag#operator为IDA反编译出的全部命令o = operator.split(";")#分割命令形成列表operators_str = []#初步有效命令列表operators_com = []#最终分析命令列表#内存中dump出来的,0x401060的结果ori = [0xffffffc0, 0xffffff85, 0xfffffff9, 0x6c, 0xffffffe2, 0x14, 0xffffffbb, 0xffffffe4, 0xd, 0x59, 0x1c, 0x23,       0xffffff88, 0x6e, 0xffffff9b, 0xffffffca, 0xffffffba, 0x5c, 0x37, 0xffffffff, 0x48, 0xffffffd8, 0x1f, 0xffffffab,       0xffffffa5]# 去除混淆命令和开头的换行、空格符号for i in o[:-1]:    if (i[3] is not 'd'):        operators_str.append(i[3:])# 分析for i in operators_str:    arr(operators_com, i)# positive(operators_com)print(negative(operators_com, ori))

C. 明日计划
NATAS

原创粉丝点击