프로그램을 실행하면 옳은값이 아닐경우 프로그램이 멈춘다. 


문제명도 그렇고 이부분에서 프로그램이 멈추는것도 그렇고 뭔가 어셈블리어를 매우 자세히 봐야할거 같은 느낌이 들었다.



입력을 받고 처리하는 부분도 IDA로 보았을때 역시나 완벽한 디컴파일이 안된다.



IDA 기능인 assembly graph view기능을 통해 보았을때 성공 메시지를 띄워주는 부분으로 점프하는 부분이 없다.


이부분에서 감이 매우안와서 고생했다.



GetDlgItemInt함수를 통해 input값을 eax에 저장하고 함수를 호출한후에 검증한다.


설명부터 하자면 401071의 점프하는 부분을NOP로 맞춰줘야 한다.


일단 내가 입력한 input값을 가지고 연산을 하는데 4084D0에 내가 입력한 값이 저장된다. 



그후에 0x601605C7을 더해주고 INC연산을 4번 더해서 총 4를 더해준다.



여기서 100401071이 중요하다. 


이 값은 위에서 점프하는 부분을 nop로 만들어주는데 밑의 사진이 바로 그부분이다.



eax에 있는 값을 두번 0x90으로 바꿔주는데 공교롭게도 위에서 우리가 nop로 바꿔줘야할 코드가 2byte이다.


즉 내가 입력한 값에 4를 더해주고 0x601605C7을 더한 값이 100401071이 되어야 하고 바이트 포인터이니까 401071이 된다.


이부분에 90을 두번 넣어주므로 결국에는 어셈블리어를 변경하는 셈이다.



식을통해 산출한 input값을 입력한후 디버깅하면 연산후에 점프하는 어셈블리어가 nop로 바뀌어있다.


입력을하면 성공메시지가 뜬다.




이문제는 문제를 만든사람도 참신하다는 생각이들고 이런식의 리버싱문제를 처음접해봐서 신기했다.


확실히 어셈블리어만 보고 리버싱하는 연습이 매우 필요할거같다.


'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr ImagePrc  (0) 2017.01.23
Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04


프로그램을 실행시키면 그림을 그릴수 있고 check 버튼을 누르면 wrong이라고 메시지 박스가 출력된다.



위 코드가 check버튼을 누르면 실행되는 코드이다.


코드를 보면 현재 내가그린 그림과 리소스에 저장된 이미지를 가져와 바이트단위로 비교를 한다.


즉 바이트 단위까지 맞춰서 그림을 똑같이 그려야 wrong 메시지가 뜨지 않을것이다.


상식적으로 불가능 하다.


첫번째로 생각한것은 리소스를 뽑아와 실제 이미지로 만들어서 보는것이고 


두번째로 생각한것은 메시지루프에서 윈도우메시지가 wm_create일때 즉 윈도우가 생성될때 아예 리소스를 띄워주는 것인데


두번째 방법은 함수조사도 해야하고 첫번째 방법이 더 빠를거 같아서 첫번째 방식을 택했다.



pe뷰어를 통해 보면 리소스 섹션에 비트맵형식의 리소스가 있다.


파일 시그니쳐 및 파일 헤더가 없기 때문에 긁어와도 온전한 이미지 파일이 되지 못할것이라 생각했다.



먼저 실행파일 내에 리소스를 뽑아주는 툴을 통해 리소스를 뽑았다.



헤더 없는 리소스가 뽑혔다.


이제 비트맵 이미지 헤더를 위에 만들어주면 될거같다.


비트맵 이미지 구조를 외우고 있는 사람은 없을것이기 때문에 나도 검색을 해봤다.


비트맵 이미지의 기본 구조는 크게 파일헤더,이미지헤더,컬러테이블,픽셀테이블로 이루어진다고 한다.



먼저 파일헤더이다.


빨강 : 파일 타입 정보


노랑 : 파일 크기


파랑 : 예약 영역(임시 할당)


검정 : 헤더의 크기



다음은 이미지 헤더이다.


빨강 : 이미지 헤더크기 (최소 40byte)


보라 : 이미지의 폭, 이미지의 높이


분홍 : 비트 플레인 수(현재 지원값은 1이라고 해서 1로 했음)


갈색 : 비트수 (16비트,24비트 비트맵 등이 있는데 구글 따라 24로 해봤음)


검정 : 압축타입(압축되지 않았음)


노랑 : 이미지 파일 크기(헤더크기를 제외한 순수 이미지 파일의 크기)


초록 : 무엇인지는 모르겠으나 0으로 채워져있음(마찬가지로 구글따라...)






위처럼 헤더를 생성해주고 비트맵 파일을 생성하면



하얀 바탕에 검정색 글씨가 쓰여있다.


이게 플래그인데 뭔지 공개하면 안되니까 빨강색으로 지워주었다.





'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Replace  (0) 2017.01.23
Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04


파일을 받으니 실행파일과 영문모를 파일 그리고 readme가 나온다.




readme를 읽어보니 실행파일을 복호화 하라고 한다.


실행파일을 통해 암호화된 file을 복호화 하는 문제같다.



이 실행파일은 키값을 입력하면 키값에 따라 file이 바뀐다.



file을 Hxd로 열어봤는데 이렇게 나온다. 


readme에서 file은 pe파일 이라고 했으므로 파일 시작부분이 MZ로 바뀌도록 복호화 하면 될거같다.





upx패킹을 풀어주고 복호화 해주는 실행파일의 메인함수를 보니 리버싱을 방해하기위해 의미없는 명령어를 매우 많이 넣어놨다.


따라서 아이다로 디컴파일이 불가능하다.



string검색을 통해 실행이 시작되는 부분으로 왔다. 


key를 입력받는다.



그 후에 file을 오픈한다.


file을 오픈해서 file을 한 바이트씩 받아와 key값과 간단한 연산을 통해 file을 변경시킨다.


밑은 연산하는 부분이다.



연산하는 부분을 분석해 보니 xor연산 두번이 끝이다.......


분석결과 키값^file^0xFF=복호화될값 이렇게 된다.


즉 내가 abcd를 키값으로 설정했으면


file의 첫번째 바이트가 0xDE였으므로 


0x61^0xDE^0xFF=0x4D 가 되야한다.


이런식으로 키값을 찾아가다보면 파일의 크기만큼 키값을 받는건 절대 아닐거라 생각하고,


분명히 키값을 반복해서 사용할거라 생각해서 수작업으로 키값이 반복될때까지 키값을 추측해보았다.



이러한 문자열이 나오고 이 문자열들이 계속 반복되는것을 보아 letsplaychess라는 키값을 얻을수 있었다.


이 키값을 통해 file을 복호화 하니 실행파일로 우리가 자주보던 PE구조를 가진 파일의 형태를 볼수있었다. 




확장자 EXE를 추가해주고 파일을 실행해 보려 했으나 DLL이 없다면서 실행되지 않았다.


역시나 이 실행파일 역시 upx패킹이 되어있어 풀어주고 디컴파일을 해보니 Key를 출력해보는 부분을 찾았다.



'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Replace  (0) 2017.01.23
Reversing.kr ImagePrc  (0) 2017.01.23
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04


문제 이름에서도 알수있듯 이 파일은 PE32+  즉 윈도우 64비트 실행파일이다.


올리디버거 peviewer peid 등 대부분의 프로그램이 32비트 파일에 맞춰 나오므로 IDA를 통해 분석할 수 밖에 없었다.




먼저 실행을 시키면 숫자를 입력받는다.




소스를 보면 먼저 무한루프 아닌 무한루프를 도는데 6개의 랜덤값을 생성하고 입력값과 모두 일치하면 반복문을 빠져나간다.


v5는 1인 상태로 빠져나간다.


빠져나간뒤 하는 일을 보니 FLAG를 출력해주는 루틴같다.


루틴을 자세히보니 미리 선언해 놓은 값들을 연산해 플래그로 만드는 작업같다.


굳이 랜덤값 6개를 맞출 필요없이 위의 반복문만 빠져나가면 될거같다.


중요한건 밑에서 v5가 참일때 플래그를 출력해주는데 이부분도 반복문 빠져나가듯이 우회하면 될듯하다.


사실 플래그 출력해주는 부분은 선언해놓은 값들을 연산하는 부분이므로 간단한 코딩을 하면되긴 하는데 


나는 32비트 환경이라 64비트 환경에서 연산하면 값이 달라질거 같기도 해서 디버깅으로 풀기로 했다.


IDA로 디컴파일이 되니까 디버깅도 될거같았는데 IDA에서 쓰는 64비트 디버거를 어떻게 설정해주는지 모르겠어서 64비트 디버거를 찾아보기로했다.


구글링을 해보니 x64dbg라는 디버거를 찾았다.



먼저 cmp edx,6 부분을 우회해야 하는데 이부분은 반복문을 빠져나가는 부분이다.


rdx를 6으로 바꿔주면 빠져나간다.



test r8b,r8b 이부분은 위에서 v5가 참이냐 거짓이냐를 따지는 부분인데 r8 레지스터값을 1로 변경해주면 마찬가지로 우회가 된다.


두 부분을 우회하고 나니 플래그가 출력된다.




'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr ImagePrc  (0) 2017.01.23
Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04
Reversing.kr Position  (0) 2016.09.30


실행파일과 readme를 준다. password를 찾으란다. 실행시켜보니 실행은 되지않고 무슨 파일인지 보니 mac os-x arm 환경에서 만들어진 파일이다.


현재 ARM 환경을 구축해놓은 서버가 없어서 일단 아이다로 보았다.



correct key! 라는 문자열이 있으니 따라가 보았다.



ARM 어셈블리어로 보여지는데 문법을 모른다.


그러나 IDA로 디어셈블링이 되기때문에 문제푸는데 문제는 없어보인다.



처음에 입력을 받고 sub_232c ()함수를 호출한 뒤 입력한값을 어떠한 배열과 비교한다.


당연히 sub_232c() 함수에서 입력한 문자열이 바뀔거라 생각하고 sub_232c() 함수를 분석했다.



sub_232c() 함수를 통해 연산이 끝나고 아래의 배열로 내가 입력한 문자열이 바뀌어야 한다.



반복문을 통해 각종 연산을 한다.



뭐 분석할 필요도 없이 코드도 짧고 연산도 간단해 brute forcing을 하면 될거라 생각했다.


입력값의 범위는 키보드로 입력할수 있는 아스키값들이다.


이 값들중 연산을 거쳐 위의 비교하는 배열과 맞으면 된다.



간단한 코딩을 통해 내가 입력해야 할 값이 나왔다. 비록 원본파일을 실행은 시키지 못하지만 인증하니 성공했다.





문제 이름부터 알수 있듯이 이 문제는 ARM 아키텍처를 이해하고 있는가에 대한 문제이다.


Intel 과 AT&T syntax에만 익숙해 있던 나에게는 공부없이 못풀 문제였지만  고급툴  IDA 통해 쉽게 풀었다.


안드로이드도 ARM 으로 구성되있기 때문에 시간될때  ARM 아키텍처에 대해 공부해야겠다는 필요성을 느꼈다.

'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr Music Player  (0) 2016.10.04
Reversing.kr Position  (0) 2016.09.30
Reversing.kr Direct3D FPS  (0) 2016.09.01


문제를 보면 음악 플레이어를 주는데 1분 이상은 못듣게 되있다. 1분이상을 듣도록 하면 플래그가 나온다고 한다.



일단 메시지 박스를 띄우길래 메시지 박스를 띄우는 곳으로 가보니 윗부분에 0xea60과 비교를 하는 부분이 보인다.


0xea60은 10진수로 60000이기 때문에 이부분이 1분을 limit 걸어놓는 부분이라는 것을 알 수 있다.


그러므로 cmp eax,0ea60h를 cmp eax,2ea60h로 패치했다.



실행 시켜보니 에러가난다.



이유가 뭘까하고 디버깅 하면서 삽질 하다가 밑줄친 함수에서 프로그램이 비정상종료된다.


test eax,eax 부분에서 eax가 0이면 함수를 실행시키지 않고 다른부분으로 점프되니까 eax를 0으로 맞춰주도록 프로그램을 패치했다.



최종적으로 총 2부분, 60000을 충분히 키워주고 sub eax,eax로 eax를 0으로 맞춰주도록 패치했다.



실행해보니 1분이상 음악듣기가 가능해졌고 프로그램 타이틀에 플래그가 뜬다.


1분이상 못듣는 음악 플레이어를 크랙한것이다.


확실히 비쥬얼 베이직으로 만들어져서 한번도 코딩해보지 않은 언어라 분석하기도 좀더 껄끄럽고 짜증났다.



'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Position  (0) 2016.09.30
Reversing.kr Direct3D FPS  (0) 2016.09.01


readme.txt를 읽어보면 시리얼값이 76876-77776일때의 password를 구하라고 한다. 그리고 password의 마지막 값은 'p'이다.



실행해보니 Wrong이라고 나와서 Wrong을 출력해주는 부분을 찾아가 보았다. 시리얼값의 포맷은 xxxxx-xxxxx이다.




sub_401740 함수의 리턴값이 1이면 Correct를 띄워줘서 sub_401740 함수를 분석해 보았다.




제일 처음에 필터링 하는 부분은 password값이다. 4글자여야 하고 알파벳 소문자여야 한다.


그리고 본격적으로 password값을 연산해  시리얼값을 만들어낸다.


먼저 생소한 함수를 찾아보았다.


GetAt(char* a1, int a2) : 문자열 a1의 a2번째 인덱스의 값을 반환해 준다.

 

먼저 if문으로 값을 검증하는 루틴 10개가 있다. 시리얼 값도 '-'를 제외하면 10자리 이므로 이부분에서 시리얼 값을 만들고 비교한다는것을 알았다.


v61은 password이므로 한자리씩 갖고와서 shift연산, and연산등을 통해서 내가 입력한 시리얼 값과 비교를 한다.


예를들어 if(v13==v12) 이부분은 v12는 내가 입력한 시리얼값의 첫번째 인덱스, v13은 password를 연산해 나온 시리얼 값의 첫번째 인덱스이다.


이런식으로 10자리가 전부 맞아야 1을 반환해준다.


password : xxxx

serial :xxxxx-xxxxx


크게보면 password값 1,2,번째 값을 통해 시리얼값 '-' 앞부분 5자리를 만들어내고 password값 4,5번째 값을 통해 시리얼값 '-' 뒷부분 5자리를 만들어 낸다.


연산하는 부분을 참고해 코드를 짜보았다.






어떤 사람이 bruteforce 해주는 툴을 만들었다.


아직 핸들, 윈도우메시지등 win32 api는 생소하니 좀더 공부해본후 내가 직접 만들어야 할거같다.



#include <iostream>
#include <Windows.h>
using namespace std;
void bruteForce(HWND hwndName, HWND hwndOutput)
{
   wchar_t inputName[5] = L"xxxp";
   wchar_t output[10];
   cout << "Correct Names:" << endl;
   for (int i = 0x61; i < 0x7B; i++)
      for (int j = 0x61; j < 0x7B; j++)
         for (int k = 0x61; k < 0x7B; k++)
         {
            inputName[0] = i;
            inputName[1] = j;
            inputName[2] = k;
            SendMessage(hwndName, WM_SETTEXT, 0, (LPARAM)inputName);
            SendMessage(hwndOutput, WM_GETTEXT, 10, (LPARAM)output);
            if ((char)output[0] != 'W')
               wcout << inputName << endl;
         }
}
int main() {
   cout << "##############################################"<< endl << endl;
   cout << "[Reversing.kr] Position Bruteforcer" << endl;
   cout << "by 거북찡 http://blog.naver.com/7005ye" << endl << endl;
   cout << "##############################################" << endl << endl;
   HWND hwnd;
   wchar_t serial[12] = L"76876-77776";
   if ((hwnd = FindWindow(NULL, L"Position")) != NULL)
   {
      HWND hwndName = FindWindowEx(hwnd, NULL, L"EDIT", NULL);
      HWND hwndSerial = FindWindowEx(hwnd, hwndName, L"EDIT", NULL);
      HWND hwndOutput = FindWindowEx(hwnd, NULL, L"STATIC", NULL);
      SendMessage(hwndSerial, WM_SETTEXT, 0, (LPARAM)serial);
      cout << "Bruteforcing for serial# "; wcout << serial << endl;
      bruteForce(hwndName, hwndOutput);
   }
   else
      cout << "Position 캡션 감지 실패. 프로그램을 종료합니다" << endl;
   system("PAUSE");
   return 0;
}

출처 : http://blog.naver.com/7005ye/220690081917


'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04
Reversing.kr Direct3D FPS  (0) 2016.09.01


먼저 실행을 하니 몬스터들이 있고 몬스터들을 만나면 HP가 0이되어 죽는다.



IDA를 통해 문자열들을 보니 Game Clear라는 문자열을 발견했고 그 문자열이 사용되는 함수를 찾아보았다.




이 함수로 들어가면 조건이 맞을 때 MessageBox함수를 호출하는데 디버깅을 통해 강제로 메시지 창을 띄우니 이렇게 나왔다.




이상한 값은 IDA를 통해 봤을 때 &byte_407028에 있는 문자열인데 강제로 메시지 박스를 띄웠기 때문에 이런식으로 나온다 생각했다.


옳은 방법을 통해 일정 점수를 넘겼을 때 &byte_407028의 문자열이 연산을 통해 바뀔거라 생각했고 &byte_407028의 문자열이 사용된 부분들을 찾아봤다.



메인함수에서 이 함수를 호출 하는데 조건에 만족할때마다 XOR연산을 통해 문자하나씩 바꿔준다.


디버깅을 통해 이 함수에 브레이크 포인트를 걸고 함수를 실행해보니 



이 문자들과 0에서 부터 시작해 4씩 증가되면서 XOR연산을 하는것을 발견했다.








'문제 > Reversing.kr' 카테고리의 다른 글

Reversing.kr Ransomware  (0) 2017.01.21
Reversing.kr x64 Lotto  (0) 2016.10.06
Reversing.kr HateIntel  (0) 2016.10.05
Reversing.kr Music Player  (0) 2016.10.04
Reversing.kr Position  (0) 2016.09.30

+ Recent posts