Sheet 2
General Information
The solutions should be created mainly with Python but it is also allowed to use a little bit of shell/Bash magic for your solution
file. If you are new to Python have a look online… there are many good resources to get started such as this course and this slide deck. Feel free to post other resources to the mailing list to help other PABE students.
Please keep in mind that you should:
push
all your changes to the GitLab repository (master
branch) before the deadline. Make also sure that the file permissions are set correctly!- make sure that your solution (also) runs on the virtual machine (and not just your local machine)
- make sure that the solution is an executable script named
solution
with a working shebang line at the top (e.g.,#!/usr/bin/env python2
) so that it can be executed like this:./solution
- the final solution string (and only that) must be written to
stdout
and could be a number, a string, a string with the formatFLAG{some letters and digits here}
, depending on the specific task - read the task description carefully, for example, if we ask you to write a Python script do not submit a Bash script or something else
Describe what you are doing using comments for all your solution scripts regardless of programming language (Bash, Python, C, …). You could use, for example, Python Docstrings (link) for you Python programs:
|
|
This helps us to find out if you really understood the task and you are not just brute-forcing some solutions.
The deadline for this sheet is Tuesday, 2019-11-19 23:59:59
Task 6 – Key Checker
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 IDA Pro 7, radare2, binary ninja or use a debugger, such as gdb).
The final task is to write a Python script as solution
that is able to generate valid keys and print 500 of them to stdout
(unique keys).
Your solution could, for example, look like this:
|
|
where keyX
is a valid key.
Note: Do not brute-force all solutions by executing the binary check_key
and checking its output. It’s a Reverse Engineering Task ;-)
Task 7 – In-memory decryption
Have a look at the binary xor
. When you run the binary it seems that nothing happens… If you have a look at the disassembly (e.g. with objdump
or any other disassembler) you can see that there is a string within the binary that gets decrypted during runtime. The decrypted string only exists during the execution but will not be printed to stdout
.
Your task is to write a gdb script in Python (link) that sets a breakpoint at the correct address (when the string is finally decrypted), runs the program and outputs the string to stdout
. This time your solution
can be a Bash script that calls gdb with the Python script as an argument (gdb --command=<your Python script>
) . Make sure that only the decrypted string is printed to the final stdout
(e.g., Bash’s stdout
).
Your solution could, for example, look like:
|
|
Task 8 – Broken Header
Oh no! Our binary broken
is causing segmentation faults. What is happening here? There could be something wrong with the header…
Your task is to write a Python script that patches and executes the binary broken
.
Your solution could, for example, look like:
|
|
Hint: You should check the header of a working binary (e.g. /bin/ls
) and compare it to the broken binary.
Task 9 – Broken Code
Oh no again! Another binary also called broken
is not printing the flag. I think the evil wizard of three-mistakes has corrupted it. Can you help us? Before this incident the binary printed a flag and exited with return code 42!
Your task is to write a Python script that patches the binary broken
so that it runs as expected.
Your solution could, for example, look like:
|
|
Hints:
- The broken code can be found in the function
_start
. - You can use the
pwntools
command line toolasm
to get the opcodes for a specific assembler instruction:1 2
$ asm "mov eax, 0x1" b801000000
1
Task 10 – Unicorn Engine
Unicorn Engine is a CPU emulator that supports many different architectures (link) CPU emulator means that you won’t have any support from the operating system and have to work very low level. This is especially true for memory mapping.
We provided you a solution
file with some Python code. When you run the code (i.e. ./solution
) you will notice that you get an error ERROR: Invalid memory read (UC_ERR_READ_UNMAPPED)
.
Your task is to:
- understand the Python and assembly code
- find out why the error messages occur
- fix the Python code so that the emulation runs correctly
If I remember correctly the value 0x1337
was stored at the address 0x31337
(mov eax, [0x31337]
)
With the code tracing hook in place engine.hook_add(UC_HOOK_CODE, hook_code)
you will also see the currently executed instruction via stdout
.
Your final solution could, for example, look like:
|
|
We will check the last 4 lines to see if the results are correct. Do not modify the simple_asm
code.
Hints:
- How can you catch illegal memory accesses?
- Must the memory you map be aligned somehow?