2021鹤城杯-re-Petition
我一开始很好奇,它对栈顶数据的操作方式,因为没有单独出现,而是出现了、等这种偏移的访问方式,这个阻碍了我进一步的分析。。动态调试下,对应的指令就直接是 :
scanf(""%63s", 0xffffd190)
此时 = 0xffffd190
此时,edi =
在0x402910里面,如果验证不正确,则最后的返回地址为start函数里的地址,如果正确,则为其他地址:
sub_402910 这个核心函数的逻辑为:
将传入参数与call指令下一个位置的地址相减,然后与dl相乘,再加回减去的地址,然后跳转到计算后的地址中
经过验证,当dl为1的时候,传入参数即可作为地址被调用成功。
esp_4 = 0x40119C
esp = 0x40117A
ret_addr = 0x40119C
#dl = ^ 0x0CC84881E) & 0xff)]
#ret_addr = (dl * ( - )) & 0xff +
temp1 = esp_4 - esp
print((ret_addr - esp)/temp1)
我没看懂的地方
官方题解说:
start函数中,只有一处向内存中写入1
而在这里,又将的值赋给了edx,再向下就是校验函数了。显而易见,我们的目的就是让程序在执行到xor byte ptr , 1这条指令时,让eax与edx相等。
于是有:
(esp ^ input ^ 0x0CC84881E) & 0xFF == esp ^ 0x3E ^ 0x46
即
input ^ 0x1E ==0x3E ^ 0x46
然后写脚本匹配,批量提取信息反推flag。
它的信息可能是指,如果你的输入是正确的,就会导致dl为1,输入错误就不能,应该是在xor edx, 这一步,将赋值给edx。它是怎么搞的我实在没看懂。
脚本
import idc
import idaapi
import idautils
import re
idaapi.auto_wait()
flag = ""
count = 0
for func in idautils.Functions():
# Ignore Library Code
flags = idc.get_func_flags(func) # 获取函数的标志,分为lib和普通函数等
#print("flags: ", flags)
if flags & FUNC_LIB: # 跳过系统函数
continue
instuction_generator = idautils.FuncItems(func) # <class 'generator'>
instuction_list = list(instuction_generator)
len_list = len(instuction_list)
opnd1 = 0
opnd2 = 0
opnd3 = 0
for i,instruction in enumerate(instuction_list): # 当前函数中的每个指令地址
# 匹配指令 xor bl, 对应操作码 32 1E ; xor ebx, XXh 对应操作码81 F3 XX XX XX XX
if idaapi.get_byte(instuction_list) == 0x32 and idaapi.get_byte(instuction_list+1) == 0x1E:
if i+1 < len_list: # 防止越界访问
if idaapi.get_byte(instuction_list) == 0x81 and idaapi.get_byte(instuction_list+1) == 0xF3:
opnd3 = idaapi.get_dword(instuction_list + 2)
print(hex(opnd3))
#count += 1
if i+1 < len_list:
insText = idc.generate_disasm_line(instuction_list, 0) # 获取指令
nextInsText = idc.generate_disasm_line(instuction_list, 0) # 获取指令
if "xor eax," in insText and 'h' in insText and "xor eax," in nextInsText and 'h' in nextInsText:
opnd1 = idc.get_operand_value(instuction_list, 1)
opnd2 = idc.get_operand_value(instuction_list, 1)
print("opnd1: ", hex(opnd1))
print("opnd2: ", hex(opnd2))
flag += chr(int((opnd3 ^ opnd1 ^ opnd2) & 0xFF))
print(flag)
题目文件:
Petition.zip
部分图片插入错误,请查看帮助 很好,关注一波 终于找宝贝了 批量提取信息反推flag,非常舒适 支持支持,撒花{:1_918:} tl;dr 发表于 2021-11-19 05:15
鹤城在哪里?
河南省鹤壁市吧
页:
[1]