문제를 보니 4글자의 NAME을 찾는 문제이다.


정답이 여러개인거 같은데 그중 숫자 소문자 대문자 순으로 가장 먼저오는 문자열이 정답인가보다.






바로 디컴파일 해보니 각설하고 name과 serial을 받아 check_serial함수에 인자로 넘겨줘 함수가 return 1을 하면 옳다고 나온다.


check_serial함수만 보면 끝날듯하다.



C++ STL을 사용해 구현한 프로그램이라 분석하는데 꽤 오래 걸렸지만 


밑줄친 stringFindSecond함수를 두번 호출하고 값을 뺀 절대값이 5보다 같거나 작으면 된다. 


함수 끝마칠때 v28을 리턴해주는데 저 조건문으로만 들어가지 않으면 v28은 원래 선언된 1 그대로 리턴된다.


반복문은 총 12번 돌아가는데 serial값의 길이만큼 돌아가며 name 한자리씩 가지고와 serial을 생성한다.


먼저 StringFindSecond(char* a,char b)함수는 사용자 정의함수인데 a라는 문자열에서 b라는 문자가 2번째로 나오는 인덱스를 리턴해준다.


두번의 호출에서 v30이라는 문자열을 인자로 넣어주는데 string으로 밖혀있는 밑의 문자열이다.



v9는 내가 입력한 serial이고 v8은 내가 입력한 name이다.


반복문이 12번 돌기 때문에 내가 만약 name을 abcd로 입력했다면 AAABBBCCCDDD 그리고 입력한 serial값 12자리를 가지고 검증을 한다.


여기서 소문자로 입력한다면 v30의 문자열에서는 대문자로 변환되어 검색한다.


검증 루틴을 분석했으니 간단한 brute forcing을 이용한 코드를 짜보았다.




문제에서 숫자 소문자 대문자 순서중 가장 먼저 오는 문자열이 답이라고 했으므로 가장 먼저오는 문자열을 출력해보았다.







'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 09  (0) 2017.01.10
CodeEngn Advance 08  (0) 2017.01.10
CodeEngn Advance 07  (0) 2017.01.10
CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10


문제에서 password를 찾으라고 해놓고 이름을 알려주지 않아서 일단 아무값이나 넣고 디버깅 해보았다.



디버깅하다보니 DonaldDuck이라는 문자열과 내가 입력한 name을 비교한다


NameDonaldDuck이 되어야 한다.



이름을 다시 입력하고 패스워드를 1234로 입력해보니 1234 16진수 4d2 특정값을 비교한다


특정값을 10진수로 바꿔인증해보니 인증이 되지만 성공 메시지를 띄울라면 아예 프로그램을 패치해야 한다.


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 10  (0) 2017.02.07
CodeEngn Advance 08  (0) 2017.01.10
CodeEngn Advance 07  (0) 2017.01.10
CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10


디버깅을 해보려고 아무값이나 입력을했더니



3자리 이상이여야 한다고 해서 cmp eax,2로 실행파일을 바꿨다.



메시지 창을 띄우기전 조건을 보니 입력한 이름으로 만들어진 키값과 내가 입력한 키값을 비교해서 성공메시지를 띄울것인지를 판단한다.



중단점을 함수두개를 걸었는데 분석 결과 밑의 함수는 문자열을 비교해주는 함수이고 


위의 함수가 name을 가지고 키값을 만들어 주는 함수이다.



함수를 분석해보면 크게 4개의 연산 과정이 있는데



‘ – ‘ 문자를 기준으로 5자리로 나뉘는데 각 자리를 산출해내는 연산을 한다.


 3번째 연산 과정은 3,4번째 자리를 같이 산출하는 것 같다.


Name 2글자라고 했고 2번째 연산과정이 가장 짧고 코드로 구현하기 쉬워서 


2번째 연산 과정을 숫자와 알파벳 대소문자 조합을 통해 name을 만들어 코딩해봤다.




2번째 자리는 53b4가 되야하는데 연산을 해서 앞 4바이트를 가져오기 때문에 


53b4000~53b4999까지의 결과가 나오는 값들을 출력해 보았다.


출력된 값중 하나를 입력하니 인증이 되었다.

'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 10  (0) 2017.02.07
CodeEngn Advance 09  (0) 2017.01.10
CodeEngn Advance 07  (0) 2017.01.10
CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10


실행파일을 peid로 열어보니 c#으로 만들어졌다는걸 알았고 c# 디컴파일러인 reflector를 사용해 분석했다.



먼저 실행시키면 키값은 16진수로 이루어져있다는 것을 알수있다


실제로 16진수 이외의 문자 (0~9,a~f가 아닌 문자)를 입력하면 프로그램에서 오류가 난다.



먼저 이과정에서 GetHashCode함수는 32bit 64bit 운영체제에서 다르게 해시값을 생성한다는 것을 알고 window7 32bit를 설치했다.


문제하나 풀라고 운영체제까지 설치했던 첫문제여서 기억이남는다.


코드를 보니 vxzzz함수를 통해 yreeeerwww의 값이 바뀌고 fsfsdf는 우리가 찾아야 하는 키값에 의해 결정된다.


vxzzz함수를 분석해보았다.



도저히 루틴을 복호화 할 자신이 없어서 브루트포싱 하기로 결정했다.



vxzzz함수에서 자료형이 unsigned int 이기 때문에 언더플로우가 발생해서 프로그램 실행시간이 매우 길어질것을 감안하여 


일단 언더플로우가 발생할 수는 아예 생략했다. 이부분은 내가 코딩을 잘 못해서 어쩔수 없는 선택이였다.


만약 언더플로우가 발생하는 수가 정답이였다면 못풀었을지도 모른다.


0~ffffffff까지 브루트포싱 했다.



거의 3억에 가까이 가서 키값이 나왔다. 두시간 돌렸다.


이부분도 내가 코딩을 잘 못해서 알고리즘을 공부했다면 좀더 효율적으로 프로그램을 짜 실행시간을 줄일수도 있었을지 모른다.



키값으로 나온 10진수를 16진수로 바꿔 인증하면 맞았다고 나온다.




//비쥬얼 스튜디오 없이 c#소스인 .cs파일을 컴파일 할 때


 C:\Windows\Microsoft.NET\Framework64\v4.0.30319 에 있는 csc.exe를 이용해 javac.exe로  자바 컴파일 하듯이 컴파일 하면됨.

'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 09  (0) 2017.01.10
CodeEngn Advance 08  (0) 2017.01.10
CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10


먼저 실행을 해보니 확인을 누르면 숫자가 올라가면서 특정 수에서 끝난다.


정답은 나왔지만 분석을 해보았다.



먼저 안티디버깅이 되어있어 eax 0으로 바꿔주며 풀었다.



이부분에서 숫자를 카운트 해준다 eax에는 원래 숫자가 카운트 되는 숫자가 있고 edi에는 1이 있다. 즉 하나씩 올려준다.



그리고 위에서 올린 값을 어느 변수(임시적으로 비교하기 위해 사용하는 변수로 생각됨)에 저장하여



어떤 헥스값과 비교한다. 조건에 부합하면 계속 진행되고 특정값 보다 커지면 프로그램이 종료된다.


어거지로 디버깅하며 카운트 되는 변수의 위치와 비교하는 부분을 찾았지만 프로그램 전체에 대한 루틴 분석은 아직 안된다


아는형이 일병 때 못 풀고 병장 때 다시 풀었다 했는데 나도 1년 뒤에 다시 봐야겠다


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 08  (0) 2017.01.10
CodeEngn Advance 07  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10
CodeEngn Advance 03  (0) 2017.01.10


먼저 1234라고 입력을 해보니 mal cracker!!!라고 나오고 메시지 창이 뜬다.


옳은 시리얼 값이 아닌거 같다.



문자열을 찾아보니 옳을 때 출력될 것으로 보이는 문자열은 보이지 않고 옳지 않을때 출력되는 문자열만 보여서 일단 중단점을 걸어준다.



다시 실행을 해보니 중단점을 건 곳에서 한번 멈추고 윗부분을 분석해보니 딱히 단서가 될만한 것을 찾지 못했으나



조금 더 윗부분을 보니 strcmp함수를 호출하는 부분이 보인다. 이 부분에 중단점을 걸고



다시 실행을 시켜보니 내가 입력한 1234  특정값을 비교한다.



맞았다고 한다.


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 07  (0) 2017.01.10
CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10
CodeEngn Advance 03  (0) 2017.01.10
CodeEngn Advance 02  (0) 2017.01.10


먼저 문자열들을 살펴보니 아무것도 없어서 이상하다 생각했다.



코드가 깨져있는것을 확인하고 제대로 코드를 다시 가져왔다.



그리고 다시 문자열들을 살펴보니 invalid serial이라고 내가 옳지않은 시리얼을 입력했을 때 출력되는 문자열을 확인해서 


중단점을 걸고 그 코드 주변으로 가서 살펴보았다.



위를 보니 인자 값 두개를 strcmp하여 타당한지 아닌지를 검증하는 부분이 있다


내가 입력한 값과 name에 의하여 생성된 시리얼 값이라고 생각했다.



nameCodeEngn 시리얼에는 무작위로 값을 넣고



중단점을 걸어보니 생성된 시리얼 값이 나왔다.



시리얼이 옳다고 나온다.




'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 03  (0) 2017.01.10
CodeEngn Advance 02  (0) 2017.01.10
CodeEngn Advance 01  (0) 2017.01.10


먼저 문자열들을 보니 성공했을 때와 실패했을 때 출력할 것으로 보이는 문자열들을 보았다. 이 부분에 중단점을 걸고



이름은 CodeEngn을 시리얼에는 무작위로 대입을 하고 실행을 시키니



중단점에서 프로그램이 멈추고 윗부분을 보니 내가 입력한 값과 시리얼 값을 비교해서 무슨 성공과 실패에 대한 메시지를 결정한다.



디버깅을 하면서 찾은 시리얼 값으로 체크를 해보니 성공했다고 나온다.


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10
CodeEngn Advance 02  (0) 2017.01.10
CodeEngn Advance 01  (0) 2017.01.10


실행해보니 패스워드를 입력해서 맞지 않으면 바로 실행이 멈춘다


문자열을 검색해보니 패스워드가 맞을 때 출력될 것으로 보이는 문자열들도 보이지 않는다.



여기 함수 호출 하는 부분은 입력받는 것으로 추정된다.



1234로 입력을 했다.



입력을 한 후 함수들을 몇개 호출하는데 그중 의심되는 함수를 찾아 보니 비교문이 있다


Eax에서 한바이트씩 가져와 16진수와 비교를 한다.




16진수들을 아스키코드로 바꾸면 어떠한 문자열이 된다.



입력을 하니 패스워드가 맞다고 메시지 창이 뜬다.



WELL DONE! 이라는 문자열을 찾을 수 없었던 이유는 16진수를 하나하나 넣어 messagebox함수를 호출하기 때문이였다.


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10
CodeEngn Advance 03  (0) 2017.01.10
CodeEngn Advance 01  (0) 2017.01.10


먼저upx 패킹이 되어있어 언패킹을 하였다.



코드엔진 베이직 19번에서 풀었던 문제와 유사하여 일단 timeGetTime함수에 모두 중단점을 걸었다.



그리고 디버깅 할때마다 안티디버깅이 되있어 eax 0으로 바꿔주며 풀었다.



첫번째 timeGetTime 함수를 호출하고



두번째 함수를 호출해서




두번째 함수의 리턴 값에서 첫번째 함수 리턴값을 빼주어 eax에 저장한후 ebx+4와 비교한다


ebx+4보다 작다면 계속 timeGetTime함수를 호출하며 무한루프를 돈다


ebx+4초 후에 프로그램이 종료된다


'문제 > CodeEngn_Advance' 카테고리의 다른 글

CodeEngn Advance 06  (0) 2017.01.10
CodeEngn Advance 05  (0) 2017.01.10
CodeEngn Advance 04  (0) 2017.01.10
CodeEngn Advance 03  (0) 2017.01.10
CodeEngn Advance 02  (0) 2017.01.10

+ Recent posts