[문제]


[풀이]

보호기법 분석

  • 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

+ Recent posts