【2021春节】逆向高级题
这一题我自己做出来的时候,都不知道是不是钻了什么漏洞,还是说我想的简单了。初级题我做了快一天,安卓题做了大概一个晚上,高级题有点奇怪,大概半个钟就出来了,话不多说进入正题
高级题的题目是python源码,先打开看一下。好家伙,是python2的代码,我电脑没有装python2,那就先看一下逻辑,然后改为python3可以运行的代码
大概分为四部分,第一部分是输入以及判断输入内容,第二部分是初始化整数,列表,字典,第三部分是加密函数,第四部分是对比函数
从第四部分中的
if lenth == 23:
print("Yes, you got it!")
这里可以知道flag的长度是23位
下面代码是将原题目加上了一些注释
print "Welcome to Processor's debugger!"
print "Please input you flag now!"
# 输入内容
input = raw_input()
# 判断是否为空
if not input:
print "Are you kidding me?"
exit(0)
# 判断输入长度是否大于10
lenth = len(input)
if lenth <= 10:
print "Short flag!"
exit(0)
print "len:%d" % (lenth)
print "OK,let's debug it! You can 'Step' by 'Space'!"
print "--------------INFO--------------"
# 定义一个现实dic的函数
def debuginfo(dic):
print "eax: %d" %(dic['eax'])
print "ebx: %d" %(dic['ebx'])
print "ecx: %d" %(dic['ecx'])
print "zf: %d" %(dic['zf'])
print "--------------INFO--------------"
# 初始化整数,列表,字典
index = 0
idx = 0
arr =
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
result =
dic = {'eax': 0, 'ebx': 0, 'ecx': 0, 'zf': 0}
# 加密函数
while raw_input() == ' ':
if index <= 10:
dic['eax'] = ~ord(input)
dic['ebx'] = 0
dic['ecx'] = index
dic['zf'] = 0
debuginfo(dic)
if raw_input() == ' ':
dic['eax'] = dic['eax'] ^ arr
dic['ebx'] = arr
dic['ecx'] = index
dic['zf'] = 1
result = dic['eax']
debuginfo(dic)
else:
dic['eax'] = ord(input) + arr
dic['ebx'] = arr
dic['ecx'] = index
dic['zf'] = 1
debuginfo(dic)
if raw_input() == ' ':
dic['eax'] = dic['eax'] ^ 0xcc
dic['ebx'] = 0xcc
dic['ecx'] = index
dic['zf'] = 1
result = dic['eax']
debuginfo(dic)
index = index + 1
if index == 23 or index == lenth:
break
# 判断结果
while raw_input() == ' ':
dic['eax'] = result
dic['ebx'] = check
dic['ecx'] = idx
if dic['eax'] != dic['ebx']:# 逐个字节对比
dic['zf'] = 1
print "Wrong flag, try again!"
exit(0)
else:
dic['zf'] = 0
debuginfo(dic)
idx = idx + 1
if idx == 23 or idx == lenth:
if lenth == 23:
print "Yes, you got it!"
exit(0)
else:
print "Close to right!"
exit(0)
但是python2的代码没法跑起来,下面是修改成python3的代码,因为我是准备用pycharm调试的,所以删除不必要的输出内容
inputtext = '12345678901234567890123'
lenth = len(inputtext)
index = 0
idx = 0
arr =
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
result =
dic = {'eax': 0, 'ebx': 0, 'ecx': 0, 'zf': 0}
while True:
if index <= 10:
dic['eax'] = ~ord(inputtext)
dic['ebx'] = 0
dic['ecx'] = index
dic['zf'] = 0
dic['eax'] = dic['eax'] ^ arr
dic['ebx'] = arr
dic['ecx'] = index
dic['zf'] = 1
result = dic['eax']
else:
dic['eax'] = ord(inputtext) + arr
dic['ebx'] = arr
dic['ecx'] = index
dic['zf'] = 1
dic['eax'] = dic['eax'] ^ 0xcc
dic['ebx'] = 0xcc
dic['ecx'] = index
dic['zf'] = 1
result = dic['eax']
index = index + 1
if index == 23 or index == lenth:
break
while True:
dic['eax'] = result
dic['ebx'] = check
dic['ecx'] = idx
if dic['eax'] != dic['ebx']:
dic['zf'] = 1
print("Wrong flag, try again!")
exit(0)
else:
dic['zf'] = 0
idx = idx + 1
if idx == 23 or idx == lenth:
if lenth == 23:
print("Yes, you got it!")
exit(0)
else:
print("Close to right!")
exit(0)
下面是根据python代码的一些特性,简化一下代码来更简单的分析
第四部分中的
dic['eax'] = result
dic['ebx'] = check
dic['ecx'] = idx
if dic['eax'] != dic['ebx']:
这里可以简化为
dic['ecx'] = idx
if result != check:
dic中的ebx,ecx,zf都是只有赋值,没有被使用到,所以都是删除
删除完以后发现eax也可以进行简化省略
下面是再次简化后的代码
inputtext = '12345678901234567890123'
lenth = len(inputtext)
index = 0
idx = 0
arr =
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
result =
while True:
if index <= 10:
result = ~ord(inputtext) ^ arr# 逆运算 先【^arr】,再~,最后chr
else:
result = (ord(inputtext) + arr) ^ 0xcc # 逆运算 先【^0xcc】,再减去【arr】,最后chr
index = index + 1
if index == 23 or index == lenth:
break
while True:
if result != check:
print("Wrong flag, try again!")
exit(0)
idx = idx + 1
if idx == 23 or idx == lenth:
if lenth == 23:
print("Yes, you got it!")
exit(0)
else:
print("Close to right!")
exit(0)
这里的第三部分的逻辑就可以很好的看到了
前十位是经过~ord(inputtext) ^ arr的运算得到的,那么我们已经有结果,逆运算后就可以得到加密前的内容了,后十位如此类推,逆运算的方法顺序见上方代码注释
接下来使用python编写逆运算的代码
def main():
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
arr =
flag = bytearray() # 省略chr操作
for i in range(23):
if i <= 10:
flag.append(~(check ^ arr))
else:
flag.append((check ^ 0xcc) - arr)
print(flag.decode())
if __name__ == '__main__':
main()
运行后可以得到flag为【52pojie{H4PpY_New_Ye4R}】
回到前面的代码尝试验证得到的flag
结果正确
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
arr =
请问这两个变量从哪里来? 本帖最后由 漁滒 于 2021-3-5 16:49 编辑
云在天 发表于 2021-3-5 16:36
那个python的代码是方便你们分析用的,题目是不含python代码的
哦,原来如此,我大概知道是什么意思了。原题没有源代码,只能一步一步的走,一步一步的看。 学习了,感谢楼主 那个python的代码是方便你们分析用的,题目是不含python代码的 只能一步一步的走 好厉害的 666.厉害 学习看看 硬着头皮看了一下,还是看不懂,啊哈哈 学习了,感谢楼主 谢谢
页:
[1]
2