미역줄기의 이모저모

pwnable.kr mistake 풀이 본문

Hacking/포너블.kr 문제풀이

pwnable.kr mistake 풀이

미역줄기줄기 2024. 2. 1. 19:54
728x90

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_bufpw_buf2PW_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