Lab 01 - Introduction. Basic Exploration Tools
(adapted from https://ocw.cs.pub.ro/courses/cns/labs/lab-01)
Resources
- assembly calling convention on x64
- assembly calling convention on x86
- gdb documentation
- strings (1) manual
- xxd (1) manual
- Perl - How do I escape/encode special characters
- Sending hex packets in Python
- Hex escape strings in Python
- strace (1) manual
- objdump (1) manual
- nm (1) manual
- ld.so (8) manual
- Radare2 Cheatsheet
Supporting files
Introduction
You will spend a large part of the labs and assignments working with binaries; in some of the cases we will also provide you with source code. You will have to find vulnerabilities in those binaries, then (possibly) exploit them and (possibly) fix the vulnerabilities in order to illustrate various secure coding practices. To achieve this, first you need to get comfortable with at least some of the common tools that are right for the job.
In the introductory lab we'll spice things up a bit by providing some simple binaries (with no source code) for you to play with. In order to solve the lab, you'll have to perform both static analysis and dynamic analysis on said binaries.
1. even-password
The binary even-password
is asking you to provide a password:
$ ./even-password
Enter password:
Unfortunately, the program isn't very well thought out, the password being hard-coded. There are a few possible approaches to this (try them all):
- Using
strings
to see if the password is hard-coded as an ASCII string - Using
objdump
to see if the password is hard-coded as a set of instructions (e.g. copying characters into a buffer)
Even if you we lucky to guess the password from the information you got from strings
we can use this simple example to learn a few details about binary organization. Binaries are internally organized in sections. For example, the .text section has contains the machine language instructions of the program. Do an objdump -d -j .text even-password
to obtain a disassembly of the instructions of the program.
- In the
main
function, what is the address of the instruction that callsstrcmp
? - Use
gdb
to show the contents of therdi
andrsi
registers just beforestrcmp
is called.
2. odd-password
Same as the previous task, only this time the password is a non-ASCII string. The following approach should work:
- Disassemble the binary and look at main. What functions does it call?
- Once you have the program flow figured out, look at how the password checking is done and figure out the password.
- Perhaps the password is a string of characters not available in the keyboard. If so you can use python to output raw bytes which you can input to the program. Use the following snippets as reference:
$ # output 0x02 20 times, followed by 0x03 and a newline and feed to the odd-password
$ python -c 'print ("\x02"*20 + "\x03")' | ./odd-password
3. halting-problem
Disassemble halting-problem using objddump - d
and take a look at it. Notice that it calls sleep
with the value 0x186a0
. Look for documentation about the sleep
linux system function.
- How many seconds will the sleep function sleep when it receives argument
0x186a0
? - In the disassembly you can see the machine code bytes corresponding to the
mov edi,0x186a0
instruction. What are they?
Use a hex editor of your choice (Bless, HTE etc.) to edit the value to something more convenient, e.g. passing a 0x0 instead of a 0x186a0
. Once you change the binary, save it and run it.
- What is the final line of output when you run the modified binary.
4. straceme
Use only dynamic analysis to figure out what straceme does. First strace it:
$ strace ./straceme
It doesn't seem to be doing anything relevant, so let's run it in gdb
.
$ gdb ./straceme
(gdb) b main
(gdb) r
(gdb) stepi
If we run the program a couple of times, we observe that the condition for cmp DWORD PTR [rbp-0x44],0x2
fails. Let's inspect that address:
(gdb) x/w $rbp-0x44
0x7fffffffd62c: 0x00000001 (the address might be different in your computer)
The rbp
register holds the base pointer for the current stack frame. We notice that $rbp - 0x44
holds the value 1
, while our program expects the value 2
. What is that value?
After figuring that out, run the program with strace
again to determine the password.
5. guesser
guesser
reads an unsigned int from /dev/urandom
and asks you to guess it.
- Disassemble the binary using
objdump
and examine its control flow. - Run the binary using
gdb
and place a breakpoint after theread
call. - Inspect the memory location of the variable where the random value was placed by
read
. If in doubt, consult the GDB documentation and the read (2) manpage. - Resume the program's execution and input the random value
Deliverables
Turn in a report through Moodle (online.upr.edu).