[Toddler's Bottle] mistake writeup
문제
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)
분석
#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의 길이만큼 입력을 줄 필요가 있음을 알 수 있다.