https://gist.github.com/bincat99/dc40fc894bed1831cd654abfcdc65f55
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <signal.h> void init () { setvbuf (stdin, 0, 2, 0); setvbuf (stdout, 0, 2, 0); setvbuf (stderr, 0, 2, 0); } int read_input (char *buf, int len) { int ret; ret = read (0, buf, len); if (ret < 0) { fprintf (stderr, "read error!\n"); exit (1); } if (buf[ret-1] == '\n') buf[ret-1] = '\0'; return ret; } int filter (char * buf) { if (strstr (buf, "flag")) return 1; return 0; } char flag[40] = {0}; char path[100] = {0}; int main () { int fd; init (); fd = open ("./flag", O_RDONLY); read (fd, flag, 40); //close (fd); puts ("give me your path :D"); printf (">> "); read_input (path, 0x40); if (filter (path)) { puts ("Nop :/"); exit (0); } fd = open (path, O_RDONLY); read (fd, path, 40); close (fd); puts (path); } | cs |
어떻게 풀까 고민하던 중 같은 대회의 basic_bf 문제가 도움이 되었다. 해당 문제에서 /dev/urandom 파일을 open 하는 것을 보고 똑같이 /dev에 open할 만한게 있지 않을까 해서 찾아보던 중 fd 폴더를 찾게 되었다.
참고로 각 프로세스는 /proc/[pid] 폴더를 갖게 되는데 /proc/self/를 하면 자신 프로세스의 폴더를 찾을 수 있다.
/dev/fd/ 폴더는 /proc/self/fd의 심볼릭 링크이다.
(참고로. stdin도 /proc/self/stdin과 같이 참조할 수 있다.)
fd는 순차적으로 할당되고 0, 1, 2는 각각 stdin, stdout, stderr로 이미 할당되어있기 때문에 3이 flag 파일의 fd(file descriptor)일 것을 예상할 수 있다.
로컬에서는 /dev/fd/3을 이용해서 풀 수 있었는데, 원격으로 풀 때는 /dev/fd/3으로 풀리지 않았다. 이유를 찾아보니 nc로 원격 접속을 할 경우 3과 4에 해당하는 fd가 이미 존재해서였다. 따라서, /dev/fd/5를 입력하면 flag를 얻을 수 있다.
'Hack > 기타' 카테고리의 다른 글
[backdoorctf17] extend_me (0) | 2017.10.13 |
---|---|
[backdoorctf17] the-wall (0) | 2017.10.13 |