继续学习,这次尝试做了一下南邮ctf平台的逆向题来练习
目录
第一题 HELLO,RE!
打开ida,找到main函数按F5,hexray反编译
就在眼前 flag{Welcome_To_RE_World!}
第二题 ReadAsm2
来锻炼汇编的阅读能力吧
main函数定义了一串字符串,应该就是加密的密文
通过func解密后输出结果,题目提示调用约定为System V AMD64 ABI
百度调用约定后,分析结果如下
总的来说,意思就是函数对输入的字符串每一个字符都与其
所在缓冲区的索引做异或运算,最后输出结果。
用py来写解密脚本吧
flag = [0x0,0x67,0x6e,0x62,0x63,0x7e,0x74,0x62,0x69,0x6d,
0x55, 0x6a, 0x7f, 0x60, 0x51, 0x66,0x63, 0x4e, 0x66, 0x7b,
0x71, 0x4a, 0x74, 0x76, 0x6b, 0x70, 0x79, 0x66 , 0x1c]
flagstr = []
index = 0
for ech in flag:
flag[index] = ech^index
flagstr.append(chr(flag[index]))
index = index+1
print ''.join(flagstr)
运行后得到答案 flag{read_asm_is_the_basic}
第三题 Py交易
Pyc文件,直接就是让我们,来反编译源文件了
百度就可以找到pyc在线反编译网站https://tool.lu/pyc/
反编译结果如下
import base64
def encode(message):
s = ''
for i in message:
x = ord(i) ^ 32
x = x + 16
s += chr(x)
return base64.b64encode(s)
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
print 'correct'
else:
print 'wrong'
import base64
def encode(message):
s = ''
for i in message:
x = ord(i) ^ 32
x = x + 16
s += chr(x)
return base64.b64encode(s)
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
print 'correct'
else:
print 'wrong'
对上述代码中的encode加密函数作逆就可以得到结果了
py脚本如下
from base64 import *
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
correct = b64decode(correct)
correct = list(correct)
flag = []
for ech in correct:
x = ord(ech) - 16
x = x ^ 32
flag.append(chr(x))
print ''.join(flag)
最终结果为 nctf{d3c0mpil1n9_PyC}
第四题 WxyVM
扔到64位windows Linux子系统下运行,显示要求我们输入flag
扔到ida,找到main函数,F5反编译
主函数没什么好说的,判断输入的字符数,sub_4005b6这个函数对其加密,然后与601060这的数组做比对
现在只要解密601060的数组即可
进入sub_4005b6函数
看来是根据6010c0表的值以及做运算
dump下6010c0处的数组,以及最后用于比较的位于601060处的密文
值得注意的是601060处的数组是一个双字数组,而我们的输入时字符单字节数组
所以做比较时,只有双字的低8位与我们的输入做比较,其他都是垃圾数据,所以
密文保存的时候只要保存低8位的字节就行了
py脚本如下
biao = open('biao','rb')
flag = [0xC4,0x34,0x22,0xB1,0xD3,0x11,0x97,0x7,0xDB,0x37,0xC4,0x6,0x1D,0xFC,0x5B,0xED,0x98,0xDF,0x94,0xD8,0xB3,0x84,0xCC,0x8]
biaolist = []
for i in range(0,15000):
tmp = biao.readline(1)
biaolist.append(ord(tmp))
biao.close()
for i in range(14997,-1,-3):
v0 = biaolist[i]
v3 = biaolist[i+2]
result = v0
if v0 == 1:
result = biaolist[i+1]
flag[result] -= v3
elif v0 == 2:
result = biaolist[i+1]
flag[result] += v3
elif v0 == 3:
result = biaolist[i+1]
flag[result] ^= v3
elif v0 == 4:
result = biaolist[i+1]
flag[result] = flag[result]/v3
elif v0 == 5:
result = biaolist[i+1]
flag[result] ^= flag[biaolist[i+2]]
else:
continue
flagstr = []
for ech in flag:
flagstr.append(chr(ech%256))
flagstr = ''.join(flagstr)
print flagstr
py的变量没有溢出之类的概念,所以记得对256取模来保证,字符正常输出
“biao”是我们dump下来的加密函数用的数组
最终结果如下:nctf{Embr4ce_Vm_j0in_R3}
第五题 maze
前天看到bugku上有一道take the maze,还没弄懂,还好这个还简单些
依然是扔到ida里去在main函数中反编译
很长呢…改了几个变量名字看着舒服多了
整体看下来就是大概用了一个变量,64位的road(这是我自己重命名的变量)
他的高32位用作列索引,低32位用作行索引(小端序机器),在提供给的maze_list这个二维
数组中前进,如果遇到 # 就算成功,几个条件判断语句控制,前进的方向,road保存着当前的位置
结果是’O’向左,’o’向右,’.’向上,’0’向下,去吧maze_list的表给dump下来
一行8个的二维数组,我用py打印出来直观的看一下
maze = ' ******* * **** * **** * *** *# *** *** *** *********'
tu = []
tuech = []
index = 0
for ech in maze:
if index == 7:
index = 0
tuech.append(ech)
tu.append(tuech)
tuech = []
continue
tuech.append(ech)
index = index+1
for ech in tu:
print ''.join(ech)
然后自己画着走就可以看出来了
应该是o0oo00O000oooo..OO
最后结果为 nctf{o0oo00O000oooo..OO}
第六题 WxyVM 2
隔了一天弄好了,解密脚本一开始就写完了,
结果运算结果匪夷所思,弄了半天才发现,原来py没有
自增运算符。。。。。
首先是main函数,光反编译就等了一会儿。。。
总的来说就是有一大串没有意义的运算,有意义的就只有以字节运算的语句
byte_694100是我们的输入,最后这个循环就是用来比较的,和前面一道题
差不多,也只要关注第一个字节就行。
把所有的运算语句copy下来选出byte运算的就可以。
我第一次弄完了后,打算迭代直接exec(),
结果由于py没有自增运算符,输出成很奇怪的
flag
郁闷了我好久。。。。。
偷个懒干脆直接生成c语言风格的语句,用c计算了。。。
python生成c语言语句
f = open('shanxuan.txt')
byte_694100 = 0xC0
byte_694101 = 0x85
byte_694102 = 0xF9
byte_694103 = 0x6C
byte_694104 = 0xE2
byte_694105 = 0x14
byte_694106 = 0xBB
byte_694107 = 0xe4
byte_694108 = 0xd
byte_694109 = 0x59
byte_69410A = 0x1c
byte_69410B = 0x23
byte_69410C = 0x88
byte_69410D = 0x6e
byte_69410E = 0x9b
byte_69410F = 0xca
byte_694110 = 0xba
byte_694111 = 0x5c
byte_694112 = 0x37
byte_694113 = 0xfff
byte_694114 = 0x48
byte_694115 = 0xd8
byte_694116 = 0x1f
byte_694117 = 0xab
byte_694118 = 0xa5
flist = f.readlines()
for i in range(len(flist)):
flist[i] = flist[i].strip(' \n;u')
tmp = []
index1 = 0
index2 = 0
for ech in flist:
index2 = 0
if ech.find('+') != -1:
tmp = list(ech)
for c in tmp:
if c=='+':
tmp[index2] = '-'
index2 = index2+1
flist[index1] = ''.join(tmp)
tmp = []
elif ech.find('-') != -1:
tmp = list(ech)
for c in tmp:
if c=='-':
tmp[index2] = '+'
index2 = index2+1
flist[index1] = ''.join(tmp)
tmp = []
index1 = index1+1
tmp = []
flist.reverse()
i = 0
for ech in flist:
if ech.find('byte') != -1:
print ech+';'
笨笨的脚本,不想管了。。
把变量,和输出结果copy到vs里再定义一下,编译出结果
结果 nctf{th3_vM_w1th0ut_dAta}。好累再去刷bugku的题。。。