These are the exploiting challenges that formed part of the CTF organized at the Ciberseg 2017, a conference about cibersecurity that takes place every year in our university.

Last year was the first edition (hopefully, there will be more, as it was pretty fun) of the CTF (and I won the first price, btw :D).

First challenge: Buffer overflow

Unfortunately, I lost the data for this challenge; so I can’t write about it :(


Second challenge: Format string

Materials

For this challenge, we were given an address of a server that was running some program, and the source code of said program.

The source code can be downloaded here (note that all text is in spanish). To compile it, simply run gcc -m32 format-main.c, and make sure to disable Adress Space Layout Randomization (the challenge is still feasible with ASLR enabled, but it’s easier with it disabled) by executing echo 0 | sudo tee /proc/sys/kernel/randomize_va_space.

The challenge

Now, after getting the code, we can start examining it. The first interesting thing we notice is that, on the function upcase (), the user input is printed unsanitized; so we could just write some strange characters, like ‘%’ and inject some formatting and do some bad things with it.

The marked lines are the important ones, where our input string is manipulated and echoed back:

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
void upcase(void) {
	char str[512];
	char *upcase_str;
	int i;

	puts ("Introduce la cadena que va a ser convertida (max 500 caracteres):");
	PROMPT;
	fflush (stdout);
==>	fgets (str, 500, stdin);
	str[strlen (str) - 1] = '\0';

	printf ("Has introducido: ");
==>	printf (str);
	puts ("");

	upcase_str = (char *)calloc (strlen (str) + 1, sizeof (char));

	strncpy (upcase_str, str, strlen (str));

	for (i = 0; i < strlen (upcase_str); i++) {
		upcase_str[i] = toupper (upcase_str[i]);
	}

	printf ("El resultado:	  %s\n", upcase_str);

	free (upcase_str);
}

To test this hypothesis we can insert some format string like ‘%08x’, that will print the argument as a 4 Byte (8 characters), zero-padded, hexadecimal representation of the argument:

Formatting test

As we didn’t gave it any arguments, the first value on the stack is taken.

Now, we can control the stack. To prove this and check the values on the stack, we can try to push one value on the top (like ‘AAAA’, or 0x41414141, an easily recognizable value). For example, lets pop 10 values from the stack with the input AAAA_%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x:

Stack test

What’s happening here is that we push the string ‘AAAA_%08x.%08x.%08x.%08x.%08x.%08x .%08x.%08x.%08x.%08x’ onto the stack; but, with every format string, the function pops one element from the stack, interpreting it as the element to be formatted.

Finally, we can exploit this to read any address we want. To do that, we can simply use the formatter ‘%s’, that pops one element from the stack and interprets it as the address of the string to be displayed.

We can get the flag’s address using the command flag, where it tells us that the flag is at 0x0804c008 (if we disable ASLR, this will always be the same address; but with it enabled it’s not any more difficult than reading that value and change the exploit accordingly), and we know that we must pop 7 elements from the stack until we can inject any value. We can now develop our exploit.

The exploit is constructed by simply replacing the ‘AAAA’ for the address of the flag (on little-endian) and the seventh ‘%08x’ for a ‘%s’. This exploit can’t be written directly, because we can’t write the ASCII value of \x08\xc0\x04\x08 with our keyboard. Instead, we can use an auxiliary file (the commands here displayed are executed on a POSIX shell):

Creating the exploit and getting the flag

In the competition, we had to exploit an instance of this program on a server, with a different flag (at which we didn’t had access, obviously), but the methodology to exploit it remains the same (just replacing the cat exploit - | ./a.out with cat exploit - | nc <server-address> <server-port>).

In the end, we get our flag: flag {9e0480fa680754a7286b9686ce606f22}.


Third challenge: casino

As with the first challenge, I lost the materials for this challenge; so I can’t write the solution :(