비교해야 할 것은 헥스 에디터로 열었을 때 안에 있는 데이터 값인 것 같다. 사람의 눈으로는 미세한 데이터 차이는 판별하지 못하기 때문에 이렇게 숨기기도 하나보다.
그럼 헥스 에디터를 열어 데이터를 비교해 보자.
내가 사용하고 있는 헥스 에디터인 010 editor의 경우 compare file 기능을 이용하면 다음과 같이 틀린 부분과 같은 부분을 색깔별로 표시해주며 밑에 Compare 메뉴에 Difference 를 누르면 다른 부분으로 바로 이동시켜주는 편리한 기능이 있어서 사용하였다.
afterimage_1.jpeg 와 afterimage_2.jpeg 의 각각 다른 헥스 값은 1이 4E, 2가 48이다. 각각 ascii 코드로 N과 H인데 HackCTF 플래그 포멧 상 HackCTF{any_string_is_Flag}이기 때문에 아마 afterimage_2.jpeg 의 다른 헥스 값이 플래그 일 것이다.
Artifact.7z 이라는 7zip 파일을 압축 해제하면 다음과 같이 mission.jpg라는 사진 파일을 주는데 열리지 않는다.
헥스 에디터로 열어서 문제점을 찾아보자.
헥스 에디터로 열어 봤을때 헤더 시그니처가 확장자인 jpg 파일은 아닌것이 분명했고 저것이 어떤 헤더 시그니처 인지 찾는 과정에서 매우 유사한 헤더 시그니처를 가진 것이 많았기 때문에 고민 했지만 대충 그냥 소리가 나오는 파일이면 인식할 수 있었다. (헤더 시그니처는 3gp5 또는 m4a 파일이라고 생각한다.)
따라서 필자는 wav로 확장자를 바꾸어 사용하도록할 것이다.
확장자를 wav로 바꾸어 주도록 하자.
그럼 다음과 같이 음성이 나오는데 뭐라 말하는지 알 수 가 없다...
이 때 사용하는 사운드 편집 프로그램인 audacity를 사용하여 편집을 이리 저리 굴려보자.
그런데 문제가 발생했다.
오다시티에서 무슨 문제인지 파일을 인식하지 못하고 가져오는데 실패하였다.
아마 원본 파일이 m4a나 그런 쪽의 파일이라서 그런것이 아닐까 추측했고 온라인 컨버터를 이용해 mp3 파일로 컨버트 시켜주었다.
그 결과 오다시티에서 성공적으로 열 수 있었다.
이제 문제만 풀면 되는데 보통 다른 오디오 포렌식 문제들과 달리 간단한 편이었다.
다른 문제들은 속도 조절하고 템포 조절하고 잔향 제거하고 여러가지 건들이는 반면 이 문제는 뒤집기 좌우로 해서 거꾸로 재생만 시켜주면 플래그가 나온다.
다음과 같이 Flag.zip을 압축 해제하려고 하자 비밀번호를 입력하라고 한다. 따라서 BruteForce어택을 백그라운드에 실행해놓고 다른 방법이 더 있나 찾아보기로 하였다.
그러던 중 파일 건너뛰기를 하고 압축을 해제했더니 암호가 걸린 flag.txt를 제외한 hint1.txt와 hint2.txt는 압축이 정상적으로 해제되었다. 이 힌트를 읽어보자.
우선 첫번째 힌트이다. Brute-Force NOOOOOOOOOOOOOO!라며 무작위 대입 공격을 사용하는 것이 아님을 알려준다. 나처럼 백그라운드에 돌려두었다면 곱게 켜서 다시 종료시켜주자.
그리고 두번째 힌트는 과연 패스워드가 존재한다고 생각하냐? 라며 패스워드로 푸는 것이 아니라는 힌트를 준다.
그럼 이제 압축파일의 파일 구조를 찾아보자.
압축파일의 암호화 기법은 Central Directory 구조의 Flags 필드를 공부해야한다. ( 그냥 압축파일에 대해 싹 다 공부하자 이김에 ) Central Directory 구조의 Flags 필드는 총 16개의 플래그 값을 가지고 있으며 Bit 00 번째 값이 암호화 된 파일을 나타낸다고 한다.
010editor는 파일 포맷을 기본적으로 지원해주기 때문에 볼때 한결 편하다.
대충 보라색 부분부터 Central Directory 영역이라고 보면 되며, 드래그 한 09 08 부분이 Flags 필드이다.
이 09 08 은 비트로 표현하기 위해 리틀언디언 방식으로 표현하면 08 09 이다. 또한 08 09 를 비트로 나타내면
1000 0000 1001 이며 암호화 부분인 00 번째 bit가 1로 활성화 되어 있는것을 알 수 있다.
따라서 2^0 = 1이니 1을 빼준 값을 보면 암호화 비트가 풀어진 바이트를 얻을 수 있다. 이는 헥스값으로 0808이다.
비트로는 1000 0000 1000 이다.
따라서 헥스값을 0808로 바꾸어 주거나 밑에 010editor에서 지원하는 기능 중 하나인 Inspector 에서 Short 부분을 2056으로 바꾸어주면 된다.
IDA를 통해 까본 prob1 소스이다. read 함수를 이용하여 name 변수에 50byte만큼 이름을 입력을 받고 변수 s를 통해 입력값을 입력받는다. gets함수를 이용하고 최대 byte수를 정해주지 않았기 때문에 BOF가 일어난다.
풀이
처음에 생각했던건 gets함수에 입력제한이 없으니 dummy[24]를 주고 ret를 shellcode 주소로 준다음 그 뒤에 추가해서 shellcode를 넣는 방법을 생각했다. 하지만 local에서의 주소와 네트워크 상에서에 주소가 다른지 쉘이 따지지 않드라.... 그리고 또 이용할 수 있는 것이 name 이었는데 name은 선언이 안되있어서 뭐지? 싶었는데 더블 클릭을 하니 .bss 영역에 할당되어 있는 것으로 보아 전역변수로 선언되어있는것 같았다. 따라서 여기다 쉘코드를 삽입하고 ret을 이 .bss 주소로 변조해주면 될 것 같다.
.bss:0804A060 name db ? ; ; DATA XREF: main+29↑o
.bss:0804A061 db ? ;
.bss:0804A062 db ? ;
.bss:0804A063 db ? ;
.bss:0804A064 db ? ;
.bss:0804A065 db ? ;
~~~
.bss:0804A093 _bss ends
일단 gdb로 분석을 해보자
음 ida로 보는 것과 별반 차이는 없는 것 같다. 정보를 종합하고 payload를 짜주러 가보자.
root@C0WB3LL:~/Desktop/pwn# gdb bof_basic
GNU gdb (Debian 8.3.1-1) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 180 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from bof_basic...
(No debugging symbols found in bof_basic)
pwndbg>
넣자마자 gdb를 돌린다.
pwndbg> i fu
All defined functions:
Non-debugging symbols:
0x08048330 _init
0x08048370 printf@plt
0x08048380 fgets@plt
0x08048390 puts@plt
0x080483a0 system@plt
0x080483b0 __libc_start_main@plt
0x080483c0 __gmon_start__@plt
0x080483d0 _start
0x08048400 __x86.get_pc_thunk.bx
0x08048410 deregister_tm_clones
0x08048440 register_tm_clones
0x08048480 __do_global_dtors_aux
0x080484a0 frame_dummy
0x080484cb main
0x08048590 __libc_csu_init
0x080485f0 __libc_csu_fini
0x080485f4 _fini
pwndbg>
i fu 명령어로 함수에 대한 정보를 확인한다.
특별한게 없으니 바로 main 함수를 파헤쳐 보자.