시작
안녕하세요 :D
passcode
에 이어 오늘은 mistake
를 들고 왔습니다.
10점짜리 풀다가 1점짜리 푸니깐 편-안하네요..ㅎㅎ..
시작해보겠습니다!
root@goorm:/workspace/LCH_Server# ssh mistake@pwnable.kr -p2222
Write UP
mistake@ubuntu:~$ ls -l
total 24
-r-------- 1 mistake_pwn root 51 Jul 29 2014 flag
-r-sr-x--- 1 mistake_pwn mistake 8934 Aug 1 2014 mistake
-rw-r--r-- 1 root root 792 Aug 1 2014 mistake.c
-r-------- 1 mistake_pwn root 10 Jul 29 2014 password
4개의 파일이 보입니다.
mistake
부터 실행해볼까요?
mistake@ubuntu:~$ ./mistake
do not bruteforce...
1234
input password : 1234
Wrong Password
입력을 하나 받고, 조금 기다리면 input password :
라며 또 하나의 입력을 받습니다.
패스워드가 틀릴 경우 Wrong 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;
}
정상적으로 프로그램이 작동하려면 다음과 같이 진행되어야 합니다.
-
fd
변수에open
함수의return
값이 들어간다. 그 후fd
와0
의<
연산이 진행된다. -
read
함수에 의해pw_buf[]
배열에/home/mistake/password
의 내용이 저장된다.
하지만 MSDN
의 연산자 우선순위를 보면 <
, >
가 =
보다 높다고 하는군요.
때문에 이 프로그램은 다음과 같이 진행됩니다.
-
open
함수의return
값과0
의<
연산이 먼저 이루어진다. 그 후의 값을fd
변수에 대입한다. -
open
함수는 정상적인 파일을 열었으므로 양수가 반환된다. -
양수 < 0의 결과는
0
이므로fd
변수에0
, 즉 표준 입력 파일 디스크럽터가 들어간다.
결국 우리는 read
함수에서 fd
를 0
으로 넘겨주기 때문에 pw_buf[]
배열에
임의의 값을 PW_LEN
만큼 넣어줄 수 있게 됩니다!!
그 다음으로 pw_buf2[]
배열에 10 bytes
만큼 입력을 받고
xor
함수에 의해 pw_buf2[]
배열은 1
과 XOR
연산됩니다.
이렇게 해서 나온 값이 pw_buf
와 같다면 flag
를 출력해주네요.
저는 pw_buf[]
에 AAAAAAAAAA
를 넣겠습니다.
AAAAAAAAAA
를 1
과 XOR
한 값은 다음과 같네요.
mistake@ubuntu:/tmp$ cat xor.c
#include <stdio.h>
int main() {
int i;
char buf[11] = "AAAAAAAAAA";
for (i = 0; i < 10; i++) {
buf[i] ^= 1;
}
printf("%s\n", buf);
return 0;
}
mistake@ubuntu:/tmp$ ./xor
@@@@@@@@@@
그대로 넣어주겠습니다.
mistake@ubuntu:~$ ./mistake
do not bruteforce...
AAAAAAAAAA
input password : @@@@@@@@@@
Password OK
Mommy, the operator priority always confuses me :(
마무리
파일 디스크립터를 많이 다루다 보니깐 조금씩 익숙해 지는군요..
MSDN
의 연산자 우선순위도 배울 수 있었던 좋은 문제인 것 같습니다!!
다음 Write Up에서 뵙겠습니다! :D
'CTF_Write_UP > pwnable.kr' 카테고리의 다른 글
pwnable.kr : lotto 풀이 (0) | 2019.04.17 |
---|---|
pwnable.kr : shellshock 풀이 (0) | 2019.04.16 |
pwnable.kr : passcode 풀이 (0) | 2019.04.14 |
pwnable.kr : random 풀이 (0) | 2019.04.13 |
pwnable.kr : bof 풀이 (0) | 2019.04.13 |