【2021春节】逆向高级题--超详细题解--小白也能看懂
本帖最后由 Eaysuild.xean 于 2021-3-1 23:00 编辑### 0X01 前(fei)言(hua)
实验环境:WIN10 Python3.8.7 / kali 2020.4 python2
###0x02 拿题看题
1. 判断python版本
```python
print "Welcome to Processor's debugger!"
print "Please input you flag now!"
input = raw_input() #从raw_input()函数可知道此代码运行环境为Python2
```
> 原因:在 Python3.x 中 **raw_input( )** 和 **input( )** 进行了整合,去除了 **raw_input( )**,仅保留了 **input( )** 函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
2. 分析执行流程
1. 先用python2跑一下程序
2. 结合代码分析
```python
# 第一部分 获取数据
input = raw_input() #接收输入的假码
if not input: #判断输入是否为空
"Are you kidding me?"
exit(0)
lenth = len(input)#获取输入假码的长度
if lenth <= 10: #判断假码长度应该 > 10
"Short flag!"
exit(0)
"len:%d" % (lenth)#输出输入假码的长度
#定义输出格式
print "OK,let's debug it! You can 'Step' by 'Space'!" # 输入空格然后按下回车输出
print "--------------INFO--------------"
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--------------"
```
```python
# 第二部分 数据处理
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: #假码前11位 进行以下
#-----------------算法1-Start-----------------------------
dic['eax'] = ~ord(input)# EAX=取出假码索引处的值->取ASCII码->取反
dic['ebx'] = 0
dic['ecx'] = index #索引数
dic['zf'] = 0
debuginfo(dic)
if raw_input() == ' ':
dic['eax'] = dic['eax'] ^ arr #EAX = EAX 和 arr索引的值 进行异或
dic['ebx'] = arr #EBX = arr 索引的值
dic['ecx'] = index
dic['zf'] = 1 #变1
result = dic['eax'] #EAX的值 保存到结果集
debuginfo(dic)
#-----------------算法1-END-----------------------------
else: #从第12位开始 进行以下
#-----------------算法2-Start-----------------------------
dic['eax'] = ord(input) + arr #EAX = 取假码索引处ASCII码 + arr索引的值
dic['ebx'] = arr #EBX= arr索引的值
dic['ecx'] = index
dic['zf'] = 1
debuginfo(dic)
if raw_input() == ' ':
dic['eax'] = dic['eax'] ^ 0xcc #EAX = EAX 异或 204
dic['ebx'] = 0xcc
dic['ecx'] = index
dic['zf'] = 1
result = dic['eax']
debuginfo(dic)
#-----------------算法2-END-----------------------------
index = index + 1
if index == 23 or index == lenth: #可知flag的长度为23
break
while raw_input() == ' ':
dic['eax'] = result #EAX = 结果集索引值
dic['ebx'] = check#EBX = 对比集索引值
dic['ecx'] = idx
if dic['eax'] != dic['ebx']:#进行比较
dic['zf'] = 1
"Wrong flag, try again!"
exit(0)
else:
dic['zf'] = 0
debuginfo(dic)
idx = idx + 1
if idx == 23 or idx == lenth:
if lenth == 23:
"Yes, you got it!"
exit(0)
else:
"Close to right!"
exit(0)
```
3. 核心算法流程图
### 0X03 逆向思维结题
1. 正确的FLAG 到程序最后 应该是和对比集完全一致
```python
check = [-56, -50, -118, -105, -98, -101, -117, -105, -96, -42, -80, 89, 78, 70, 177, 86, 126, 80, 80, 96, 177, 109, 28]
#对比集
```
2. 把对比集 当作输入 并且将过程中的运算变为逆运算
>异或 逆运算还是异或
>
>ord() 逆运算 chr()
>
>取反 逆运算 取反
>
>加号 逆运算 减号
>
然后取对比集的第一个逆运算尝试一下,看来没问题
3. 写算法代码
```python
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]
while index <= 23:
if index <= 10 :
temp=~(check ^ arr)
else:
temp= (check ^ 0xcc) - arr
print(chr(temp), end="")
index=index+1
if index == 23:
break
```
运算结果:**52pojie{H4PpY_New_Ye4R}**
4.验证结果
现在的题解算是白盒分析了,原题是看不到代码的吧?
出题者的代码跑在服务器上,解题者只能通过不断地按空格,然后获得服务器返回提示信息,只能根据寥寥几句eax,ebx,ecx,zf等信息推测服务器代码的算法。
解题者需要有一些汇编、编码的前置知识才会往正确的方向去猜,所以难度还是蛮大的
不过还是感谢您的讲解。:lol 还是看不懂手动滑稽啊{:1_907:} 学习到了,很好! 感谢楼主分享。。。但是还是看不懂。。。 fzwQAQ 发表于 2021-2-28 15:02
还是看不懂手动滑稽啊
小白是指的有点基础的,像我们这种完全没基础的连小白都算不上{:301_1008:} 感谢你的分享,我还需要努力学习 学到了,感谢分享!:loveliness: 怎才能看懂这些代码 ? 不太会玩py {:301_977:}吓得我以为我也能看懂,进来看看我还是想多了哈哈