Sheet 3

PABE Exercise Sheet 3

General Information

All solutions must be Python 3 scripts if not stated otherwise. If you are new to Python 3, have a look online, there are many good resources to get started such as this intro course, this advanced course, this blog post, and this slide deck. Feel free to post other resources to the mailing list to help your fellow PABE students.

Please keep in mind that you should:

  • read the task description carefully

  • push all your changes to the GitLab repository (master branch) before the deadline. Make also sure that the file permissions are set correctly! If you are new to Git check out this site!

  • Make sure that your solution (also) runs in the CI environment (and not just your local machine); this also means that you must install all additional packages yourself from within the solution script (see our blog post for details how to do that).

  • Make sure that the solution is an executable python3 script named solution (chmod +x ./solution) with a working shebang line at the top (i.e. #!/usr/bin/env python3) so that it can be executed like this: ./solution (do not name your script solution.py, Solution, solution.sh, … just solution)

  • The final solution string, and only that, must be written to stdout and could be a number, a string, a string with the format FLAG{some letters and digits here}, depending on the specific task.

  • Describe what you are doing using detailed comments for all your solution scripts! For example, use Docstrings (link) or inline comments:

    1
    2
    3
    4
    5
    6
    7
    8
    
    def check_input_length(input_string):
        """
        The input string must have a length greater than 42 and must also be even.
        """
        length = len(input_string)
    
        # the final check happens here
        return (length > 42) and (length % 2 == 0)
    

    This helps us to find out if you really understood the task and you are not just brute-forcing some solutions. Please do not leave any commented code (i.e., code that is not needed to solve the task) in your solution files!

  • Make sure that your solution executes within 10 seconds (this is a hard timeout on our server).

  • Violating any of the points above might lead to reduced final points for the specific task!


The deadline for this sheet is Tuesday, 2021-11-30 23:59:59 CET

Task 11 – Key Checker II (8 Points)

The program check_key needs a valid key as an input. Find out how to provide the key to the program and how the key checking algorithm works (use a disassembler such as Ghidra, IDA Pro, radare2, binary ninja or use a debugger, such as gdb).

The final task is to write a Python script solution that generates one valid key and prints it to stdout. This time you must use the z3 Python module (link) (link) to solve the constraints on the key.

Your solution could, for example, look like this:

1
2
./solution
thisisavalidkey

Task 12 – Function Tracer (4 Points)

To make you even more familiar with GDB (you’ll need it for the upcoming exploitation exercises a lot!) here is another task to be solved with a GDB Python script (link).

Your task is to program a function call tracer for the traceme binary that prints the names of all functions visited during the execution of the program to stdout. Start the tracing at _start and let the program run until it finishes.

Hints:

  • If a function has a name in GDB it is displayed in an angle brackets call 0x40fa90 <puts>.
  • How can you make GDB stop at every call instruction?
  • Write the trace to a file first and then print the contents of the file to stdout, thus you avoid having all the verbose output of GDB in your output.
  • Also: make sure you respect the execution timeout (see General Information above)

Your solution could look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ./solution
_start
__libc_start_main
get_common_indeces.constprop.1
generic_start_main
_dl_aux_init
_dl_discover_osversion
uname
__pthread_initialize_minimal
sbrk
brk
brk
memcpy
__libc_init_first
__libc_init_secure
_dl_non_dynamic_init
_dl_get_origin
malloc
ptmalloc_init.part.5
_int_malloc
malloc_consolidate
sysmalloc
...

Task 13 – Simple Buffer Overflow (4 Points)

Have a look at the simple_bo file. You have to find out how the binary works and how you can make it print the flag. Please do not just brute-force possible solutions. This may lead to a reduced number of points for the task.

Your concrete task is to:

  • reverse the binary and understand how it may be exploited so that it prints the flag

  • write a Python script that exploits the binary and prints the flag

  • describe your approach using a docstring at the top of the file (below the Shebang line!); we want to know what is happening exactly and why the flag is printed… describe the mechanisms!

    • just an example:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      ###!/usr/bin/env python3
      
      """
      The binary does foo and bar. We have to check that x, y, and z are true.
      After we did ... we use ... to make the program print the flag.
      """
      
      def main():
          pass
      
      ...
      

Your solution should look like:

1
2
$ ./solution
FLAG{some letters and/or digits here}

Task 14 – Reverse Me (8 Points)

Seeing how effortless you managed to parse integers on the last sheet, we fired our old programmer without further consideration. However, we were informed that his legacy code still drives a part of our system.

We found one of these binaries: reverseme. Please re-implement its functionality as a Python script called solution. We had a brief look, and what seemed a bit strange to us, we can not remember him ever implementing so many functions!?

Hints:

  • Use all the tools we mentioned in the lecture to get a good overview first!
  • What is a callback?
  • How does this program take user input? How does it behave if there is no such input?
  • The program has different exit codes / return value types (4 of them) depending on the user input. Make sure your program uses the same codes depending on the user input!
  • Use high level python libraries such as requests or httpx.
  • You are reimplementing this in Python 3 for a reason. Do not meticulously recreate the effects of limited buffer sizes in C, or the exact behaviour of hacky shortcuts our old programmer might have taken.
  • The easiest solution is to just call the binary directly in your python script. That is however not the point of this exercise 😂

PS: Encodings are annoying, do not worry about the occasional � in your strings for this task.

Task 15 – In-memory decryption II (8 Points)

Have a look at the extractme executable. It decrypts a flag during runtime. Please try to extract it again.

The flag is in the format FLAG{some characters here}.

Write a (vanilla, not pwndbg!) GDB Python script that extracts the flag.

Write a solution script that calls GDB with your GDB Python script and prints the flag to stdout.

Hints:

  • Try to find the flag with pwndbg first an then write the script.
  • At no point in time, the flag is completely decrypted.
  • You can capture the output of your gdb call and then extract the flag from that in your solution script

Your solution should look like:

1
2
$ ./solution
FLAG{some characters here}