The theme of the day was dynamic analysis of programs, and some tools to use.
Software tools used today
- determine the file type from its contents.
- print the strings of printable characters in files.
- the GNU debugger.
- Run a program and print used library calls and their arguments.
- make a hexdump of a file.
A hexdump is a printable representation of data, it typically looks like this:
$ xxd a.out 00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............ 00000010: 0300 3e00 0100 0000 7006 0000 0000 0000 ..>.....p....... 00000020: 4000 0000 0000 0000 e019 0000 0000 0000 @............... ...
Every line displays 16 bytes. To the left is the address (or file offset), in the middle is the data in hexadecimal, and the rightmost column shows the same data but as printable characters. In this case, the second, third and fourth bytes (offset 1 to 3) are 0x45, 0x4c, 0x4f or “ELF”. Non-printable characters are show as dots.
A note of caution, do NOT use
xxd to dump multiple files at once,
as it will assume the second argument is a destination to write the dump to. This destroys the file in the second argument.
(Lars has done this, on important files…)
$ xxd *
gdb is a very powerful tool, but it can take some time to get
used to. It has a command line interface.
Here are some common
- help - get inline help about commands
- run (r) - run program from beginning
- continue (c) - continue from current location
- x - examine memory (requires a format and an address)
- backtrace (bt) - print the call stack from current position (What series of function calls made the program end up at this point?)
- info - information about program structure (takes extra argument)
- info proc map - information about memory areas in the running process (Where are the stack, heap, executable, libraries etc located in memory?)
- info register - list registsrs and their contents
- disassemble - list the assembler instructions of a function.
Sometimes the disassemble command does not work, especially if you execute code where you are not supposed to… It is possible to use the x command with the instruction format.
(gdb) disassemble $rsp No function contains specified address. (gdb) x/5i $rsp 0x7fffffffdd60: add %cl,0x55(%rdx) 0x7fffffffdd63: push %rbp 0x7fffffffdd64: push %rbp 0x7fffffffdd65: push %rbp 0x7fffffffdd66: add %al,(%rax) (gdb)
ltrace can almost feel like cheating sometimes, in a good way.
As an exercise, we wrote small programs that checked for a password and then took them apart.
Analyzing Lars' binary
Lars had written a small program, and the task was to find out what it did.
Analyzing binary 2
We made an assembler listing with
objdump -d and commented it. Together
we examined the instructions to find out what it did and what input it
We also tried dynamic analysis:
$ ltrace ./easy <<< asdfasdfasdf read(0, "asdfas", 6) = 6 strncat(0x7fffe1749030, 0x7fffe17490ca, 5, 0x7fffe17490ca) = 0x7fffe1749030 popen("echo -n asdfa | md5sum", "r") = 0x5628600d9260 fgets("aa41efe0a1b3eeb9bf303e4561ff8392"..., 256, 0x5628600d9260) = 0x7fffe17490d0 --- SIGCHLD (Child exited) --- pclose(0x5628600d9260) = 0 strncmp("aa41efe0a1b3eeb9bf303e4561ff8392"..., "8b1a9953c4611296a827abf8c47804d7"..., 32) = 41 puts("Fuck off!"Fuck off! ) = 10 +++ exited (status 0) +++
This gave the same result as the static analysis, just a bit quicker.
The program reads six bytes, calls
popen() to compute the md5 checksum of the
bytes and then compares the checksum to “8b1a9953c4611296a827abf8c47804d7”.
This can be brute-forced, but even easier is to search for the hash and
see that it is “Hello”.
There was also an uninteded solution. The binary used popen(), and it was possible to get the correct output by supplying a bogus version of md5sum:
$ ./easy <<< asdfasdfasdf Fuck off! $ ls -l md5sum -rwxrwxr-x 1 larsh larsh 53 Sep 9 19:52 md5sum $ cat md5sum #!/bin/sh echo "8b1a9953c4611296a827abf8c47804d7 -" $ PATH=. ./easy <<< asdfasdfasdf Access granted! $
But this is a more advanced technique that we might cover more at another meeting.
We briefly looked at alternative debuggers.
For windows there is
Ollydbg, there is also
EDB but noone had used it.
A visual debugger makes some patterns easier to spot, such as ASCII string pointer in registers.