这一题我自己做出来的时候,都不知道是不是钻了什么漏洞,还是说我想的简单了。
初级题我做了快一天,安卓题做了大概一个晚上,高级题有点奇怪,大概半个钟就出来了,话不多说进入正题
高级题的题目是python源码,先打开看一下。好家伙,是python2的代码,我电脑没有装python2,那就先看一下逻辑,然后改为python3可以运行的代码
大概分为四部分,第一部分是输入以及判断输入内容,第二部分是初始化整数,列表,字典,第三部分是加密函数,第四部分是对比函数
从第四部分中的
if lenth == 23:
print("Yes, you got it!")
这里可以知道flag的长度是23位
下面代码是将原题目加上了一些注释
[Python] 纯文本查看 复制代码 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 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83]
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 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
dic = {'eax': 0, 'ebx': 0, 'ecx': 0, 'zf': 0}
# 加密函数
while raw_input() == ' ':
if index <= 10:
dic['eax'] = ~ord(input[index])
dic['ebx'] = 0
dic['ecx'] = index
dic['zf'] = 0
debuginfo(dic)
if raw_input() == ' ':
dic['eax'] = dic['eax'] ^ arr[index]
dic['ebx'] = arr[index]
dic['ecx'] = index
dic['zf'] = 1
result[index] = dic['eax']
debuginfo(dic)
else:
dic['eax'] = ord(input[index]) + arr[index]
dic['ebx'] = arr[index]
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[index] = dic['eax']
debuginfo(dic)
index = index + 1
if index == 23 or index == lenth:
break
# 判断结果
while raw_input() == ' ':
dic['eax'] = result[idx]
dic['ebx'] = check[idx]
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调试的,所以删除不必要的输出内容
[Python] 纯文本查看 复制代码
inputtext = '12345678901234567890123'
lenth = len(inputtext)
index = 0
idx = 0
arr = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83]
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 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
dic = {'eax': 0, 'ebx': 0, 'ecx': 0, 'zf': 0}
while True:
if index <= 10:
dic['eax'] = ~ord(inputtext[index])
dic['ebx'] = 0
dic['ecx'] = index
dic['zf'] = 0
dic['eax'] = dic['eax'] ^ arr[index]
dic['ebx'] = arr[index]
dic['ecx'] = index
dic['zf'] = 1
result[index] = dic['eax']
else:
dic['eax'] = ord(inputtext[index]) + arr[index]
dic['ebx'] = arr[index]
dic['ecx'] = index
dic['zf'] = 1
dic['eax'] = dic['eax'] ^ 0xcc
dic['ebx'] = 0xcc
dic['ecx'] = index
dic['zf'] = 1
result[index] = dic['eax']
index = index + 1
if index == 23 or index == lenth:
break
while True:
dic['eax'] = result[idx]
dic['ebx'] = check[idx]
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[idx]
dic['ebx'] = check[idx]
dic['ecx'] = idx
if dic['eax'] != dic['ebx']:
这里可以简化为
dic['ecx'] = idx
if result[idx] != check[idx]:
dic中的ebx,ecx,zf都是只有赋值,没有被使用到,所以都是删除
删除完以后发现eax也可以进行简化省略
下面是再次简化后的代码
[Python] 纯文本查看 复制代码
inputtext = '12345678901234567890123'
lenth = len(inputtext)
index = 0
idx = 0
arr = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83]
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 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
while True:
if index <= 10:
result[index] = ~ord(inputtext[index]) ^ arr[index] # 逆运算 先【^arr[index]】,再~,最后chr
else:
result[index] = (ord(inputtext[index]) + arr[index]) ^ 0xcc # 逆运算 先【^0xcc】,再减去【arr[index]】,最后chr
index = index + 1
if index == 23 or index == lenth:
break
while True:
if result[idx] != check[idx]:
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[index]) ^ arr[index]的运算得到的,那么我们已经有结果,逆运算后就可以得到加密前的内容了,后十位如此类推,逆运算的方法顺序见上方代码注释
接下来使用python编写逆运算的代码
[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 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83]
flag = bytearray() # 省略chr操作
for i in range(23):
if i <= 10:
flag.append(~(check[i] ^ arr[i]))
else:
flag.append((check[i] ^ 0xcc) - arr[i])
print(flag.decode())
if __name__ == '__main__':
main()
运行后可以得到flag为【52pojie{H4PpY_New_Ye4R}】
回到前面的代码尝试验证得到的flag
结果正确
|