728x90
반응형
1. intro
2. code 및 분석
2.1. code
#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;
}
2.2. 분석
그냥 보기에는 password 파일을 읽고, 입력 받은 값과 비교해서 같으면 flag를 출력해주는 것처럼 보인다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
힌트를 준 것과 같이 operator priority에 의해 의도치 않은 동작을 하게 된다.
3.2. 공격 준비
gdb로 까봤을때 예상대로 password 파일을 열지 못하기에 곧장 종료되는 것을 볼 수 있다.
하지만, 천천히 다시 보면
아래 코드에서,
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
printf("can't open password %d\n", fd);
return 0;
}
파일을 정상적으로 열린 뒤, fd 변수에 값을 넣는 것이 먼저가 아니라 비교문인 "<" 가 우선순위가 높기에 먼저 비교하게 된다.
파일이 열린 뒤의 리턴 값은 1일 것이다.
1 < 0 에서 false이기에 0이 다시 set 될 것이며, 결국 fd에는 0이 들어갈 것이다.
더불어 if 문은 if(0) 이기에 실행되지 않을 것이다.
두번째 if 문을 보자.
마찬가지로 read로 값을 받아들이는데, 여기서 fd가 0이기 때문에 stdin으로 값을 받아들일 것이다.
if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
printf("read error\n");
close(fd);
return 0;
}
read의 return 값은 입력 받은 길이 이기에 len은 양수가 된다.
그러므로 if(!10) 과 같은 식이 되기에 if문은 또한 작동하지 않는다.
결국은 pw_buf와 pw_buf2가 모두 입력값이 되며, XOR만 고려하면 된다.
비교하는 길이가 10이기 때문에 이것만 맞춰주자.
4. exploit
mistake@pwnable:~$ ./mistake
do not bruteforce...
1111111111
0000000000
input password : Password OK
----------#플래그는 삭제
참고로 input password가 뜨기 전에 두번째 입력을 하던, 뜨고나서 하던 아무 상관 없다.
buffer에 쌓여있다 한번에 입력되기 때문.
728x90
반응형
'Wargame > pwnable.kr' 카테고리의 다른 글
coin1 (0) | 2022.12.30 |
---|---|
shellshock (0) | 2022.12.29 |
input (0) | 2022.12.28 |
random (0) | 2022.12.28 |
passcode (0) | 2022.12.27 |