풀이
다음은 blukat.c의 코드이다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
char flag[100];
char password[100];
char* key = "3\rG[S/%\x1c\x1d#0?\rIS\x0f\x1c\x1d\x18;,4\x1b\x00\x1bp;5\x0b\x1b\x08\x45+";
void calc_flag(char* s){
int i;
for(i=0; i<strlen(s); i++){
flag[i] = s[i] ^ key[i];
}
printf("%s\n", flag);
}
int main(){
FILE* fp = fopen("/home/blukat/password", "r");
fgets(password, 100, fp);
char buf[100];
printf("guess the password!\n");
fgets(buf, 128, stdin);
if(!strcmp(password, buf)){
printf("congrats! here is your flag: ");
calc_flag(password);
}
else{
printf("wrong guess!\n");
exit(0);
}
return 0;
}
/home/blukat/password 에서 읽어온 fp 값을 password에 집어넣는다.
그 후, buf 배열에 사용자의 입력을 받고 password와 buf가 동일하면, flag를 출력하는 문제이다.
gdb로 풀기 전 힌트를 주자면, /home/blukat/password의 권한을 잘 봐보자.
이제 gdb로 열어보겠다.
Dump of assembler code for function main:
0x00000000004007fa <+0>: push rbp
0x00000000004007fb <+1>: mov rbp,rsp
0x00000000004007fe <+4>: add rsp,0xffffffffffffff80
0x0000000000400802 <+8>: mov rax,QWORD PTR fs:0x28
0x000000000040080b <+17>: mov QWORD PTR [rbp-0x8],rax
0x000000000040080f <+21>: xor eax,eax
0x0000000000400811 <+23>: mov esi,0x40096a
0x0000000000400816 <+28>: mov edi,0x40096c
0x000000000040081b <+33>: call 0x400660 <fopen@plt>
0x0000000000400820 <+38>: mov QWORD PTR [rbp-0x78],rax
0x0000000000400824 <+42>: mov rax,QWORD PTR [rbp-0x78]
0x0000000000400828 <+46>: mov rdx,rax
0x000000000040082b <+49>: mov esi,0x64
0x0000000000400830 <+54>: mov edi,0x6010a0
0x0000000000400835 <+59>: call 0x400640 <fgets@plt>
0x000000000040083a <+64>: mov edi,0x400982
0x000000000040083f <+69>: call 0x4005f0 <puts@plt>
0x0000000000400844 <+74>: mov rdx,QWORD PTR [rip+0x200835] # 0x601080 <stdin@@GLIBC_2.2.5>
0x000000000040084b <+81>: lea rax,[rbp-0x70]
0x000000000040084f <+85>: mov esi,0x80
0x0000000000400854 <+90>: mov rdi,rax
0x0000000000400857 <+93>: call 0x400640 <fgets@plt>
0x000000000040085c <+98>: lea rax,[rbp-0x70]
0x0000000000400860 <+102>: mov rsi,rax
0x0000000000400863 <+105>: mov edi,0x6010a0
0x0000000000400868 <+110>: call 0x400650 <strcmp@plt>
0x000000000040086d <+115>: test eax,eax
0x000000000040086f <+117>: jne 0x4008a0 <main+166>
0x0000000000400871 <+119>: mov edi,0x400996
0x0000000000400876 <+124>: mov eax,0x0
0x000000000040087b <+129>: call 0x400620 <printf@plt>
0x0000000000400880 <+134>: mov edi,0x6010a0
0x0000000000400885 <+139>: call 0x400786 <calc_flag>
0x000000000040088a <+144>: mov eax,0x0
0x000000000040088f <+149>: mov rcx,QWORD PTR [rbp-0x8]
0x0000000000400893 <+153>: xor rcx,QWORD PTR fs:0x28
0x000000000040089c <+162>: je 0x4008b9 <main+191>
0x000000000040089e <+164>: jmp 0x4008b4 <main+186>
0x00000000004008a0 <+166>: mov edi,0x4009b4
0x00000000004008a5 <+171>: call 0x4005f0 <puts@plt>
0x00000000004008aa <+176>: mov edi,0x0
0x00000000004008af <+181>: call 0x400670 <exit@plt>
0x00000000004008b4 <+186>: call 0x400610 <__stack_chk_fail@plt>
0x00000000004008b9 <+191>: leave
0x00000000004008ba <+192>: ret
End of assembler dump.
제일 간단하게 알 수 있는 방법은 strcmp@plt에서 무슨 값을 검사하는지 확인하면 되지 않을까?
*main +110 부분에 bp를 걸고 edi의 값을 봐보도록 하자.
(gdb) x/s $edi
0x6010a0 <password>: "cat: password: Permission denied\n"
password 배열에 왜 저런 값이 들어갔을까?
password 파일의 권한이 640 이기 때문에 password을 읽을 권한이 없기 때문이다.
-rw-r----- 1 root blukat_pwn 33 Jan 6 2017 password
fgets 함수는 개행 문자를 입력받으므로, 개행 문자를 제외한 값을 입력해주면 문제가 해결될 듯하다.
'Wargame > pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] asm 풀이 (6pt) (0) | 2020.07.27 |
---|---|
[Pwnable.kr] uaf 풀이 (8pt) (0) | 2020.07.27 |
[Pwnable.kr] cmd2 풀이 (9pt) (0) | 2020.07.22 |
[Pwnable.kr] coin1 풀이 (6pt) (0) | 2020.07.22 |
[Pwnable.kr] cmd1 풀이 (1pt) (0) | 2020.07.22 |