이번 포스트에서는 Pwnable의 mistake 문제에 대해 다루겠다.
문제 코드는 다음과 같다.
#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;
}
## 문제 해석 :
pw_buf의 값과 pw_buf2의 값이 같으면 flag를 획득할 수 있는 것으로 보인다.
## 문제 풀이 :
코드를 전체적으로 살펴보았을 때 pw_buf2의 값이 XORKEY(1)로 인해 XOR연산하여 그 값이 pw_buf와 같게 하면 된다는 것을 알 수 있다. 그럼 pw_buf의 값을 알아내보겠다.
코드의 초반부분을 살펴보면 if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)라는 줄이 보인다. open("/home/mistake/password",O_RDONLY,0400) 라는 함수는 true를 반환하므로 0이 아닌 양수값이 반환될 것입니다. 또한 여기서 중요한 것이 바로 연산자 "<"는 연산자 "="보다 빨리 실행된다는 사실이다. 즉, if(fd=(양수<0))이 되고 이는 곧 if(fd=0)이다.(양수가 0보다 클 수 없으니 0을 반환)
파일 디스크립터 중 0은 stdin, 즉 표준 입력이다.
이어서 코드를 살펴보면 다음 부분이 보인다.
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;
}
pw_buf와 len이 선언되고, len은 read() 함수를 통해 실행되었으며 이때의 파일 디스크립터가 fd(0, stdin)이기 때문에 입력을 받을 수 있고 그 값이 len에 저장된다. 즉, 우리의 입력에 의해 pw_buf의 값이 결정된다.
여기서 정리하자면, pw_buf와 pw_buf2의 값을 다 우리가 결정할 수 있고, pw_buf2의 XOR한 값이 pw_buf이며 해당 문제를 해결할 수 있다.
그럼 pw_buf를 임의의 값인 "AAAAAAAAAA"로 정의한 다음에 테스트 해보겠다. (pw_buf2의 버퍼 길이가 10이기때문에)
## XOR 코드 :
#include <stdio.h>
#define XORKEY 1
void xor(char* s, int len)
{
int i;
for(i=0;i<len;i++) {
s[i] ^= XORKEY;
}
}
int main()
{
char pw_buf2[11] = "AAAAAAAAAA";
xor(pw_buf2, 10);
printf("%s\n", pw_buf2);
}
## 실행 결과 :
"A" 는 0x41이므로 0x41을 1로 XOR 하면 "@"이 나온 것을 확인할 수 있다.
## 최종 결과 :
### 공격문 : "AAAAAAAAAA", "@@@@@@@@@@"
### 실행 결과 :
Flag = Mommy, the operator priority always confuses me :(
'Wargame > Pwnable' 카테고리의 다른 글
Pwnable (11. coin1) (0) | 2022.07.09 |
---|---|
Pwnable (10. shellshock) (0) | 2022.07.08 |
Pwnable (8. leg) (0) | 2022.07.06 |
Pwnable (7. input) (0) | 2022.07.05 |
Pwnable (6. random) (0) | 2022.07.04 |