woonadz :)

[CodeEngn Basic] RCE L01 문제 풀이_nabi 본문

IT/codeengn 문제 풀이

[CodeEngn Basic] RCE L01 문제 풀이_nabi

C_scorch 2021. 9. 13. 23:31
반응형

기록용

3줄 TMI

첫 포스팅을 리버싱 문제로 하게 되다니 너무 기쁘다. 2달전부터 만들려고 한 블로그지만 나의 소소한(?) 실력들을 밝히고 싶지 않아 이제야 포스팅하게 되었다. 누군가 내 풀이를 봐 준다면 너무나도 감사할 것 같다. 일단 나의 현재 상태는 리버싱 이 정도는 알아야지 강의를 수강한 상태고 리버싱 입문 1단원, A1을 공부한 상태다. (완전 쌩초보)

 


 

동아리 팀활동에서 풀고 이미 팀블로그에 나의 풀이를 올린 문제지만 내가 푼 과정을 처음부터 세세하게 담고 싶어 동아리 진도에 맞게 앞으로 포스팅하려 한다. 이번 학기 끝날 때쯤에 다시 읽어보면 너무 웃길거 같다ㅎㅎ

 

사실 1번 문제 파일을 열 때부터 순탄치 않았다. 7z로 압축되어있는 파일을 처음 봤기에 별도의 프로그램 없이 압축을 풀 수 없다는 것을 몰랐다. 그것도 모르고 한 20분 씨름한거 같다..

https://www.7-zip.org/download.html

 

Download

Download .7z Any / x86 / x64 LZMA SDK: (C, C++, C#, Java)

www.7-zip.org

나는 이 주소에서 7-zip을 다운받았다. 7-zip을 다운받고 7z로 압축된 파일을 열면 열릴 것이다. 처음 리버싱 문제를 풀어본 사람들은 나처럼 이상한데서 삽질하지 않길 바란다.

 

그럼 7-zip을 다운받으면 열리냐? 그건 또 아니었다. 물론 이건 윈도우 설정의 문제지만 나는 실시간 보호를 켜두었기에 압축을 풀어도 자동으로 파일이 삭제되었다. 솔직히 파일 압축을 풀 때마다 바이러스 위협이 있다는 알림이 계속 뜨길래 속으로 오만가지 생각을 했다. 여기서도 한 30분 헤맨거 같다... 시간을 효율적이게 못써서 스스로가 굉장히 답답했다.

이 문제에 해결법은 간단하다. 윈도우 설정 -> 업데이트 및 보안 -> windows 보안 -> 바이러스 및 위협 방지 끄기 

이렇게 간단한 방법으로 이제 파일이 열릴 것이다. (아 window 10 기준이다 다른 버전은 써본적이 없어서 모르겠다..) 

 


이제 정말 Basic RCE L01 문제 풀이를 시작해보겠다.

HDD를 CD-Rom으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가

abex' 1st crackme 파일을 처음 열었을 때 화면

abex' 1st crackme 파일을 처음 열면 이런 화면이 보인다. 시작 주소가 00401000이다. 즉, 앤트리 포인트가 00401000이다. 이제 앤트리 포인트부터 차례로 한줄씩 실행시켜줄것이다. F8을 이용하여 함수 내부로 들어가진 않고 실행만 시켜준다. (F8의 또 다른 기능이 탑재되어있는 노트북은 Fn 키와 함께 눌러주기)

MessageBoxA 실행시키기

한줄씩 실행시키다 보면 0040100E 주소에서 이러한 메시지 박스가 실행된다. 나의 HD를 CD-Rom으로 인식하도록 만들어야겠다. 이제 또 한줄씩 실행시켜보겠다.

GetDriveTypeA 실행시켜야 할 단계

문제에 나온 GetDriveTypeA가 포함된 줄이니 리턴값이 어떻게 바뀌는지 집중해서 보자. 리턴값, 즉 반환값이 저장되는 레지스터는 EAX 레지스터이다. 현재 EAX 레지스터의 값은 1이다.

GetDriveTypeA 줄을 실행시킨 상태

EAX 레지스터의 값이 3으로 바뀌었다. 즉, GetDriveTypeA의 리턴값이 3이다. 

다시 또 한줄씩 실행시켜보겠다.

두번째 메시지박스 실행
exit(프로세스 종료)

프로세스를 끝까지 다 실행시켜보면 3번째 메시지 박스를 건너뛰었다는 것을 알 수 있다. 또 이 메시지 박스에는 우리가 원하는 내용이 담겨있다. 세번째 메시지 박스를 실행시키려면 어떻게 해야 할까?

두번째 메시지 박스 위에 명령어들로 거슬러 올라가 보겠다.

CMP 명령어까지 실행시킨 상태

현재 CMP 명령어까지 실행시킨 상태이다. CMP 명령어는 인자 1과 인자2의 값을 비교하여 같을 경우 제로플래그에 1을 입력, 다를 경우 0을 입력한다. 위 사진에서 제로플래그 값을 보면 0이다. 또한 EAX 레지스터 값과 ESI 레지스터 값이 다르단걸 알 수 있다. 또 이제 실행시켜야 할 차례인 JE 명령어는 제로플래그 값이 1일 경우 0040103D로 이동한다. 즉, 우리는 EAX 레지스터 값과 ESI 레지스터 값을 같게 만들어야 한다. 문제에서 조건에 맞는 GetDriveTypeA 리턴값을 구하라고 하였기에 우린 EAX 레지스터 값을 건드려 ESI 레지스터 값과 같게 만들것이다. 

무엇을 바꿔야 할지 결정했으므로 CMP 명령어부터 거슬러 올라가며 인자가 EAX인 명령어를 하나씩 해석해보겠다.

00401023 주소의 명령어 : EAX 레지스터의 값에서 -1을 해라.

0040101E 주소의 명령어 : EAX 레지스터의 값에서 -1을 해라.

GetDriveTypeA의 리턴값에서 총 -2를 한 값과 ESI 레지스터의 값(401003)이 같아야 한다. 즉, GetDriveTypeA의 리턴값은 401005로 수정되어야 한다.

GetDriveTypeA 리턴값 수정하기

이제 나머지를 실행시켜보겠다.

제로플래그 값이 1로 바뀜
문제 풀기 성공!

짠!!!!!!!!!!!!

 

사실 ESI 레지스터 값과 내가 결론을 내린 답이 몇 몇 분들과 전혀 다르길래 엄청 멘붕이 왔었다. 그때는 시간이 없어서 문제 다 풀고 다른 분들의 풀이를 3~4개 정도 밖에 보지 못했는데 오늘은 시간 여유가 있어서 좀 찾아보았다. 사실 아직도 명쾌한 해답을 얻은 건 아니다... 혹시라도 이유를 아시는 분이 계신다면 꼭 알려주셨으면 한다.

 

ESI 레지스터는 데이터를 조작하거나, 복사시에 소스 데이터의 주소가 저장하는 역할을 한다. 그래서 내 추측에는 이 파일이 원본이 아니라 누군가가 한번 수정을 한 파일이 아닐까 싶다.(아닐 가능성이 크기에 나중에 좀 더 개념이 자리 잡히고 이유를 알게 되면 수정을 할 예정이다.) 그냥 재미로 읽기...!

=> ASLR을 끄자. ASLR로 주소가 바껴서 사람마다 다르게 값이 나온 것.

 

내가 결론을 내린 답이 몇 몇 분들과 다른 이유는 ESI 레지스터 값이 다르기 때문인데 나와 같은 결론을 내린 블로그의 글들을 읽어보았다. 401005, 이 답의 40100이 코드 부분의 주소이니 5가 리턴값이라고 결론을 내리신 분도 있으셨고 제작자가 원하는 GetDriveTypeA의 리턴값은 5 이지만, 실제로 동작하도록 하는 리턴값은 401005이라고 결론을 내리신 분도 계셨다. 사실 전자의 내용은 이해를 못했다... 앞으로 공부를 더 하다보면 이해가 될 것 같기도 하다.

 

끝인사 및 느낀점

쌩초보라서 그런지 엄청 낑낑대면서 오랜시간 동안 풀었는데 막상 다 풀고 나면 엥 싶은 문제였다ㅎㅎ 오늘 시간이 좀 많아서 여유롭게 글을 썼는데 다 쓰고 보니 왜 이렇게 오래 쓴건지... GetDriveTypeA의 리턴값 말고도 다른 방법으로 세번째 메시지 박스에 이동할 수 있게 다양한 풀이도 포스팅 하고 싶었는데 이제 또 시간 여유가 없어졌다..첫글이니까 하고 싶은 말이 많았던 걸로 자기합리화했다. 작은 바람이 있다면 아무리 바빠도 학기 말까지 규칙적으로 업로드 하고 싶다. 화이팅!

반응형