吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4512|回复: 18
收起左侧

[原创] 【2021春节】逆向高级题

[复制链接]
漁滒 发表于 2021-3-5 16:25
这一题我自己做出来的时候,都不知道是不是钻了什么漏洞,还是说我想的简单了。
初级题我做了快一天,安卓题做了大概一个晚上,高级题有点奇怪,大概半个钟就出来了,话不多说进入正题
高级题的题目是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
0.jpg
结果正确


免费评分

参与人数 6威望 +1 吾爱币 +25 热心值 +5 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
星辰丿 + 1 用心讨论,共获提升!
小哲哲你来了 + 1 + 1 热心回复!
YMYS + 1 + 1 我很赞同!
努力加载中 + 1 + 1 谢谢@Thanks!
ycf0616 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

青山依旧在 发表于 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 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83]

请问这两个变量从哪里来?
 楼主| 漁滒 发表于 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
学习了,感谢楼主 谢谢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-26 14:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表