Wargame/pwnable.kr
[Pwnable.kr] mistake 풀이 (1pt)
bjloed
2020. 7. 20. 23:14
풀이
문제 안읽고 그냥 냅다 풀다가 당했다
다음은 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;
}
먼저 문제를 읽어보자.. 제발..
We all make mistakes, let's move on.
(don't take this too seriously, no fancy hacking skill is required at all)
hint : operator priority
힌트가 연산자 우선순위다. 멍하니 코드를 10분 동안 바라보다가 이상한 부분을 찾았다. 검거!
int fd;
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
printf("can't open password %d\n", fd);
return 0;
}
먼저 연산자 우선순위 사진을 퍼와봤다.
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)
해당 코드에서는 fd 값에 open 함수의 리턴 값을 대입하는 게 먼저가 아니라 0과 비교하는 게 먼저 실행된다.
해당 파일에는 아무런 이상이 없으니 음수가 아닌 파일 디스크립터 값(음이 아닌 정수)을 반환한다.
그러므로 if(fd=[음이 아닌 정수] < 0)이고, 음이 아닌 정수와 0중 큰 값은 당연히 왼쪽 값이므로 false가 남게 된다.
즉, fd에는 false 값(0)이 대입된다.
그러면 fd에는 0이라는 값이 들어있음을 알았다.
if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
printf("read error\n");
close(fd);
return 0;
}
그렇다면 read(0, pw_buf, PW_LEN)이 되고, 0은 stdin이니 우리가 원하는 값을 pw_buf에 10칸만큼 넣을 수 있다.
if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
printf("Password OK\n");
system("/bin/cat flag\n");
}
결국, read로 읽은 값인 pw_buf와 우리가 입력할 값인 pw_buf2를 비교하는 것이기 때문에, xor(pw_buf2)와 pw_buf1이 같다면 문제가 해결될 것이다.