abcd 를 넣고 check를 눌러도 어떤 변화가 나타나지 않았다. 옆에 about을 누르니 옳은 키를 찾아서 넣어달라는 문구가 적혀 있었다.
ollydbg 로 파일을 열어 성공 메세지가 뜨는 곳을 찾아보도록 하자. 성공 메세지가 뜨는 문구를 찾았다. 이 메세지 출력부분 근처에 입력값과 올바른 키을 비교하는 부분이 있을거다. 차례차례 읽던 도중에 CMP EAX, 7A2896BF 가 있는게 눈에 띈다. EAX 값과 7A2896BF을 비교하는 것 같은데 뭔가 이 7A2896BF가 키 값인 것 같다.
7A2896BF 값을 넣어 봤는데 KEY를 찾아다는 메세지가 뜨지 않는다...혹시 다시 10진수(=2049480383)로 계산해서 넣으니까 성공!
이제 키 값은 얻었으니 문제에서 설명한대로 키 값과 주소 영역을 더한 값이 FLAG 값이다. 주소 영역을 찾기 위해서 HXD를 이용했다. 성공 메세지가 뜨는 부분을 찾아서 성공메세지 대신 KEY 값이 출력 되도록 오버라이트 하면 된다.
키값 2049480383에 널 값까지 포함해서 0x0D3B ~ 0x0D45 영역이 된다!!
문제에서도 알려 주었지만, elf 실행파일은 리눅스 환경에서 실행힝 가능하다. 실행해본 결과 사용자의 입력을 받아서 wrong 혹은 correct를 출력하는 프로그램임을 확인 했다.
IDA를 이용해서 파일을 열어보니까 main 함수에 call 부분에 write 가 있고 아래 sub_8048434 랑 sub_8048451 이 있고 cmp eax,1 에서 eax 값과 1이 같으면 correct를 출력하는 함수인 sub_80484F7을 호출하고, jnz short loc_804855B 이 실행되면 wrong이 출력되는 것을 확인 할 수 있다.
그렇다면 sub_8048434 랑 sub_8048451 중 하나에 correct로 이어지는 함수가 있을 것이라 유추할 수 있다.
sub_8048434에 들어가보니 내용이 없었고, sub_8048451에 들어가니 다음과 같은 화면이 나왔다.
자세히 보게 되면,
두번째 문자는 1이라고 주어졌고 나머지 문자들은 xor 연산을 통해서 구할 수 있다.
첫 번째 문자: xor 34h
세 번째 문자: xor 32h
네 번째 문자: xor 0FFFFFF88h
다섯 번째 문자와 58h 비교하여 같으면 loc_80484A8로 이동한다.여기서 다섯 번째 문자는 X이다.
: 프로그램 코드 크기를 줄이고자 압축하거나 혹은 프로그램 분석을 어렵게 만들려고 암호화하는 것
압축하는 것을 컴프레싱, 암호화하는 것을 프로텍팅이라 구분한다.
◆ Compressing
: 실행 코드를 압축해서 PE 파일의 특정 섹션에 저장하고 프로그램이 실행될 때 공간에 압축을 풀어 실행하는 구조이다.
: 과거에는 메모리와 하드디스크 용량이 작았기 때문에 프로그램 크기를 줄이려 등장한 기술이었고, 현재는 많은 파일을 배포할 때 전송 시간과 데이터 요금을 줄이고자 사용된다.
◆ Protecting
: 실행 파일을 암호화해서 분석을 어렵게 만드는 기술로, 실행 코드는 암호화된 상태로 배포되고, 실행 시점에 복호화되어 동작을 수행한다.
: 약간의 속도 저하가 발생하지만, 비밀 보호가 중요한 프로그램 혹은 악성코드의 경우 이러한 프로텍팅 기술이 적용된다.
1-2. 언패킹 동작 방식
UPX 기반으로 살펴보도록 한다.
UPX로 패킹된 파일은 1. unpacking code (언패킹에 필요) 2. packed data(패킹된 데이터가 들어가 있는 영역) 3. Empty sapce ( 언패킹된 데이터가 저장되는 빈 공간) 으로 구성된다.
01. 운영체제의 loader가 실행 파일을 메모리에 로딩
02. entry point 로부터 프로그램 실행되어 패킹된 파일의 entry point는 언패킹 코드 영역에 들어 간다.
03. 언패킹 코드는 패킹된 데이터를 하나씩 읽어 압축을 해제하고 공간에 원본 데이터를 저장한다.
후에 모든 코드가 언패킹되면 OEP(original entry point)에서부터 프로그램이 다시 시작된다.
1-3. 패킹 도구
◆ Compressor
: Petite, ASPack, MEW, FSG, UPX 등
◆ Protector
: Themeda, Yoda, ASProtect, armadillo 등
01. UPX
: 가장 많이 사용하는 실행 압축 프로그램으로, 여러 운영체제에서 다양한 파일 형식을 지원하도록 오픈 소스 형태로 제공된다.
02. ASPack
: 상용 프로그램으로써 지속적인 프로그램 개발이 이루어지는 고성능 compressor로 빠른 복호화 루틴을 통해 높은 성능을 제공한다.
03. Themida
: 상용 프로텍터로 적용된 옵션마다 언패킹 방법이 다르기에 풀기 어려운 강력한 프로텍터 중 하나다.
많은 악성코드가 Themida를 사용해서 프로텍팅되어 있으며, 국내에서 사용되는 많은 보안 프로그램과 ㄱ게임들이 실행 파일을 리버싱으로부터 보호하기 위해 Themida를 사용한다.
04. ASProtect
: UPX와 유사하게 패킹된 코드를 특정 영역에 넣고 실행 시간에 언패킹해 사용하는 방식이다.
수동으로 언패킹하기 쉬운 단점이 있다.
2. 대표적인 패커 UPX
2-1. 개요
UPX란?
: 오픈 소스 실행 압축 파일로 윈도우뿐만 아니라 다양한 운영체제를 지원하고 있다.
- 장점
01. 압축과 해제에 효율적인 알고리즘을 제공하고 있어 압축 효율이 높다.
02. 압축된 파일을 실행하기 전 압축을 해제하는 과정에서 매우 효율적으로 처리하여 메모리 부하가 매우 낮은 편이다.
03. 다양한 실행 파일 형식을 지원한다.
04. 효율성 높은 압축 성능을 제공한다.
05. C++ 언어로 개발되어서 이식성이 높다.
06. 새로운 실행 파일 형식이나 압축 알고리즘을 추가하기에 유연한 구조이다.
07. CNU 라이선스 하에서 자유롭게 사용이 가능하다.
2-2. 패킹
upx -o '패킹 후 파일' '패킹 전 파일'
+ -o : option = output file
+ upx -h : 도움말
2-3. PE 파일 확인
◆ Detect It Easy
: PE 파일을 분석할 수 있는 프로그램으로 UI가 쉽게 구성되어 있다.
: PE 파일에 대한 다양한 정보를 얻을 수 있다.
01. 파일 크기
02. 프로그램 생성 시 사용된 시스템 소프트웨어 정보
03. PE 파일에 대한 요약 정보
04. Code Section 위치 여부
05. 데이터 분포 정보를 주는 entropy로 섹션마다 분포된 것을 확인 할 수 있다.
2-4. 언패킹과 OEP
◆ entry point
: 프로그램에 대한 제어권이 운영체제에서 사용자 코드로 넘어가는 지점으로 프로세서가 메모리에 있는 코드 섹션으로 처음 들어가는 지점이다.
: 엔트리 포인트가 위치한 곳은 PE 헤더에 있는 AddressOfEntryPoint에 저장되어 있다. 이 위치는 상대 주소이기에 AddressOfEntryPoint + ImageBase 메모리 주소가 프로세서가 인식하는 진짜 엔트리 포인트의 주소가 된다.
+ OEP(Original Entry Point)
: 패킹되기 이전 프로그램의 실제 엔트리 포인트다. 언패킹할 때 가장 중요한 것 중의 하나가 정확한 OEP를 찾는 가가 관관건이다.
01. UPX로 패킹된 파일의 엔트리 포인트는 PUSHAD 명령어(모든 레지스터의 값을 스택으로 백업하는 동작을 수행)로 시작한다.
02. 다음으로 언패킹 코드가 따라온다. 압축된 데이터를 풀어 메모리 특정 영역에 저장한다.
03. 언패킹이 끝나면 POPAD 명령어를 수행해 스택에 저장된 레지스터 값을 다시 복구한다
04. 이제 OEP로 점프해서 프로그램 본래의 기능을 수행한다.
05. OEP 아래에서 패킹되기 전의 원본 코드를 확인할 수 있다.
2-5. 메모리 덤프
◆ OllyDumpEx 플러그인
: 메모리에 로딩된 PE 파일의 상태 그대로 PE 파일로 다시 저장하는 기능을 지원
: OllyDbg에서 지원하는 UPX 언패킹 기능을 사용했다면, 올바른 엔트리 포인트 값이 설정되겠지만, MUP 방식을 사용하게 되면 직접 입력해야하는 부분에서 엔트리 포인트 주의하여야 한다.
2-6. IAT 복구
: 윈도우 응용 프로그램은 DLL 형태의 시스템 라이브러리를 사용하는데, 프로그램이 실행되면서 필요할 때 DLL을 불러와 사용한다.
: 어떤 DLL에서 어떤 함수를 잠조하는 지에 대한 정보가 PE 헤더의 IAT에 저장되어 있다. 메모리 덤프하는 과정에서 IAT 테이블은 쉽게 손상되기 때문에 별도의 복구 과정이 필요하다.
: 손상된 IAT 정보는 Detect It Easy 프로그램을 통해 쉽게 확인 할 수 있으며, 손상된 IAT 파일을 복구하려면 PE 헤더 정보를 분석해서 사용하는 DLL과 함수에 대한 정보를 일일이 맞춰야 한다. 하지만 일부 정보가 손상되었더라도 일정한 규칙이 있기 때문에 프로그램으로 복구할 수 있다.