Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
Archives
Today
Total
관리 메뉴

White Security

Mistake 문제풀이 본문

Wargame Writeups/pwnable.kr

Mistake 문제풀이

POSIX 2019. 2. 8. 08:04
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