Loading

[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()

结果:

posted @ 2024-05-14 12:18  S1nyer  阅读(125)  评论(0编辑  收藏  举报