#About


유준혁은 PC가 고장나서 형 유성준에게 PC를 고쳐 달라고 했다.

그런데, 유성준은 동생의 PC를 고치면서 몇 가지 장난을 했다.

당신은 이 PC를 정상적으로 돌려 놓아야 한다.


1. 웹 서핑은 잘 되는데, 네이버에만 들어가면 사이버 경찰청 차단 화면으로 넘어간다. 원인을 찾으면 Key가 보인다.

2. 유성준이 설치 해 놓은 키로거의 절대경로 및 파일명은?(모두 소문자) -ex) c:\windows\notepad.exe

3. 키로거가 다운로드 된 시간은? -ex) 2016-05-27_22:00:00 (yyyy-mm-dd_hh:mm:ss)

4. 키로거를 통해서 알아내고자 했던 내용은 무엇인가? 내용을 찾으면 Key가 보인다.


인증키 형식 : lowcase(MD5(1번키+2번답+3번답+4번키))




#Solution


[그림 1] - 문제 파일 확인


시나리오에서 주어진 파일을 받으면 가상 머신에서 사용되는 디스크 파일을 확인할 수 있고, 가상 머신을 통해 열게 되면 


아래와 같이 지문이 주어진 메모장이 하나 띄워지며 해당 지문은 시작프로그램에 등록되어 가상머신으로 실행하게 되면 자동으로 띄워 진다


[그림 2] - 시작 프로그램에 등록 된 메모장 내용 확인


시나리오에서 주어진 문제를 해결하기 위해 각 문제별로 필요한 것을 정리해보았고 다음과 같다.


1. %systemroot%\System32\drivers\etc 경로에 위치하는 hosts 파일의 변조 유무 검토 필요


2. 프로세스 확인을 통한 키로거 확인 및 $MFT, $Logfile, $UsnJnrl의 종합적 분석을 통한 절대 경로 확인 


3. 외부저장장치를 통한 설치라면 $MFT, $Logfile, $UsnJrnl 분석, 웹을 통한 다운로드라면 웹 히스토리 정보 및 다운로드 목록 확인을 위한 아티팩트 분석


4. 현재로선 알 수 없고 문제를 해결하는 과정에서 알 수 있을 것 같다




먼저 네이버에만 들어가면 사이버 경찰청 차단 화면으로 넘어가므로 DNS 스푸핑 또는 Hosts 파일의 변조라고 생각할 수 있다


하지만 시나리오상에서 단순한 장난으로 보이므로 Hosts 파일 변조일 것이라는 생각이 들고 또한 DNS Query를 거치기 전에 로컬의 


Hosts 파일을 먼저 거치기 때문에 1번 문제와 같이 다른 페이지로 리다이렉트 되는 경우, 가장 먼저 hosts 파일의 변조 유무를 확인해야 한다


[그림 3] - hosts.txt 파일 확인


해당 경로에서 hosts 파일 확인결과 .txt 확장자가 붙은 파일을 확인할 수 있었고 위에서 확인할 수 있듯 별 다른 특징을 


확인할 수 없었을 뿐더러 .txt 파일인 것이 의심스러워 조금 더 알아본 결과 숨김 파일로 hosts 파일이 있음을 확인헀다


[그림 4] - 숨김 파일 표시를 통한 hosts 파일 확인



[그림 5] - Key 값 확인


hosts 파일 열람 결과, what_the_he11_1s_keey라는 키 값을 얻을 수 있었다.


2번 문제에서 요구하는 것은 키로거의 절대경로 및 파일명이며 이는 프로세스에 상주하고 있을 것이라 생각, Ctrl+Alt+Del을 


이용하여 확인하려 했지만 일반 사용자의 권한으로 확인할 수 없었고, 커맨드 라인을 통해 아래와 같이 확인할 수 있었다


[그림 6] - 명령창을 통한 프로세스 정보 확인


tasklist는 프로세스를 확인하는 명령어이며 svc 옵션은 각 프로세스에 호스트된 서비스를 표시하는 옵션이다. 이를 통해 위와 같이 


현재 호스트된 서비스를 확인할 수 있었고 그 중 PID 1764번이자 파일명이 v1tvr0.exe라는 의심스러운 프로세스를 확인할 수 있었다


[그림 7] - FTK Imager를 통한 $UsnJrnl, $Logfile, $MFT 추출


추출 한 파일을  NTFS Log Tracker를 이용, 파싱 된 결과를 아래와 같이 db 파일 및 csv파일로 추출해 냈다.


[그림 8] - NTFS Log Tracker를 이용한 구조 분석



[그림 9] - SQLite를 이용한 LogFile 내용 확인 및 추출할 컬럼 정보 확인


추출할 컬럼은 위에서 확인할 수 있듯 빨간 네모박스며, 파일명이 키로거인 조건을 걸어 아래와 같이 쿼리를 날렸더니 필요한 정보를 추출할 수 있었다


[그림 10] - SQL 쿼리를 이용한 필요한 정보 추출


이를 통해 키로거가 위치하는 경로 및 생성 시간을 확인할 수 있었고, 웹 브라우저를 통한 키로거 다운로드임을 추측, 웹 브라우저 아티팩트 파일을 추출했다


[그림 11] - 웹 브라우저 아티팩트 index.dat 추출


해당 시나리오에서 주어진 시스템에서는 브라우저가 IE밖에 없음을 확인했으며, 브라우저 IE의 히스토리 및 다운로드 아티팩트의 경로는 아래와 같다 


%UserProfile%\AppData\Local\Microsoft\Windows\History\History.IE5\index.dat 


[그림 12] - Index.dat Analyzer를 통한 키로거 다운로드 확인


절대 경로 : http://192.168.163.1/files/pc-spy-2010-keylogger-surveilance-spy-3.exe


생성 시간 : 2016-05-24_04:25:06


[그림 13] - 2번에서 확인한 경로에서의 키로거 확인


해당 경로의 v196vv8 폴더는 숨김 속성되어 있었고 키로거 파일인 v1tvr0.exe 역시 숨김 속성으로 되어있었다


마지막으로 4번 문제를 해결하기 위하여 해당 폴더를 탐색 중 아래의 폴더에서 z1.dat이라는 파일을 확인할 수 있었고 


해당 파일에서 시나리오서 요구하는 마지막 문제의 키 값을 얻을 수 있었다


[그림 14] - 4번 문제에서 요구하는 키 값 확인


인증키 =md5(what_the_he11_1s_keeyhttp://192.168.163.1/files/pc-spy-2010-keylogger-surveillance-spy-3.exe2016-05-24_04:25:06blackkey is a Good man)


잘 구한거 같은데 시간이 문젠지 인증이 안되네요, 해당 게시판에도 인증 때문에 말이 있기도하고.. 혹시나해서 


아래와 같이 WEFA로도 해봤는데 시간은 같이 나오고 뭐 제 부족이 아니길 바랄뿐이고 혹시라도 풀게되면 업데이트 하겠습니다


[그림 15] - WEFA를 통한 index.dat 파일 분석




Update : 2017-12-12 13:43 (PM)


시간은 문제 없었고 자세히 확인해보니 키로거의 절대 경로랑 드랍퍼(?)의 경로랑 헷갈려서 풀리지 않았었습니다


키로거의 절대 경로 및 파일명 = c:\v196vv8\v1tvr0.exe


인증키 = md5(what_the_he11_1s_keeyc:\v196vv8\v1tvr0.exe2016-05-24_04:25:06blackkey is a Good man)



#About


[그림 1] - Death_knight.c 소스 코드 확인




#Solution


[ + ] 소스 코드 해석


buffer에 40바이트 할당 및 소켓 통신에 필요한 변수들을 선언하고 포트번호 6666번으로 접속을 기다린다


19, 56번 줄을 확인하면 buffer에 40바이트를 할당한 것에 비해 256바이트를 받으므로 오버플로우가 일어나며 


다른 문제와 달리 오버플로우 방지 및 문자 필터링 코드가 없으므로 손 쉽게 셸 획득이 가능하다




셸 획득에 필요한 코드는 리버스 셸코드로, 서버에서 클라이언트 측으로 접속하는 코드를 말한다


리버스 셸 코드는 아래의 링크에서 확인할 수 있으며 IPADDR과 PORT 부분에 값을 입력해주면 된다


https://www.exploit-db.com/exploits/25497/


IPADDR과 PORT부분의 값을 메타스플로잇을 이용하여 얻을 수 있지만 굳이 메타스플로잇을 이용하지 않더라도 


IP 주소 체계가 256진수로 이루어 졌음을 알고 있다면 직접 계산도 가능하다 


해당 문제를 해결함에 있어 사용할 클라이언트 IP 주소는 192.168.232.136이며 PORT는 12345이다


[그림 2] - 클라이언트 IP 확인 및 nc를 통한 12345 포트 오픈


256진수로 이루어진 192.168.232.136을 10진수로 변환하는 과정은 아래와 같고 10진수 값으로 3232295048이 된다


192 * 256^3 = 3221225472

168 * 256^2 = 11010048

232 * 256^1 = 59392

136 * 256^0 = 136


위 10진수 값을 16진수로 변환하면 0xC0A8E888이되며 또한 PORT 번호 12345는 16진수로 변환 시 0x3039가된다


[그림 3] - 익스플로잇 코드


구해준 IP & PORT의 16진수 값을 위와 같이 입력해준 뒤 코드를 실행하면 아래와 같이 실행되며


[그림 4 ] - 코드 동작


조금 기다리게 되면 다른 아래와 같이 포트를 열어주었던 터미널에서  Connection 되었음을 확인할 수 있고 셸을 획득할 수 있었다


[그림 5] - 셸 획득



[그림 6] - Lord of Buffer Overflow 클리어

#About


[그림 1] - xavius.c 소스 코드 확인




#Solution


[ + ] 소스 코드 해석


1. buffer라는 변수에 40바이트 및 포인터 변수 ret_addr 할당


2. fgets 함수를 통한 buffer로부터 256바이트를 받아 stdin에 복사 후 buffer 출력


3. 조건문을 통해 ret의 마지막 바이트가 \xbf 또는 \x08을 막음으로써 스택 영역 및 바이너리 영역으로 리턴 불가


4. memcpy 함수를 이용, ret 주소 4바이트를 복사 후 ret 값 중 2바이트가 \x90\x90일 때 까지 반복 및 leave-ret 사용 불가


5. memset 함수를 이용, 입력 buffer 및 ret 이후의 공간, LD_*를 막기 위한 buffer아래로 3000바이트 모두 초기화




해당 문제는 buffer 및 LD_환경변수, leave-ret 영역 등 현재까지 문제를 풀어 옴에 있어 사용하던 공간을 모두 사용할 수 없다


하지만 여지껏 strcpy 함수를 이용하여 strcpy(buffer, argv[1])와 같이 사용해오던 것과는 달리 fgets 함수를 이용한다


 fgets 함수에서 사용되는 stdin은 임시 입력 버퍼로써, stdin으로 입력을 받을 경우 임시 입력 버퍼에 저장이 된다


이 때, getchar 함수와 같은 것으로 임시 입력 버퍼를 초기화 해주어야 하지만 해당 코드에서는 초기화 되지 않음을 알 수 있다


이는 메모리 어딘가에 임시 입력 버퍼의 값이 남아 있다는 말이므로 stdin에 저장 된 입력 버퍼의 위치를 찾아야 한다


[그림 2] - 디스어셈블링을 통한 stdin 구조체 주소 값을 가리키는 주소 확인


이 후 저장 된 값을 확인하기 위해선 임의의 페이로드 입력이 필요하므로 fgets 함수가 실행 된 후에 중단점을 걸고 임의의 페이로드를 입력해주었다


[그림 3] - stdin의 시작 확인


stdin 객체 <_IO_2_1_stdin_>은 _IO_FILE type이며 _IO_FILE은 /usr/include/libo.h에 정의되어 있으며 구조체는 다음과 같다



struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags /* The following pointers correspond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ ... }


위 _IO_FILE의 구조와 메모리 값을 매핑 시켜보게 되면 아래와 같다


_flags = 0xfbad2288

_IO_read_ptr = 0x4001502d

_IO_read_end = 0x4001502d

_IO_read_base = 0x40015000

_IO_write_base = 0x40015000

_IO_write_ptr = 0x40015000


주석을 살펴보면 0x40015000부터 입력 값이 저장되는 영역임을 알 수 있고 해당 영역을 살펴본 결과 임의로 입력해주었던 페이로드를 확인할 수 있다 


[그림 4] - 임시 입력 버퍼 주소 확인


이를 통해 buffer에 NOP과 셸 코드를 담고 RET 주소를 0x40015000으로 덮어 씌워 주면 문제를 해결할 수 있음을 알 수 있다


[그림 5] - 셸 획득



+ Recent posts