Sheet 1

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.

Please keep in mind that you should:

  • read the task description carefully

  • push all your changes to the GitLab repository (main 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).

  • Check the CI-Pipeline status and output for any errors. If the Pipeline is green and the output looks right, your solution should be correct.

  • Make sure that the solution is an executable Python 3 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 2024-04-28 22:00:00 UTC

Task 1 – Encrypted header (4 Points)

Help! All of our executables seem broken! We have attached one for you as fixme. All we got is a ransom letter, claiming our files were encrypted utilizing xor with an unbeatable 8 bit key on their header? Can you write us a script decrypting the binaries?

In more detail:

Write a Python 3 script named solution (with a shebang line at the top so that it can be run as ./solution) that:

  • decrypts the fixme file
  • runs the fixed file and captures its output (e.g., with a function from subprocess (link))
  • prints the captured output of fixme to its stdout again

The final execution of your solution script must look like this:

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

Task 2 – Parse ELF files (8 Points)

We have found a strange symbol in one of our files. Could you write a small Python 3 script scanning the symbols of the given ELF file parseme for the name flag and return its value in hex?

The value must be the same as printed by readelf (leading 0s included):

1
2
$ readelf --symbols parseme | grep flag
     7: 00000000deadbeef     8 OBJECT  GLOBAL DEFAULT   26 flag

Some notes:

  1. You do not want to write a complete parser for ELF in Python!
  2. You can assume that the file is 64 bit (cf. parseme)
  3. You will need to find/parse the string table as referenced by .shstrtab that, for example, contains the strings of the section names .dynsym, .dynstr, … (link), (link)
  4. You will need to iterate over all section headers to find .dynstr and .dynsym (link)
  5. You will need to parse the dynamic symbols string table referenced by the section .dynstr (contains, for example, the string flag).
  6. You will need to parse the dynamic symbols table referenced by the section .dynsym (link)
  7. In the dynamic symbols table you will find a reference to the symbol name (st_name) and to the symbol value (st_value).
  8. If st_name references “flag” print the value st_value.
  9. Use Python’s open, seek, read file methods or Python’s mmap module, as well as struct.unpack to get the correct values.
  10. Might also be helpful: ELF - Wikipedia or man 5 elf

Your solution must look like this:

1
2
./solution
00000000deadbeef

Task 3 – Key Checker (4 Points, individual Task)

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 reverse engineering tool such as IDA Pro, Ghidra, radare2, or Binary Ninja, or use a debugger, such as gdb).

The final task is to write a Python script which must be named solution, is able to generate valid keys, and prints 500 of them to stdout (unique keys, newline-separated, no other output), i.e., your solution could must look like this when executed:

1
2
3
4
5
6
./solution
key1
key2
key3
...
key500

where keyX is a valid key.

Note: Do not brute-force all solutions by executing the binary check_key and checking its output. This is a reverse engineering task.

Task 4 – In-memory decryption (8 Points)

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

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

Edit the provided GDB Python script gdb_script.py to extract the flag. Only use vanilla gdb features, no extensions allowed here!

Then edit the 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
  • If you need a refresher on Python gdb scripting, check out the docs

Your solution must look like:

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

Task 5 – CSV to Json (4 Points)

Have a look at the C code in broken.c! It is a utility to convert CSV (Comma-Separated Values) files into JSON (JavaScript Object Notation) files. Sadly, there still seem to be some bugs, as when we run ./broken test.csv test.json, the first line of each entry is corrupted.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
root@f264241bdee3:/io# gcc broken.c -Wall -o broken
root@f264241bdee3:/io# ./broken test.csv test.json
root@f264241bdee3:/io# cat test.json
[
 {
  "????U": "p???U",
  "last_name": "Doe",
  "email": "john.doe@fkie.fraunhofer.de",
  "gender": "Male",
  "age": "13"
 },
...

Please report ALL vulnerabilities you can find in a solution text file.

hints:

  • It may help running under ASAN gcc broken.c -g -fsanitize=address -o broken.
  • It may also help compile with another compiler to get other warnings.