White Security
Mistake 문제풀이 본문
We all make mistakes, let's move on. (don't take this too seriously, no fancy hacking skill is required at all) This task is based on real event Thanks to dhmonkey hint : operator priority ssh mistake@pwnable.kr -p2222 (pw:guest)
Toddler's Bottle 9번 문제.
코딩 오류를 찾아내는 문제로
연산자 우선순위와 관련이 있습니다.
mistake@ubuntu:~$ ls -l total 24 -r-------- 1 mistake_pwn root 51 Jul 29 2014 flag -r-sr-x--- 1 mistake_pwn mistake 8934 Aug 1 2014 mistake -rw-r--r-- 1 root root 792 Aug 1 2014 mistake.c -r-------- 1 mistake_pwn root 10 Jul 29 2014 password
소스, 바이너리, 플래그 파일 이외에
패스워드 파일이 존재합니다.
#include <stdio.h> #include <fcntl.h> #define PW_LEN 10 #define XORKEY 1 void xor(char* s, int len){ int i; for(i=0; i<len; i++){ s[i] ^= XORKEY; } } int main(int argc, char* argv[]){ int fd; if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ printf("can't open password %d\n", fd); return 0; } printf("do not bruteforce...\n"); sleep(time(0)%20); char pw_buf[PW_LEN+1]; int len; if(!(len=read(fd,pw_buf,PW_LEN) > 0)){ printf("read error\n"); close(fd); return 0; } char pw_buf2[PW_LEN+1]; printf("input password : "); scanf("%10s", pw_buf2); // xor your input xor(pw_buf2, 10); if(!strncmp(pw_buf, pw_buf2, PW_LEN)){ printf("Password OK\n"); system("/bin/cat flag\n"); } else{ printf("Wrong Password\n"); } close(fd); return 0; }
언뜻 봐서는 별 문제 없어 보입니다,
패스워드 파일을 읽고, xor 1 을 한 후에
사용자 입력과 비교해서 같으면 통과시킬 것 같죠.
int fd; if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ printf("can't open password %d\n", fd); return 0; }
하지만 잘 보면 무언가 이상한 점이 있습니다.
파일 디스크립터를 얻고, 유효한지 비교하는 부분에 말이죠.
open 함수로 파일 디스크립터를 얻고
fd 에 대입한 다음, fd 를 0 과 비교해
음수일 경우 파일을 여는데에
실패했다고 판단해서 종료해야 합니다.
그런데 C언어에서는 관계연산자가
대입연산자보다 우선순위가 높기 때문에
파일 디스크립터 < 0 의 불리언 값이 fd에 대입됩니다.
때문에 fd는 항상 0이라 종료될 리가 없지요.
결론적으로 fd는 0(STDIN)이 됩니다.
printf("do not bruteforce...\n"); sleep(time(0)%20); char pw_buf[PW_LEN+1]; int len; if(!(len=read(fd,pw_buf,PW_LEN) > 0)){ printf("read error\n"); close(fd); return 0; }
read 함수가 참조하는
디스크립터는 STDIN 입니다.
따라서 우리가 입력을 하지 않으면
sleep 함수가 종료되어도
패스워드를 입력하라는 문장은 나타나지 않습니다.
어쩌면 이 부분에 혼동을 주기 위해서
sleep 함수를 넣은 것일지도 모르겠네요.
#define XORKEY 1 void xor(char* s, int len){ int i; for(i=0; i<len; i++){ s[i] ^= XORKEY; } }
사용자의 입력에 xor 1 을 수행하고 있습니다.
mistake@ubuntu:~$ ./mistake do not bruteforce... 0000000000 input password : 1111111111 Password OK Mommy, the operator priority always confuses me :(
패스워드 파일 대신에 사용될
10 글자 입력을 해주신 후에
xor 1 한 문장을 재입력하면
플래그 휙득이 가능하겠습니다.
'Wargame Writeups > pwnable.kr' 카테고리의 다른 글
Coin1 문제풀이 (0) | 2019.02.09 |
---|---|
Shellshock 문제풀이 (0) | 2019.02.08 |
Leg 문제풀이 (0) | 2019.02.08 |
Input 문제풀이 (0) | 2019.02.07 |
Random 문제풀이 (0) | 2019.02.06 |
Comments