미역줄기의 이모저모
pwnable.kr mistake 풀이 본문
1. 문제확인

힌트는 operator priority 연산자 우선순위!
ssh mistake@pwnable.kr -p2222 들어가자~!

ls를 해보니 flag, mistake, mistake.c, password가 있군여 그럼 이제 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;
}
2. 분석
으아.. 일단 여기서
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;
}
이 부분, 특히 if 조건문을 보면 파일 디스크립터(fd)를 반환하고 해당 값이 0보다 작은지 여부를 확인하는데
여기에 있는 문제는 '<' 비교 연산자가 대입 연산자 '=' 보다 낮은 우선순위를 가지므로, 대입이 먼저 수행되고 나서 비교가 이루어진다는 것이다. 이로 인해 fd는 비교 결과인 0 또는 1이 된다!
위 코드가 실행될 때 open함수에서 파일이 정상적으로 열려서 양수를 반환하게 된다.
그리고 0과 비교했을 때 Fasle 이므로 fd에는 0이 들어가게 된다
if(!(len=read(fd,pw_buf,PW_LEN) > 0))
이 부분도 마찬가지!
fd는 0이 들어가므로 stdin이 된다! 즉 우리가 입력할 수 있고 그 값은 pw_buf에 들어간다! 아 그래서 두 번 입력할 수 있었구나!

그리고
scanf("%10s", pw_buf2);
// xor your input
xor(pw_buf2, 10);
pw_buf2의 값을 입력받기 때문에 pw_buf, pw_buf2 모두 우리 모두 설정할 수 있다.
pw_buf2를 입력 받고 xor함수를 거친다.
void xor(char* s, int len){
int i;
for(i=0; i<len; i++){
s[i] ^= XORKEY;
}
}
xor() 함수에서는 string으로 받은 인자와 len을 이용해 len만큼 for문을 돌며 각 string 문자를 XORKEY(1)와 xor해준다
그러니까, 입력값이 1111111111이면 0000000000가 된다는 것이다!!
if(!strncmp(pw_buf, pw_buf2, PW_LEN))
strncmp 함수는 두 문자열을 비교하는 함수이다.
pw_buf와 pw_buf2를 PW_LEN만큼 비교하고, 그 결과가 서로 같으면 참(true), 다르면 거짓(false)을 반환한다!
그러니까! pw_buf와 pw_buf2가 같아야 하는데, pw_buf2를 입력하고 나서 xor함수가 pw_buf2를 XOR1 연산하니까, pw_buf2에는 pw_buf에 XOR1을 한 결과를 쓰면 되네!
헷갈려서 예를들면!
1111111111(pw_buf)를 입력하고 0000000000(pw_buf2)를 입력하면 pw_buf2를 XOR1한 값 (1111111111을 XOR1하면 0000000000이 된다) 과 pw_buf가 같아지니까 플래그를 뿌려주게 된다는 것이다!
3. 해결

flag: Mommy, the operator priority always confuses me :(
논리적으로 생각하는 힘을 길러야겠다.. 에휴
'Hacking > 포너블.kr 문제풀이' 카테고리의 다른 글
pwnable.kr cmd1 풀이 (1) | 2024.02.02 |
---|---|
pwnable.kr lotto 풀이 (0) | 2024.02.01 |
pwnable.kr blackjack 풀이 (0) | 2024.02.01 |
pwnable.kr shellshock 풀이 (0) | 2024.02.01 |
pwnable.kr leg 풀이 (1) | 2024.02.01 |