[H&NCTF] maybe_xor题解
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 = 0
key = bytearray()
result = bytearray()
# 导出异或数组key
while i < 0xff:
# 判断是不是真的xor指令
if opcode[i] == 0x34 and opcode[i+2] == 0x48:
key.append(opcode[i+1])
i = i + 2
continue
# 如果到达exit指令则退出
if(opcode[i] == 0xf) and (opcode[i+1] == 0x5):
break
i = 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()
结果: