[문제]
[풀이]
보호기법 분석
- 64bits 바이너리
- 카나리 존재
- NX bits 존재
- PIE 없음
소스코드 분석 - 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;
}
- password 파일을 fp에 읽어와서 password 변수에 넣음
- fgets 함수로 buf에 사용자의 입력을 받음 → buf는 100byte이나 128byte만큼 입력해 BOF 발생(그치만 카나리 걸려있어서 안먹힐 것 같긴함)
- password와 buf 값이 일치하면 calc_flag 함수를 호출하면서 flag를 출력해줌
- calc_flag 함수에서는 password를 byte 단위로 key의 1byte와 xor 연산하여 반환함
gdb-peda$ info func
All defined functions:
Non-debugging symbols:
0x00000000004005b8 _init
0x00000000004005f0 puts@plt
0x0000000000400600 strlen@plt
0x0000000000400610 __stack_chk_fail@plt
0x0000000000400620 printf@plt
0x0000000000400630 __libc_start_main@plt
0x0000000000400640 fgets@plt
0x0000000000400650 strcmp@plt
0x0000000000400660 fopen@plt
0x0000000000400670 exit@plt
0x0000000000400690 _start
0x00000000004006c0 deregister_tm_clones
0x0000000000400700 register_tm_clones
0x0000000000400740 __do_global_dtors_aux
0x0000000000400760 frame_dummy
**0x0000000000400786 calc_flag
0x00000000004007fa main**
0x00000000004008c0 __libc_csu_init
0x0000000000400930 __libc_csu_fini
0x0000000000400934 _fini
gdb-peda$ info variables
All defined variables:
Non-debugging symbols:
0x0000000000400940 _IO_stdin_used
0x00000000004009c4 __GNU_EH_FRAME_HDR
0x0000000000400b18 __FRAME_END__
0x0000000000600e10 __frame_dummy_init_array_entry
0x0000000000600e10 __init_array_start
0x0000000000600e18 __do_global_dtors_aux_fini_array_entry
0x0000000000600e18 __init_array_end
0x0000000000600e20 __JCR_END__
0x0000000000600e20 __JCR_LIST__
0x0000000000600e28 _DYNAMIC
0x0000000000601000 _GLOBAL_OFFSET_TABLE_
0x0000000000601060 __data_start
0x0000000000601060 data_start
0x0000000000601068 __dso_handle
**0x0000000000601070 key**
0x0000000000601078 __TMC_END__
0x0000000000601078 __bss_start
0x0000000000601078 _edata
0x0000000000601080 stdin
0x0000000000601080 stdin@@GLIBC_2.2.5
0x0000000000601088 completed
**0x00000000006010a0 password
0x0000000000601120 flag**
0x0000000000601188 _end
- 전역 변수로 선언되어 있는 key, password, flag를 확인할 수 있음
- fopen 함수를 호출하는 부분에 bp를 걸어 반환 값을 확인해봄
- open에 성공하면 pointer 값을 반환한다고 하니 fp의 값이 반환된 것이 아닐까 추측할 수 있음
- fgets 함수를 통해 password 변수로 값을 옮기는데, password에 “cat: password: Permission denied\n” 문자열이 들어감
→ 이거 보고 password 파일을 못 읽어온 거라고 생각했는데…………. 뭔가 이상함 - 원래는 파일 내용을 못읽어오면 fopen함수에서 null을 반환해야 함. 앞에서는 fopen이 잘돼서 포인터 값을 rax에 받아왔는데, permission denied가 뜬다..?
- 파일을 다시 확인해봄 → blukat_pwn 권한으로만 읽을 수 있는데.. 정말 이상하다 싶어서 id 명령 사용해봄
- 아놔; blukat_pwn 권한이 있었다. 그럼 password 파일을 정상적으로 읽었다는 건데, password 파일 속 내용이 error 메시지가 아니라 그냥 진짜 password 내용이었다 ……………………
아 진짜 어이없다 ..……………………… michin
flag
🍒 Pl3as_DonT_Miss_youR_GrouP_Perm!!
'Wargame > Pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] asm (0) | 2023.02.26 |
---|---|
[Pwnable.kr] memcpy (0) | 2022.10.15 |
[Pwnable.kr] uaf (0) | 2022.10.15 |
[Pwnable.kr] cmd2 (0) | 2022.10.15 |
[Pwnable.kr] cmd1 (0) | 2022.10.15 |