BlackJackson의 Hacking Story

TRUST CTF 리버싱문제 (MESS) - write up 본문

기타 IT

TRUST CTF 리버싱문제 (MESS) - write up

알 수 없는 사용자 2019. 2. 18. 19:37


상대적으로 쉬운 문제였던 Mess파일 리버싱.
일단 뭐가됬든 가장 먼저 해 볼 방법은 역시 직접 실행이라 생각해서 실행을 해보았다.


다행이도 직관적으로 어떤 프로그램인지 알아보기 쉽게 만들어논 문제다.

대충 위의 문장을 보면


"우리가 숨겨둔 X8Wj<UF:x\5wl 라는 코드를 풀면 된다"
입력:



아무거나 입력을 해보자.
그러면 키가 틀렸는지 바로 프로그램이 종료되게 만들어져있다.
이제 어떤 툴로 프로그램을 뜯어볼지 결정하고 뜯으면되는데
필자는 아직 olldbg밖에 쓸줄 모르는 사람임으로 무작정 ollydbg로 실행을 해보았다.
보통 막아두는 경우도 보통인데 다행이 여는데 성공을 했다.









메인함수 영역을 보면 대충 이런 식이다.
주석에 뭐라고 뭐라고 열심히 적혀있다.
만약 생각이 단순한 사람이라면 이 스크린샷만 보고도 맞춰버릴수도 있는 꽤나 간단한 방법의 문제이다.
일단 함수를 끝까지 실행해서 프로그램 종료과정까지 둘러보도록 하자.

실행을 시작하면 013550C1 ~ 013550EE를 일정 횟수 반복하게된다.
처음에 함수를 실행하다보면 이 반복이 지루해서 눈이 굴러간다면 정상.



f8를 아무생각없이 누르다보면 이렇게 넘어오게된다.
그러면서 첫줄 실행창이 프린트되었는데.
이 과정을 지내면서 의문점을 발견하지 못했다면 조용히 ctl f2를 눌러서 다시 해보길 바란다.




.
.
.
.
.
.




그렇게 하다보면 발견 못할래야 못할 수가 없는 부분이 생긴다.

바로 



이 함수다.

주석을 보면 
013550C1 ~ 013550EE 구간을 한번 반복할 때마다 한글자씩 글자가 바뀌는 것을 발견할 수가 있다.
처음엔 아무생각 없이 지나 갈수도 있다.
나도 보고서 이게 왜바뀌는건지 의문은 들었지만 중요히 생각안하고 계속해서 내려가기 바빴으니.

하지만 정신을 차려보면 결국 저 주석에 있는 아스키코드는 


요렇게 실행창에 보이던 hide 코드로 변해있다.

일단 여기까지만 생각하고 더 진행해 보도록 하자.



예상한대로 "%s"에서 프로그램 진행이 멈춘다.

초보들은 이떄 당황하며 "뭐지 프로그램이 끝났나?", "내가 뭐 잘못눌렀나?" 생각하며 당황해서 다시 초기화 할수 있으나
당황하지말고 이럴때는 실행창에 문자열을 입력해주면된다.
즉 명령어가 까라는데로 우리는 까면 되는 것.
아무말이나 입력해보자.



입력하면 다음함수로 진행이 된다.





내가 입력한 스트링을 EBP에서 EAX로 옮기기 시작하며 다시 뺑뻉이가 시작되고 전부 옮기고 나면 EAX에 다 담겨지게되며 레지스트리 값을 보면 뭐가 담겼는지 확인이 가능하다.



우리의 예상대로라면 EAX에는 "tlqkf"이 담겨있어야 할텐데 확인해보면


이라고 적혀있다.

이로써 다시한번 의문을 갖게되면서 아까 들었던 의문과 맞아떨어진다는 것을 캐치할 수 있게된다.

다시 처음 문장을 해석해보자.



"우리가 숨겨둔 X8Wj<UF:x\5wl 라는 코드를 풀면 된다"



즉 일종의 제작자만의 규칙을 통해서 인코딩된 문자열이라는 걸 뜻한다.
그리고 우리가 입력한 "tlqkf"도 01355136 ~ 0135515D 함수의 반복으로 "yqvpk"로 인코딩 됬다는 뜻이다.
여기서 어셈블 코드를 조금 볼 줄 아는 사람은 적혀있는 뜻을 해석해서 바로 알 수가 있다.
01355153을 보면 ADD ECX, 5라고 친절히 써져있다.
아스키 코드는 결국 16진수의 숫자값으로 우리가 적은 아스키값에 5씩 더해서 변환값을 뱉어내고 있다는 것을 알 수가 있다.

하지만 ECX가 뭔지 EBP가 뭔지 잘 몰라도 시간을 들이면 더 직관적으로 알 수 있는 방법이 존재한다.

abcdef를 입력해보거나
1234를 입력해보는 방법이다.

매우 원초적이지만 때론 쉽게 어떤 규칙을 발견하는 방법으로 매우 좋은 방식이라 생각한다.
현재는 우리가 문자를 입력했을때 규칙을 발견하기 쉽지가 않다는 것을 보아서 1234를 입력해서 다시 프로그램을 돌려보았다.




이처럼 내가 조금 지식이 부족하다 싶으면 직접 구르면서 해결해나가면 된다.
전혀 포기할 필요가 없다는 것이다.
저것만 봐도 우리는 규칙을 바로 알수가 있다.


"아, 각 스트링에 +5를 하는게 규칙이구나!"


여기서 조금 요령을 알고 귀찮은걸 싫어한다면 아마도 당신은 ctl f2를 눌러서 재실행해서 바로 코드값을 의심해보고 직접 넣어볼 것이다.
그게 아니라 조심하는 스타일이면 바로 인터넷에 아스키코드표를 검색해서 


X8Wj<UF:x\5wl
이 문자를 하나하나 비교하고 있을 것이다.

방법은 다양할 뿐 풀이에는 왕도가 없다.


사실 +5 규칙은 몰라도 푸는데 지장이 없다.
다만 우리에게 힌트를 더 제공하는 하나의 정보일 뿐
이쯤 개고생을 하고나면 서서히 뒷목을 잡고 보게 될 주석이 하나 있을 것이다.



바로 아까본 이 코드

이코드가 프로그램이 진행되면서 hide code값으로 변하게 된다.
사실 우리에게 정답을 다 보여주고 시작한 것이다.
013550E2에도 보면  01355153와 같은 명령어가 적혀있다.

즉 S3CRe7PA5sW0rD가 각각 5씩 더해서 hidecode값이 되었다는 것을 우린 발견할 수가 있게된다.

아마도 어셈블 코드를 잘 읽고 해석 할 수 있는 사람이라면 나처럼 프로그램을 끝까지 실행하지 않아도 바로 발견했을 것이다.


그럼이제 우리의 가설이 맞는지 input에 써보도록하자.


그냥 입력해서 실행하면 프로그램이 빛의 속도로 꺼지므로 디버깅을 통해 보도록하자.



예상대로 우리의 입력값은 비교 값과 일치하게된다.

만약 코드가 틀리게된다면 01355168에서 013510D7로 내려가게 되겠지만 우리는 일치함으로 그대로 바로 밑 코드들이 실행된다.

이정도 내려오게되면 flag값을 얻을 수 있다.



이로써 간단하게 생각한다면 정말 쉬울 수 있고 좀만 더 살펴본다면 대부분 알아 낼 수 있는 문제였다.






Comments