코드엔진 Basic - 6번 문제 풀이

김왕구·2023년 7월 24일
0

CodeEngn

목록 보기
1/3

이번에 풀 문제는 CodeEngn Basic의 06번 문제입니다.

우선 들어가기에 앞서 문제에서 제공된 정보를 수집해야합니다.
06basic-question
문제의 핵심은 SerialOEP(Original Entry Point)을 찾는 것입니다.
하지만 문제 내용에 "Unpack"이라는 키워드가 있어 어떤 알고리즘에 의해 압축이 되어 있을 가능성이 존재합니다.

ExeInfoPE

문제에서 주어진 프로그램에 어떠한 압축이 있는지 확인하기 위해 ExeInfoPE를 사용하여 Basic 1번 문제에서 제공되는 프로그램과 비교해보았습니다.

ExeInfo01PackingStatus

ExeInfo06PackingStatus

두 프로그램의 자세한 내용에는 차이가 있을 수 있지만 6번 문제의 프로그램 EP(Entry Point) Section의 이름이 "UPX1"으로 다른 것을 확인할 수 있었습니다.

그렇다면 위에서 얻어낸 정보인 "UPX1"에 대하여 검색을 해보았습니다.

WikiPediaUPXInfo

검색한 결과에 따르면, UPX(Ultimate Packer for eXecutables)란 여러 운영체제에서 수많은 파일 포맷을 지원하는 오픈 소스 실행 파일 압축 프로그램입니다. UPX는 UCL이라는 데이터 압축 알고리즘을 사용하고 있습니다.

이제 6번 문제의 프로그램이 UPX로 압축 되어 있다는 것을 알았으니 UPX 프로그램을 이용하여 압축을 풀어보겠습니다.

우선 원본 파일과 비교하기 위해 Packing 프로그램Unpacking 프로그램을 준비하겠습니다.

언패킹을 하기 위해 UPX를 실행하여 -d 옵션을 이용하여 아래와 같이 압축을 해제합니다.

이제 두 프로그램을 비교해보겠습니다.

ExeInfo06PackingStatus

ExeInfo06UnpackingStatus

같은 프로그램이지만 Packing 여부에 따라 EP(Entry Point) SectionEP(Entry Point)가 다르다는 것을 알았습니다.

분석

UPX 프로그램을 이용하여 Unpacking 프로그램과 Packing 프로그램을 분석해보겠습니다.
프로그램을 분석을 위해 사용할 툴은 xdbg입니다.

Packing Program(Basic-06)

Packing-EP
Packing-UnpackingStub

Packing 프로그램의 Entry Point004298F0이라는 것을 알 수 있습니다.
전체적으로 보았을 때 pushadpopad라는 명령 볼 수 있는데, 이 명령은 범용 레지스터인 EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDIStack에 저장하고 복원합니다.

위 명령을 수행하는 이유는 패킹된 프로그램이 압축된 코드를 언패킹하여 원본 코드를 복원하는 작업을 수행하기 때문입니다.
원본 코드를 복원하는 과정에서 레지스터의 값이 변동되기 때문에 EP에서 레지스터의 초기 상태 값을 저장하는 명령을 수행합니다. 코드 복원 작업이 끝나면 popad 명령을 통해 레지스터를 초기 상태로 되돌립니다.

jmpOEP
OEP

언패킹 스텁이 끝나고 나오는 jmp 명령은 이 프로그램의 OEP(Original Entry Point)로 이동하여 코드가 정상적으로 실행되도록 합니다. jmp 명령의 주소는 401360을 가리키고 있기 때문에 OEP401360이 됩니다.

Option

  • OEPjmp되는 코드를 찾았다면 OEPEIP를 이동시킨 뒤, scylla plugin를 이용해 덤프를 하여 일부 복원이 가능합니다.

dump

Unpacking Program(Basic-06)

패킹된 프로그램의 분석이 끝났으니, 언패킹된 프로그램을 분석해보겠습니다.

UnpackingEP

언패킹된 프로그램은 위 사진과 같이 EP가 패킹된 프로그램에서의 OEP와 같다는 것을 다시 한 번 더 확인할 수 있습니다.

Serial Key를 찾는 가장 간단한 시도는 프로그램의 정적 데이터에 Serial Key가 존재하는지 확인해보는 것입니다. 문자열을 찾는 것은 xdbgFind Strings 기능을 사용하여 찾을 수 있습니다.

Find Strings

위 사진과 같이 프로그램에서 쓰이는 문자열들이 보이는 것을 확인하실 수 있습니다.
하지만 어떤 것이 Serial Key인지는 모르는 상황이기에 Key 입력이 틀렸을 시, 출력되는 "Wrong serial!!!"이라는 문자열을 검색하여 추적할 것입니다.

Wrong serial!!!

Hint

Key 불일치 시에 출력되는 문자열을 추적하니 성공 시 출력되는 문자열과 Serial Key로 추정되는 문자열이 보입니다.

확인하기 위해 프로그램을 실행하여 위 사진에서 발견한 Key(AD46DFS547)를 입력해보았습니다.

Success Serial!

Serial Key가 일치하는 것을 확인할 수 있었습니다.

이제 이전에 찾아둔 OEPSerial Key를 합치면 정답은 00401360AD46DFS547가 됩니다.

Success 06 Basic

다음은 7번 문제 풀이로 찾아오겠습니다. 감사합니다!

profile
시스템 보안과 운영체제 개발, Rust에 관심이 많은 학생

0개의 댓글