달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

※ LEVEL 13


Q. There is a security check that prevents the program from continuing execution if the user invoking it does not match a specific user id.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
 
#define FAKEUID 1000
 
int main(int argc, char **argv, char **envp)
{
  int c;
  char token[256];
 
  if(getuid() != FAKEUID) {
      printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID);
      printf("The system administrators will be notified of this violation\n");
      exit(EXIT_FAILURE);
  }
 
  // snip, sorry :)
 
  printf("your token is %s\n", token);
  
}
cs


A. 이는 간단한 리버싱 문제이다. "// snip, sorry : )" 라고 표시되어 삭제된 코드 부분을 맞추는 문제이다. 


위의 14번째 라인만 우회하면 토큰 생성 로직으로 넘어가게 되는데 어셈블리어를 스스로 분석해도 되고 그냥 넘어가도 알아서 토큰이 생성되어 출력되므로 뭐 편할대로 하면된다. 간단하니까 별도 설명없이 캡쳐만 첨부하도록 하겠다. 


[그림 1] 로직 우회 후 토큰이 생성되는 것을 확인


[그림 2] 토큰 값을 패스워드로 사용하여 로그인 




※ LEVEL 14


Q. This program resides in /home/flag14/flag14. It encrypts input and writes it to standard output. An encrypted token file is also in that home directory, decrypt it :)


A. 이는 토큰 파일에 암호화되어 있는 문자열을 복호화하는 문제이다. 이 또한 굉장히 단순한 리버싱 문제이다. 


[그림 3] 토큰 값 확인 


[그림 4] 프로그램을 실행하여 암호화 로직 확인 


보는 바와 같이 굉장히 간단한 암호(?)화 방식이다. 실행 방식만 봐도  규칙을 알 수 있다. 문자열 인덱스 값을 문자 아스키코드에 더해 나오는 방식이다. 그럼 뭐 간단히 코드를 짜서 복호화해도 되고 얼마 안되니 수동으로 해도 되고.. 


[그림 5] 토큰 값 확인 


[그림 6] 플래그 확인 



이번 두 문제는 오히려 이전 레벨보다도 너무나 쉬웠다.

이런 문제들도 가끔 나와야지 ~ ㅋ






:
Posted by einai

이 문제는 이전에 MetroApp 문제의 업그레이드 버전이라고 보면 될 것 같다. 


게임으로 동작되는 터라 낯선 부동소수점 연산을 눈에 익히는 과정과 객체를 분석하는 과정에 애를 먹었다. 

낯선 어셈블리 명령어를 보니 문제가 더욱 더 어려워보였다. 


하지만 막상 문제를 풀었을 때는 핵심을 놓치고 주변 것들에 너무 신경을 쓰고 있었구나 라는 느낌을 받았다. 


그럼 문제풀이를 시작해보겠다.

우선 ReadMe.txt 파일을 먼저 열어보았다.




해당 파일을 보았을 때 두개의 플래그가 존재하고 이를 결합한 뒤 md5 해시 함수를 적용하면 되겠구나 싶었다. 물론 정답은 소문자로 입력하고..!!




이후 애플리케이션을 동작시켜 보았다.




짠 ~ 저 네모난 주인공이 빨간 악마를 총으로 쏴 죽이는 게임이다. 


이를 보았을 때 뭐를 어떻게 해야 답을 맞출까 고민을 했다. 게임 난이도는 엄청나게 어렵다.

활성화되어 있는 악마만 죽일 수 있고 속도도 다양하고 움직이는 방향도 다르다. 




쩜쩜쩜.. 마음을 가다듬고 문제를 분석했다. 



저기에 보이는 빨간 박스에 존재하는 게 첫번째 조건이다. 0xDDB 수만큼 악마를 죽이면 된다. 그래도 이건 양호하다.

두번째 조건은 0x31159cd 마리를 잡아야 한다. - - ;


순간 별의별 생각을 다했다. 악마를 일렬로 내려오게 할까? 모든 악마를 활성화 시켜볼까? 등등..

결국 걍 알아서 죽이게끔 만들어서 동작시켰다. 



흠흠.. 게임할 땐 엄청 빨리 내려오던 악마들이 너무 천천히 내려왔다. 물론 속도는 동일하겠지만 스코어가 올라가는걸 보고 있자니 가슴이 답답했다. 약 1시간? 가량 돌리다보니 첫번째 플래그를 얻을 수 있었다. 


1초에 한마리씩이라고 가정했을 때의 속도랑 거의 유사했다. 

이후 고민을 했다. 


0x31159cd 마리는 약 51468749 초가 걸리고... 이는 857812분이 걸리고.. 이는 14296시간이 걸리고.. 이는 595일이 걸린다. 이 문제를 풀기 위해 약 2년이 안되는 시간을 컴퓨터만 켜놓고 요놈만 바라보고 있을 것인지.. 다른 해결책을 찾을 것인지..!!



결국 다른 해결책을 찾았다. !

걍 정답 로직을 구현해서 돌려버렸당. 그러니 뭐 금방 답이 나왔따 ! 냠냠

이제 CRC 문제들만 남았넹.. 아직 머릿속에 그림이 안그려지는디 어떻게 접근해야 할랑가~



:
Posted by einai

※ 사전지식 


AVR Registers 

총 32개로 구성되어 있으며 R0 ~ R31 로 표기한다. 



AVR 메모리 참조 방식 

AVR은 독특하게도 X, Y, Z 라는 명칭(?)으로 메모리를 참조하는데 이는 각 아래와 같이 레지스터에 의존한다.

X : R27:R26 

Y : R29:R28

Z : R31:R30 




따라서 이런 연산을 하는 어셈블러들을 리버싱하는 동안에 수도 없이 볼 것이다. 



AVR 어셈블리어 

AVR Studio로 디버깅을 하면 친절하게 어셈 명령어 옆에 해당 명령어가 무엇을 하는지 나타낸다. 


추가로 AVR 어셈블리어도 앞에 위치하는 피 연산자(R30, R31)에 연산된 결과가 적용된다. 

즉, ADD R30, R24 -> R30 += R24 와 동일하다.

 

자주 보여졌던 어셈블리어에 대해서만 나열하도록 하겠다. 


RCALL - Relative Call to Subroutine

CPC- Compare with Carry 

CPI- Compare with Immediate

LDI - Load Immediate

LSR – Logical Shift Right

ST - Store Indirect From Register to data space using Index X

ST (STD) - Store Indirect From Register to data space using Index Y

ST (STD) - Store Indirect From Register to data space using Index Z

BRNE - Branch if Not Equal

BREQ - Branch if Equal

BST – Bit Store from Bit in Register to T Flag in SREG

BRCC - Branch if Carry Cleard 

BRTC – Branch if the T Flag is Cleared


사전지식 끝!



그럼 이제 문제풀이를 시작하도록 하겠다. 


이 문제는 사전지식에서 알 수 있듯이 AVR(Atmel AVR) 아키텍쳐 기반 애플리케이션을 리버싱하는 문제이다.

AVR는 임베디드 전용 아키텍쳐라고 하는데 이번 기회에 처음 접해보았다.  


해당 애플리케이션은 AVR Studio와 hapsim 을 이용하여 동적 디버깅을 하면 된다. 


간단히 프로그램들을 설명하자면 AVR Studio는 AVR 디버거이고

hapsim은 AVR 디버거로 분석하는 애플리케이션과 통신 할 수 있는 터미널 역할을 한다.  


AVR Studio를 이용하여 화면을 띄어보도록 하겠다. 




그리고 hapsim을 띄어보겠다. 



hapsim의 경우는 옵션에서 터미널 세팅의 시리얼 인터페이스를 USART1로 설정하면 알아서 통신한다. 

여기서 USART란 ATmel사에서 사용하는 직렬통신 방법이라고 한다. 


이 문제의 핵심(?)은 패스워드 처리 함수(비교함수 말고)에 대한 역연산으로 

이미 저장된 패스워드(비교대상)를 유추하는 것이다. 


이는 꼭 역연산을 하지 않고 브루트포싱을 해서 풀어도 시간이 오래 걸리지 않는다. 


나의 경우는 역함수를 구현하여 문제를 해결하였다. 

처음에 연산 순서를 역으로 배치하는 것 때문에 무지하게 애먹었다. 


논리상 문제가 없을 것이라고 판단했던 곳에서 문제가 발생하고 있었다. 

역시 내 머리는 너무 믿을게 못된다 -ㅅ-


anyway .. 


문제의 흐름을 간단히 살펴보도록 하겠다. 


이는 각 3단계의 반복문으로 구성되어 있으며 각 반복문에서 패스워드를 꼬아 다음 반복문에 전달하는 식으로 진행된다. 반복문에 전달하기 이전에 구성된 배열을 다시 재배치하는 작업도 진행한다. 


이는 아래와 같다(전체를 나타낸 것은 아님). 



위와 같은 재배치 과정이 끝나면 특정 연산과 함께 XOR를 진행하는데 XOR를 할 값을 구하기 위해 인덱스 값을 구하는 함수를 호출한다. 아래의 캡쳐에는 함수호출 부분이 빠져있다(일부로 뺀 것은 아님..)



패스워드를 변환하는 로직은 마지막 반복문을 빼고 이와 같은 순서를 가진다.

마지막 루프는 단순 ROTATE .. 



이를 쭈우욱 이해하고 역연산 함수를 짜면 패스워드가 나타난다 . 

이 패스워드를 이용해서 조금만 쉘을 가지고 놀면 답을 얻을 수 있다.

 

처음 작성했을 때 몇글자가 자꾸 깨져나와서 머리카락을 다 쥐어뽑을뻔 했는데 

결국 문제점을 찾아서 답을 얻을 수 있었다.


문제를 풀어서 마음이 한결 가벼워졌다. !!!!!ㅎ 


문제풀이 끝!




:
Posted by einai

이 문제는 윈도우 앱을 리버싱하는 문제이다. 


이 문제 하나로 윈도우 앱 분석을 어떻게 해야하는지 알겠다라고 깨닫긴 힘들었지만

그래도 접근은 어떻게 해야겠다 라는건 알았다. 


나중에 시간이 되면 더 깊게 공부해봐야겠다. 할때마다 느끼지만 참 공부란게 끝도 없다. 

그래서 이쪽 일이 재미있는 거지만 하루가 너무 짧다. 이것만 할수도 없고 ㅠㅠㅠ



푸념은 이정도로 하고 문제풀이 들어가보도록 하겠다. 

문제를 동적으로 풀기 위해서는 윈도우 8 이상 앱이 동작할 수 있는 환경을 깔아줘야 한다. 


일단 문제를 다운받으면 읽어달라는 놈을 읽어보자. 



이 시점에는 저게 먼 의미가 있을랑가 ~ 일단 음 저렇구나 하고 넘어가보자. 


환경이 구축되었으면 앱을 실행시켜보자. 




동작화면은 이렇다. 패스워드를 입력하고 "OK" 버튼을 누르면 뭐 옳다, 그르다 이런 팝업이 뜬다. 


사실 앱을 설치할 때 주의해야 할 사항이 있다. 

인증서가 만료되어 신뢰할 수 없기 때문에 파워쉘을 켜서 날짜를 조절해주고 설치를 시작한다.


또한, 신뢰되지 않은 사용자가 게시한 소프트웨어를 실행하기 위해서는 아래와 같이 설정해줘야한다.  

간단히 명령어만 나열하자면, 

 > Set-ExecutionPolicy -ExecutionPolicy Unrestricted 

 (캡쳐를 안찍었는데 다시 찍기는 귀찮다 ㅠㅠ)


이런 일련의 과정을 겪고 나면 위처럼 정상적으로 실행될 것이다. 



만약!!!!! 이 모든게 귀찮다. 

환경 구성도 귀찮고 다 싫다! 하시는 분은 appx 파일의 확장자를 zip으로 변경한 뒤 압축을 풀면 된다. 




그럼 뙇!! 하고 실행파일이 생기는데 이거를 머 IDA로 열어서 확인해보면 된다. 

얼떨결에 만지다보니 파일 시그니처가 압축 파일인 걸 알아서 풀어보니 걍 저렇게 있었다. 


어째든 실제 동작 로직을 찾아가기 위해서는 동적분석이랑 같이 해주는게 편하다(for me). 

아직 익숙하지 않아서 그냥 찾아가기가 복잡스러워보인다. 



분석해야 하는 함수에 맞딱뜨리면 저렇게 기이이인 뭔가가 보기만해도 짜증나게 나타난다.

근데 사실 분석해야 하는 부분은 극도의 일부이다. 저것까지 알려주면 보시는 분의 재미를 빼앗아가는 것 같아 하지 않겠다.


진행하다보면 눈에 보이는 트릭이 존재하는데 알아서 잘 판단하시길 바란다. 

너무 얽매이지 않기를!!






극도의 일부를 분석하고 나면 답을 구할 수 있다. 답을 구할 때 힌트가 유용할 것이다. :) 





드디어 100위권 진입





:
Posted by einai

이번 문제는 ELF 파일구조에 대한 문제였다. 


ELF 파일 리버싱은 익숙하지 않기도 하고, 도대체 익숙한건 뭔지- -,  말로만 듣던 난독화 기법 중 가상머신이 적용된 내용이라 사전학습이 좀 필요했다. 개념을 잡기에 괜찮은 사이트를 하나 발견했는데 아래에 주소를 적어놓았으니 관심있는 사람은 한번쯤 읽어볼만 하다. 


간단히 가상머신 기법에 대한 설명을 하자면,

실행 프로그램안에 별도의 OPCODE를 정의하고 해당 OPCODE가 동작할 수 있는 기반을 마련하여 개발자가 정의한 OPCODE로 프로그램을 동작하는 것이다. 그러기 위해선 일단 사용자가 정의한 OPCODE가 동작할 수 있는 메모리(스택, 레지스터 등)가 필요하고 정의한 OPCODE가 어떻게 동작하는 지에 대한 정의는 필수적이다. 



그럼 문제풀이를 시작하도록 하겠다. 


우선 문제를 동작시키면 아래와 같은 형태로 실행된다. 여러 다른 문제들과 같이 프로그램 내에 정의된 값을 맞추는 것이다. 



내부를 보기 위해 디스에셈블러를 이용하여 한번 열어보았다. 그러니 아래처럼 툴이 정상적으로 캐치를 하지 못한다. 





처음부터 호락호락하지 않은 문제구나 싶었다. :( 

왜 그럴까 싶었는데 프로그램의 EP가 프로그램 헤더에서 정의한 영역을 벗어나서 그런거 같았다. 그래서 현재 EP에 있던 명령어를 실행한 뒤 상태로 만들어놓고 EP를 수정한 뒤 다시 로드하니 아래처럼 인식을 하게 되었다. 




근데 저 위에 로직은 문제 해결에 핵심적인 부분은 아니다. 이는 문제를 생성하기 위한 기반을 만드는 로직인 것 같다. 뭐 메모리를 할당하고 해당 메모리에 별도의 실행 로직을 만들고 파기했다가 어쩌구 저쩌구 한다. 이런저런 행위가 지나고 나면 프로세스는 0x8048000-0x804a000 범위로 IP를 옮기게 된다.  


위에서 언급한 메모리를 덤프떠서 디스어셈블러 툴에서 열어보면 흐름을 파악할 수가 있다. 


대충 핵심만 얘기해보자면 프로세스는 자식 프로세스를 생성하고 생성된 자식 프로세스에서 Input: 에 입력된 값과 OPCODE 셋을 부모 프로세스에게 전달해준다. 이를 전달받은 부모 프로세스는 OPCODE 셋에 특정 연산을 한 뒤 저장하고 이를 활용하여 자신만의 OPCODE를 실행하게 된다. 


아래는 OPCODE 셋이 저장되어 있는 메모리다. 아래의 캡쳐를 간단히 설명하자면 빨간색 박스에 위치한 값이 내가 입력한 값이고 노랑색 박스는 내가 입력한 문자와 추가로 연산이 될 값이 저장되는 위치, 초록색 박스는 실행될 OPCODE의 인덱스(EIP와 같이)가 저장되는 위치이다. 
초록색 박스 뒤에는 연산자와 피연산자가 쭈우우욱 이어져있다. 



아래의 캡쳐는 위의 OPCODE 셋에 정의된 명령어를 실행시키는 반복문이다. 




바로 위 두개의 캡쳐가 이번 문제를 풀기 위한 핵심이다. 위 부분을 잘 분석하면 답을 얻을 수 있다. 



짜잔 ~ 


가상머신 난독화 기법에 대한 개념을 잡아보기에 좋은 문제인 것 같다. 좋은 경험이었다 :)



Reference

[1] Reversing Engineering Virtual Machine Protected Binaries, 

    http://resources.infosecinstitute.com/reverse-engineering-virtual-machine-protected-binaries/

:
Posted by einai
2017. 7. 7. 12:47

[문제풀이] reversing.kr - CSHARP Wargames/reversing.kr2017. 7. 7. 12:47

이번 문제는 닷넷 리버싱 관련 문제이다. 이전에도 닷넷 문제가 있었으나 블로깅은 하지 않았다. 


보통 닷넷 문제는 디컴파일러를 이용해서 문제를 해결한다. 이번 문제도 물론 디컴파일러(JetBrains dotPeek)를 이용했다. 하지만 이번 문제는 디컴파일러로만 해결할 순 없었다. 이와 더불어 디어셈블러(ILDasm.exe), 헥스에디터(Hxd)도 활용했다. 


CSHARP은 여러가지 방법으로 접근해서 문제를 해결할 수 있었다. 


우선 문제가 어떤식으로 출제됬는지 확인한 뒤 다시 논하도록 하겠다. 



프로그램을 실행시키면 위와 같은 화면이 뜨고 문자열을 입력한 뒤 Check를 입력할 경우 "Correct!!" 또는 "Wrong" 팝업을 띄운다. 그럼 디컴파일러를 이용하여 로직을 살펴보도록 하자.


우선 생성자 부분을 확인해보도록 하겠다. 



생성자 부분에서는 "MetMett" 함수 바디에서 MSIL 바이트를 배열 단위로 가져온 뒤 byte[] 에 삽입한다. 그 뒤에 반복문과 특정 값 대입을 실행한 뒤 InitializeComponent 함수를 호출한다. 해당 함수는 화면 구성과 이벤트 핸들러 등록 등 그닥 살펴볼 부분이 없기 때문에 넘어가도록 하겠다. 


MetMett 함수의 몸체는 아래와 같이 디컴파일에 실패한다. 



그 뒤 "MetMetMet" 함수가 존재하는데 프로그램에서 "Check" 버튼을 눌렀을 때 발생하는 함수다. 여기서 어셈블리가 동적으로 생성된다. 닷넷 프로그램에서 사용되는 어셈블리라는 개념은 흔히 사용하는 어셈블리 언어와 개념은 다르나 여기서는 크게 유념치 않아도 될 것 같다. 여기서는 단순히 하나의 동적 함수를 생성한다 정도로만 받아드리면 될 듯 하다(정확한 의미는 아님).



바로 위의 캡쳐를 잘보면 Form1 클래스의 생성자에서 생성된 Form1.bb 배열을 이용하여 메소드를 생성한다. 여기까지만 보면 대충 느낌이 오지 않는가 ?! 


위에서 문제를 풀 수 있는 방법에 대해 언급하다만 내용을 다시 얘기해보겠다. 

크게 두가지 방법으로 접근해서 해당 문제를 해결할 수 있겠다. 


첫 번째, MetMett 함수의 hex 값을 가져와서 수동으로 변조한 뒤 바이너리 파일의 hex 값을 덮어쓰는 것 

두 번째, 디버거를 이용하여 동적 어셈블리가 생성되어 호출될 곳에 BP를 걸고 분석하는 것 


각 방법에 대한 자세한 방법은 따로 기재하지 않겠다. 


우선 첫 번째 방법을 이용하여 hex 값을 수정한 뒤 디스어셈블러를 이용해 불러보면 아래와 같이 나타난다. 



그리고 두번째 방법을 이용하여 접근했을 경우는 이렇다. 



문자열 비교 로직은 여지껏 진행해 온 문제들과 다르지 않다. 한가지 정도 다른데 다들 눈치챘을거라 생각하고 ~슥 





빠밤~~ 미션 컴플릿 !!

:
Posted by einai
2017. 7. 7. 12:46

[문제풀이] reversing.kr - Lotto Wargames/reversing.kr2017. 7. 7. 12:46

이번 문제는 64비트에서 실행되는 것 외에는 특별한게 없었던 문제였다. 


문제를 풀기 전에 알아야 할 건 64비트에서는 어떻게 함수에 파라미터를 전달하느냐 정도이다. 64비트 프로그램은 기존 방식과 다르게 총 4개의 레지스터를 사용하여 파라미터를 전달하고 그 이상 파라미터가 존재할 경우 스택을 이용한다. 


사용되는 레지스터 (순차적으로)

 - 정수형 : RCX, RDX, R8, R9 

 - 실수형 : XMM0, XMM1, XMM2, XMM3



그럼 문제풀이를 진행해보도록 하겠다. 


문제는 문제 이름을 보면 알수있듯이 랜덤으로 생성되는 6개의 수를 맞추는 것(또는 우회)이다. 

그럼 퀵하게 한번 보도록 하겠다. 


우선 문제를 시작하면 아래와 같이 동작한다. 여기서 숫자는 내가 임의로 입력한 값이다. 



로직을 살펴보도록 하겠다. 아래 보이는 부분은 wscanf_s 함수를 호출하는 부분이다. 

특별한 건 없고 어디에 내가 입력한 값이 저장되는지 정도만 확인하고 넘어가자.



아래 캡쳐는 6개의 수가 어떻게 생성되는지 나타낸다. rand 함수를 호출하고 곱셈, 쉬프트 연산 등등을 이용해서 값을 생성해낸다. 



아래 부분은 단순히 내가 입력한 값과 바로 위에서 생성된 값을 비교한다. 총 6번 비교를 진행한다. 



머 어찌저찌 위 비교 로직을 통과하게 되면 문제에 대한 해답을 나타내주는 부분이 진행된다. 

여기선 따로 분석을 진행하지 않겠다.



위 부분이 쭉쭉 지나고 나면 답을 출력해준다. 



Clear!

:
Posted by einai

음 이번 문제는 못풀었다고 보는게 맞다. 


문제 초기에 완전 혼자 딴 생각에 빠져서 삽질만 겁나 하다가 지쳐서 검색했다. 

나는 왜 이것을 키젠 문제라고 생각했을까 ? ㅠㅠ


문제에 원본 프로그램과 패킹된 프로그램 두개를 떡하니 넣어놓고 

패커 탐지툴도 탐지했었는데 패스워드 체크란 타이틀만 보고 덥석 패스워드 푸는것만 생각하고

다른 생각을 아예 하지 못했다. 원래 입력된 값을 어떻게 추측할 수 있을까만 내내 고민했다.


좀 더 다양한 측면에서 생각할 수 있도록 하자. !!


고로, 이번 문제는 문제풀이 대신 참고한 사이트를 게시하도록 하겠다. 



thx to http://revers3r.tistory.com/9 

:
Posted by einai

이번 문제는 이전에 푼 AutoHotkey1 문제와 유형이 다른 문제였다. 


인터넷에서 알아보니 오토핫키 프로그램은 컴파일 시 자동으로 UPX 패커를 적용시킨다고 나와있었다. 

근데 내가 테스트해봤을 땐 자동으로 패킹되진 않았다(옵션이 있나,, 아님 수동으로 적용시키는건가,,).  


어째든 이번 문제는 오토핫키 실행파일이 정상적으로 작동되지 않는 걸 동작시키는게 목표다. 우선 문제를 다운받아 압축을 풀어보자. 



이번에도 실행파일과 나를읽어 파일로 구성되어 있다. 

나를 읽어 파일을 읽어보자. 



동작하기 위해선 수정을 해야한단다. 우선 동작시켜보자 !! 



음.. 사실 이 에러는 이전에 AutoHotkey1 문제에서 언패킹을 한 뒤에도 동일하게 나타났던 현상이다. 그땐 문제를 해결하는데 언패킹이 필요가 없는 걸 깨닫고나서 더 이상 알아보지 않았다.  

근데 이번 문제는 그냥 실행하자마자 이 화면이.. 그리고 이것을 해결해야 답을 알수있으니.. 어쩔수 없이 분석을 진행해야했다. 



에러를 발생시키는 곳을 찾아가는 것은 어렵지 않으니 생략하도록 하겠다. 

아래 캡쳐는 문제가 발생되는 곳을 그래프로 표현한 것이다. 



처음엔 그냥 대충대충 분석안하고 플래그 변조나 하면서 지나갔는데 에러가 발생했다. 

역시 제일 빠른 건 차근차근 원인을 분석하는 것이었다. 어차피 결국 분석할테니까... ㅠㅠ 



위 구문을 봐서 알겠지만 함수명이 표현되지 않는다. 

추측인데 특정 함수를 인라이닝해서 컴파일해서 그런 것 같다. 


다행스럽게도 아이다님께선 함수를 알고 계셨다. 


어째든 여기서 사용되는 몇몇 함수는 파일 관련 함수였다. 읽고 위치 변경하고 하는.. 

조금 내려가다보면 프로세스에서 어떤 값을 저장한다. 이것도 역시 나중에 나를 물맥이려고 하는 수작이다. 



0x10 크기만큼 어떤 값을 가져와 어떤 위치에 저장한다. 

그리고 이어서 ~ 



우선 파일의 위치를 변경하고 특정 값을 읽어온다. 위에서 읽어오는 값이 이후에 비교될 값의 대상이 된다. 게다가 읽어온 값이 어떠냐에 따라 프로세스가 뻗어버리던지 돌아가던지 한다. 음음. 



여기서는 파일을 무결성을 검증하기 위한 값을 만든다. 간단하게 말하면 파일의 값을 가져와서 XOR 연산을 한뒤 위에서 읽어온 값 중 하나와 비교한다. 여기는 뭐 그냥 쩜프만 뛰어도 충분하다. 



그 다음에 위에서 0x10 크기만큼 가져온 값과 파일의 내용을 참조해서 비교한다. 

0x10 크기만큼 다 맞으면 통과 !! 위에서 힌트가 있으니 이 값만 맞추면 왠만하면 문제없이 동작할 것이다.


하지만 동작한다고 해서 끝이 아님!!

이번엔 동작한 프로그램에서 문제가 나타난다. 

인터넷 검색하니까 금방 답이 나오긴 했지만 :) 


어째든 동작한 프로그램은 이렇게 생겼다. 



끄으으읏!!


:
Posted by einai

이 문제는 블로그에 안쓸까 했따. 


문제 의도만 알아채면 어렵지 않은 문제라, 

사실 다른 분들이 만들어놓은 디컴파일러 때문에 쉽게 풀렸다고 보는게 맞겠다. 


우선 AutoHotkey 가 무엇인지 알아보자. 


AutoHotkey ?

AutoHotkey는 매크로를 오픈소스 프로그램이다. 이를 이용하면 반복적인 작업을 간결하게 만들 수 있고 각종 단축키를 지정할 수 있다. 이를 스크립트로 이용할수도 있고 컴파일해서 실행파일로 변환하여 사용할 수도 있다. 


간략히 이정도만 알아보고 문제풀이에 들어가겠다. 


일단 문제를 다운받아 압축을 풀면 아래와 같은 구성으로 되어있다. 






나를읽어.txt 파일을 읽어보겠다. 



어떤 해쉬 값의 원래 값을 알아내서 조합하는 게 이 문제의 답이다. 


하지만 어떻게 알아낼까 ?! 원래 해쉬 함수는 함수의 출력 값을 이용해서 입력 값을 알 수 없는 법이다. 하지만 일부 사이트에서 다량의 해쉬 함수의 결과 값과 입력 값을 수집하여 매핑시켜 놓고 검색을 허용해준다. 아마 이 문제도 그걸 노리는 것 같았다. 사실 이 느낌 반과 다른 트릭이 있을 거 같단 느낌 반반이었다.  그래서 약간의 삽질 좀 했쥐..


우선 나도 오토핫키를 처음 봐서 DecryptKey가 뭔지 몰랐다. 또한 Exe's Key 도 무슨뜻인지 단번에 와닿진 않았다. 

어째든 오토핫키에 대해 검색을 하다보니, 오토핫키를 컴파일하는 과정에 패스워드를 입력할 수 있고 이를 이용하여 무분별한 디컴파일을 막는 것 같았다. 하지만 입력한 패스워드가 평문으로 저장되고 찾기가 용이한 듯 보였다(실제 분석하진 않았음). 



주저리 주저리 떠들다 보니 문제 실행 사진을 안올렸군...

문제를 실행했을 때는 아래와 같다. 




What a simple window..


어째든 , 이를 디컴파일할 수 있는 툴이 인터넷에 돌아당기고 쉽게 찾을 수 있땅.

또한 패스워드를 입력하지 않아도 자동으로 패스워드를 검출해주고 디컴파일까지 해주는 프로그램도 존재한다.


어째든 해당 툴을 이용하면 패스워드가 노출되고 이 값이 DecryptKey 가 된다. 

그리고 디컴파일되면 간단한 해쉬값이 나오는데 이 값이 Exe's Key 값이 된다. 


해당 해쉬 값들을 해쉬 함수 검색 사이트에서 검색하면 금방 해쉬 함수의 입력 값을 찾을 수 있다. 

처음에 시도한 해쉬 함수 검색 사이트에서 찾아내질 못해서 괜히 딴생각하고 삽질했었음..ㅠㅠ


이렇게하면 게임 클리어!!

:
Posted by einai