Ciberseg '17 write-ups: exploiting
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:
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
:
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):
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 :(