您的位置:首页 > 其它

170818 逆向-南邮CTF(WxyVM2)

2017-08-18 13:31 585 查看
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 flag

def 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: