Home Assignment 2a › hacker track › assignment2-177 Digital test Mon, 20 Apr Submit
Aryan
No shell in the binary? Bring your own. NOP-sled, shellcode, overflowed buffer. scanf is now my favourite and least favourite function.
Aryan

See the assignment's PDF available on BrightSpace for task descriptions and submission requirements.

Level 8

8
(1) Explain what were the vulnerabilities of the target program of this level.
(2) Explain how you exploited the aforementioned vulnerabilities to get access to the next level.
Your explanations must be clear and not miss any detail. Take care that with your explanations a reader would be able to exploit the target program.
Answer

1) The vulnerability is that they use scanf("%d", &choice); and that can be used for buffer overflows.

2) There's no /bin/sh or /bin/bash in the code itself, we must inject shellcode via the scanf into the username buffer. Maybe use NOP sleds if it turns out to be difficult to determine the correct offsets.
Start gdb:

students177@appsec2026:/levels/level8$ gdb ./level8
(gdb) run
Starting program: /levels/level8/level8
warning: Probes-based dynamic linker interface failed.
Reverting to original interface.
process 754960 is executing new program: /levels/level8/level8
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
What is your name?
Ary
Welcome, Ary!
What do you want to do?
1)Solve this exercise
2)Get access to a shell
2
That would be too easy...
[Inferior 1 (process 754960) exited normally]
(gdb) start
Temporary breakpoint 1 at 0x555555555191
Starting program: /levels/level8/level8
process 754972 is executing new program: /levels/level8/level8
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, 0x0000555555555191 in main ()

When we disassemble main: let's find the first scanf which writes into username bufffer, so it should reveal the location

0x70 = 112 bytes until RBP, and after that we have the old RBP, so 120 bytes in total
the 8 bytes after that are the return address, which we must overwrite
Let's find the actual mem addr where username starts by breaking after scanf and printing:

unset env LINES 
unset env COLUMNS
Breakpoint 2, 0x00005555555551cf in main ()
(gdb) print/x $rbp - 0x70
$1 = 0x7fffffffe8d0

Note: I did it again with the shellcode injected, and I ran unset env LINES and unset env COLUMNS in GDB and I got a different value: 0x7fffffffe8f0, so I'm using that one.

Now I'm going to write a python script:
the shellcode to run /bin/sh is 27 bytes
we need to fill the 120 bytes with 27 bytes shell code, and the remaining 93 bytes:
Since the shell code needs space to push thiings on the stack, and if we don't have proper padding, the shellcode (living in the stack itself) will overwrite and corrupt itself. The code below leads to shellcode corruption

instead do it with padding:

I want the return address to be somewhere in the middle instead of on the edge 0x7fffffffe8f0, so i put in some bytes inwards (little endian in code, see comment)
Now make payload

python3 ~/lv8_exploit.py > ~/payload.bin

and run

Shellcode Injection via scanf
No shell is in the binary, so we inject our own. A username buffer at $rbp-0x70 receives our shellcode. We overflow past the buffer to overwrite the return address with a NOP-sled pointer. When the function returns, it lands in our shellcode.