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;
}
소스코드를 해석하자면
처음에 입력한 10byte 값과 두번째로 입력된 10byte를 XOR 연산한다.
연산한 결과값이 처음에 입력한 값과 같다면 /bin/cat/flag 를 출력한다.
소스코드를 분석할 줄 알면 아주 간단한 문제이다.
동시에 C언어에 대해 얼마나 깊게 이해하고 있는지를 묻는 아주 재미있는 문제이다.
XOR 연산의 특징은
--------------------
A xor B
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 0
--------------------
두개의 값이 반전일 경우 1을 출력하고 두개의 값이 같을경우에는 0을 출력한다.
첫번째 10바이트와 두번째 10바이트 수를 XOR 해서 처음 수가 나와야 한다면
1111111111
0000000000
을 연산하게 되면 1111111111 처음 값이 나오게 된다.
개인적으로 이런 문제를 아주 좋아한다.
'pwnable > pwnable.kr' 카테고리의 다른 글
pwnable.kr -bof (0) | 2016.07.29 |
---|---|
pwnable.kr -flag (0) | 2016.07.15 |
pwnable.kr -shellshock (0) | 2016.07.15 |
toddler -collision (0) | 2016.07.15 |
toddler -fd (0) | 2016.07.13 |