漁滒 发表于 2021-3-5 16:25

【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

结果正确


青山依旧在 发表于 2021-3-8 08:41

    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:40

本帖最后由 漁滒 于 2021-3-5 16:49 编辑

云在天 发表于 2021-3-5 16:36
那个python的代码是方便你们分析用的,题目是不含python代码的
哦,原来如此,我大概知道是什么意思了。原题没有源代码,只能一步一步的走,一步一步的看。

MZA1220 发表于 2021-3-5 16:36

学习了,感谢楼主

云在天 发表于 2021-3-5 16:36

那个python的代码是方便你们分析用的,题目是不含python代码的

漂荡的大学 发表于 2021-3-5 21:40

只能一步一步的走

Colin0715 发表于 2021-3-6 11:48

好厉害的

shenqidehailuo 发表于 2021-3-6 14:28

666.厉害

wangxiangyake 发表于 2021-3-6 15:20

学习看看

nur11111 发表于 2021-3-6 19:25

硬着头皮看了一下,还是看不懂,啊哈哈

bfg001 发表于 2021-3-6 20:07

学习了,感谢楼主 谢谢
页: [1] 2
查看完整版本: 【2021春节】逆向高级题