Sheet 4

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-06-16 22:00:00 UTC

Task 16 – Heap Visualization (4 Points)

Motivation: It is often necessary to “extend” GDB with own scripts to make your own lifes more comfortable. Examples of such extensions are:

So some day this little scripting exercise might come in very handy ;) And now your task…

Write a GDB script that visualizes parts of the heap by showing all free chunks (fast bin, small bin, unsorted bin, large bin chunks). Your solution must not use pwntools/pwndbg.

In more detail:

In GDB you can use libc’s debugging symbols to get information about the main_arena like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
(gdb) p main_arena 
$1 = {
  mutex = 0, 
  flags = 0, 
  have_fastchunks = 0, 
  fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
  top = 0x0, 
  last_remainder = 0x0, 
  bins = {0x0 <repeats 254 times>}, 
  binmap = {0, 0, 0, 0}, 
  next = 0x7ffff7facc40 <main_arena>, 
  next_free = 0x0, 
  attached_threads = 1, 
  system_mem = 0, 
  max_system_mem = 0
}

There you can see the fastbinsY, bins, the top chunk and so on. Implement a gdb.Command (https://sourceware.org/gdb/onlinedocs/gdb/Commands-In-Python.html#Commands-In-Python) that can be used with freeheapchunks in GDB and shows all free chunks (fast bin, small bin, unsorted bin, large bin chunks) like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
free fast bin chunks:

prev_size = ???, 
size = ???,
fd = ??? 
bk = ???
fd_nextsize = ??? 
bk_nextsize = ???
data = ??? 

...snip...more chunks here...

free small bin chunks:

prev_size = ???, 
size = ???,
fd = ??? 
bk = ???
fd_nextsize = ??? 
bk_nextsize = ???
data = ??? 

...snip...more chunks here...

free large bin chunks:

prev_size = ???, 
size = ???,
fd = ??? 
bk = ???
fd_nextsize = ??? 
bk_nextsize = ???
data = ??? 

...snip...more chunks here...

free unsorted bin chunks:

prev_size = ???, 
size = ???,
fd = ??? 
bk = ???
fd_nextsize = ??? 
bk_nextsize = ???
data = ??? 
...snip...more chunks here...

The ??? should contain the correct values in hexadecimal notation.

Also note:

  • First, some of the values make no sense for specific chunk types (e.g., fastbins do not have a bk pointer) so set them to n/a for not available.
  • Second, some bins hold linked lists with specific sizes (e.g., chunks of size 0x20, 0x30, …), so print all the free chunks in every bin of any size.

The data field (which is not part of a libc heap chunk) should give a “preview” of the data that is still inside the chunk’s malloc()ed memory even if the chunk has been free()d by the user. If the data is printable then print it, if it is not printable render a dot (.) like in xxd.

Please use the code in malloc_and_free.c as a reference and invoke your custom command freeheapchunks at the lines where the comments tell you to do so (set the breakpoints accordingly). Also use the provided binary malloc_and_free. Here is a snippet of the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// snip

int main(int argc, char **argv)
{
	srand(time(NULL));

	noise();

	// invoke your command here

	char *string_1 = (char *)safe_malloc(32);
	strcpy(string_1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
	char *string_2 = (char *)safe_malloc(32);
	strcpy(string_2, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
	char *string_3 = (char *)safe_malloc(128);
	strcpy(string_3, "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC");
	char *string_4 = (char *)safe_malloc(256);
	strcpy(string_4, "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
	char *string_5 = (char *)safe_malloc(512);
	strcpy(string_5, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
	char *string_6 = (char *)safe_malloc(4096);
	strcpy(string_6, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
	
	// invoke your command here
	
	free(string_1);
	free(string_2);

	// invoke your command here
	
	free(string_3);
	free(string_4);
	free(string_5);
	
	// invoke your command here
	
	free(string_6);

	// invoke you command here
	
	return 0;
}
// snip

Use pure GDB (not pwntools/pwndbg, you can add a -n to the gdb ... command to not use .gdbinit) to solve this task! You may ignore the tcache bins if you want.

Once again, edit the provided solution template and explain your approach with meaningful comments! This solution template expects a gdb_heap_vis.py file which is your GDB script.

Task 17 – Notebook App (4 Points)

We got a new app that allows you to take notes. There are two kinds of notes: simple ones and printable ones. The app is still work in progress so there might still be some bugs.

Find the bug in the notebook application and exploit it to print the flag. As always, describe what you are doing with technical details in comments so that we see that you fully understood the vulnerability and the exploit.

Once again, edit the provided solution template and explain your approach with meaningful comments!

Hints:

  • What happens if you set the printing function to puts() and then have heap allocation with the same size before that?
  • Have a closer look at the struct printable_note

Your solution should execute like this:

1
2
./solution
FLAG{some letters}

Task 18 – Bank Robbery 2.0 (12 Points, individual Task)

You are now a member of the digital bank robber group Fang-Den-Shui which is famous for stealing money from the rich and giving it to the poor. Are you ready to prove your value?

To successfully rob the bank, exploit bank_robbery to make it print the flag!

Edit the provided solution template and explain your approach with meaningful comments!

Hints:

  • Can you configure your panic() function wisely?
  • Maybe read up on scanf again.
  • Are you able to influence the allocation on the heap in a way that you are able to overwrite something nice there?

Your solution should execute like this:

1
2
./solution
FLAG{some letters here}

Task 19 – Some Poison for the cash machine (16 Points)

Money is not everything, but with money everything is more fun. Therefore we want to use this awesome cash machine to get our money printed.

Poison cash_machine in a way that it gives you a shell, and use the shell to print the flag!

Edit the provided solution template and explain your approach with meaningful comments!

Hints:

  • Have a look at the backdoor function
  • How can you set up RDI when invoking the backdoor function?
  • Which functions offers you the possiblity that your allocation gets into the TCACHE?
  • Can you see the diference between the cashbox_delete and the cashbox_update functions? What can you use after that?

Your solution should execute like this:

1
2
./solution
FLAG{some letters here}

Task 20 – Fake it till you make it! (8 Points)

Can you leverage the Cheat class to print the content of flag.txt?

Hints:

  • What do you know about vtables?
  • Can you leverage your Nickname wisely?

Your solution should execute like this:

1
2
./solution
FLAG{some letters here}