maybe_xor
感觉这道逆向题与其说是考逆向水平,倒不如说是考编写脚本的能力
首先题目给了个远程地址,nc连接会回显ELF:
接一串base64编码的东东,解码后发现是ELF文件。
用IDA打开发现是从数据段读取24个字节到栈上并进行异或,每个字节异或的值都不同,但异或后的结果不会写回栈
程序的目的是让你算出异或后的字节数组并发送过去,并且这个过程会重复多次
调试可知,虽然每次文件的数据不同,程序入口不同,但汇编代码都差不多。只是每次数据段的偏移和异或值有变化罢了,写一个文件处理脚本即可
具体思路看下面脚本注释即可
from base64 import *
from pwn import *
import struct
# context.log_level = 'debug'image_base = 0x8048000
def get_hex():f = open('elf', 'rb') f.seek(0x18)# 获取程序入口地址并转为文件偏移地址EP = u64(f.read(8)) - image_base# 获取数据的偏移地址f.seek(EP + 7)rsi = struct.unpack("<i", f.read(4))[0] + EP + 11# 读取数据f.seek(rsi)data = f.read(24)# 读取机器码f.seek(EP + 4)opcode = f.read(0x100)i = 0key = bytearray()result = bytearray()# 导出异或数组keywhile i < 0xff:# 判断是不是真的xor指令if opcode[i] == 0x34 and opcode[i+2] == 0x48:key.append(opcode[i+1])i = i + 2continue# 如果到达exit指令则退出if(opcode[i] == 0xf) and (opcode[i+1] == 0x5):breaki = i + 1# 获得结果for i in range(24):result.append((data[i] ^ key[i]) & 0xff)f.close()return bytes(result).hex()# 获取ELF文件
def get_elf():f = open("./elf","wb")base = b64decode(io.recvline()[0:-1])f.write(base)f.close()# 第一次结果程序已给出,将它给的结果发送即可
io = remote("hnctf.imxbt.cn", 37580)
io.recvuntil("Expected bytes: ")
io.send(io.recvline())# 循环处理
try:while(io.recvuntil("ELF: ",timeout=3)):get_elf()io.sendline(get_hex().encode('utf-8'))
except(PwnlibException, EOFError):io.interactive()
结果: