pwntools 读取程序输出的同时也记录在日志文件中

pwn_college

在使用 pwntools 的 pwnlib.tubes.process 模块时,遇到的问题是,既想要用 recvuntil() 在脚本中读取到程序的 stdout 输出,又想在终端 PTY 上同时看到程序的输入。

一般这是把程序 pipe 到 tee 来解决的,但得起个 shell 还得处理 buffer 的问题。
要么就只使用 recvline(),每次收到数据后自行转写文件。
或者直接开启 debug 日记级别,不过默认的输出格式和程序直接在终端上输出的样子大相径庭。

最后想了个简单的注入方式:

def tee(process, logfile='/tmp/challenge.log'):
    orig_send_raw = process.send_raw
    orig_recv_raw = process.recv_raw
    log_file = open(logfile, 'wb')
 
    def send_raw(data):
        log_file.write(data)
        log_file.flush()
        return orig_send_raw(data)
 
    def recv_raw(numb):
        data = orig_recv_raw(numb) or b''  # orig may return str('')
        log_file.write(data)
        log_file.flush()
        return data
 
    process.send_raw = send_raw
    process.recv_raw = recv_raw
    context.terminal = ['tmux', 'splitw', '-v']
    run_in_new_terminal('tail -s 0.1 -f ' + logfile, kill_at_exit=False)
 
 
p = process('/challenge/run')
tee(p, '/tmp/challenge.log')

把 process 类真正处理输入输出的 send_raw & recv_raw 封装起来。
纵向分屏避免 tail 窗口关闭后因终端宽度变更,终端上已有文字产生错位。