[코드엔진] Basic RCE L14 풀이

코드엔진 Basic RCE L14번 문제를 풀어보았다.


실행 파일을 DIE에 올려보았다. UPX로 압축되어있다고 한다.


UPX 압축을 풀었다.


압축을 푼 파일을 IDA에 올리고, F5를 눌러 디컴파일해보았다. 그리고 유의미해 보이는 sub_401025 함수에 들어가보았다.


또 win32api에서 중요한WndProc함수인 sub_4011E2 함수 안에 들어가보았다.


중간 부분에서 do while 연산을 볼 수 있는데, 이곳에서는 byte_403037에 어떠한 연산을 수행해서 새로운 v5를 만든다.

특이한 점은 인덱스를 의미하는 v7이 1부터 시작한다는 것인데, 입력받은 Namedword_403038이므로 Name의 인덱스 0은 byte_403037의 인덱스 1과 동일하다는 것이다.

즉, 여기서 byte_403037Name과 동일하게 보고 문제를 풀어도 된다.


sub_401383에 들어가면 이러한 연산을 볼 수 있는데, sub_401383라는 연산 후의 Name과 v5가 일치하는지를 확인한다.


동일하면 aGoodJobIWishYo에 있는 캡션을 메세지박스에 출력하고, 동일하지 않으면 aYouHaveEnterAW에 있는 캡션을 메세지박스에 출력한다.


각각의 캡션에는 아래와 같은 메세지가 들어가 있다. 결국 Good Job, I Wish You the Very Best을 출력하려면 do while문 후의 v5sub_401383(byte_401338)이 같아야 한다. 이 둘을 각각 살펴보도록 하자.


1. do~while문 후의 v5

아래의 디컴파일된 코드를 파이썬으로 바꾸면 다음과 같다.

name = "CodeEngn"
v5 = 0

for ch in name:
  v5 += (ord(ch)>>1) + ord(ch)*ord(ch) - ord(ch)
  
print(v5)

  • 파이썬 코드에 디컴파일된 코드처럼 v5를 더해주지 않은 이유는 v5 += 라는 식 자체에 자기 자신을 더해주고 있다는 뜻이 포함되기 때문이다.

결과는 76193가 나온다.


2. sub_401383(byte_401338) 구하기

이제 76193라는 값과 sub_401383(byte_401338)를 비교해서 같으면 Good Job, I Wish You the Very Best을 출력한다.


sub_401383을 더블클릭해서 안으로 들어가보았다. 그러면 아래와 같은 코드가 보인다.


변수명을 다르게 바꿔보았다. 먼저 do while문 안에서 num = c - '0'은 문자를 정수로 만들어주는 코드이다.

예를 들어, 아스키코드 '3'(51)에서 아스키코드 '0'(48)을 빼면 정수 3이 남는다.

이제 몇자리 수인지 알려주어야 한다. for 문으로 len-1부터 i까지 -1씩, 결국 0부터 len-1번 10을 곱한다. 그러면 12345가 있을 때 1은 1*1000, 2는 2*1000, 3은 3*100, 4는 4*10, 5는 5*0이 된다.

(이는 모두 아스키코드 '1', '2', '3', '4', '5'에서 각각 '0'을 빼서 정수 1, 2, 3, 4, 5가 되어 계산된 것이다.)


결과적으로 보기에는 76193으로 답이 같지만, 이전에는 문자열이었다면 지금은 숫자라는 점에서 연산을 거치기 전과 다르다.

정답은 숫자 76193이다!

좋은 웹페이지 즐겨찾기