문제

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)


분석

mistake.c 의 내용

#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;
}


여기서 주목할 점은 아래의 코드이다.

fd = open("/home/mistake/password", O_RDONLY, 0400) < 0

이때 대입연산자('=')보다 비교연산자('<')가 우선순위가 높기 때문에 먼저 실행된다.

결과적으로, open함수의 결과값은 3이상이기에 fd에는 false를 의미하는 0이 대입된다.

그렇기 때문에 if문 내용도 자연히 실행되지 않고

read(fd, pw_buf, PW_LEN)

이 코드는 stdin으로의 입력을 받아들이게 된다.


결국 pw_buf와 pw_buf2 모두 사용자에 의해 그 내용이 결정되므로

xor 연산을 거쳤을 때 두 문자열이 같아질 수 있도록 값을 입력해주면 끝! ('H' : 0x70, 'I' : 0x71


FL4G

참고로 이 문제를 로컬에 가져와서 실행할 때는 "/home/mistake/password" 파일이 있어야 한다.

또한 코드를 잘 보면 10의 길이만큼 입력을 줄 필요가 있음을 알 수 있다.

'pwnable.kr' 카테고리의 다른 글

[Toddler's Bottle] coin1 writeup  (0) 2018.09.16
[Toddler's Bottle] shellshock writeup  (0) 2018.09.16
[Toddler's Bottle] mistake writeup  (0) 2018.09.16
[Toddler's Bottle] leg writeup  (0) 2018.09.16
[Toddler's Bottle] input writeup  (0) 2018.09.16
[Toddler's Bottle] random writeup  (0) 2018.09.15

+ Recent posts