curons
[reversing.kr] Position 본문
프로그램을 실행하면, Name과 Serial을 입력받는다. 그리고 프로그램은 Wrong! 이라는 문구를 띄우고 있다. 올바른 Name과 Serial을 제대로 입력하면 Wrong!이라는 문구가 "Correct" 혹은 다른 문구로 바뀌지 않을까 싶다. 먼저 Olly를 사용하여 Entry Point를 찾아냈더니 위치가 402A70이었다. 프로램은 딱히 인증하는 버튼이 없기 때문에 다른 방법으로 Name과 Serial을 판별하고 있을거라 생각된다. 디버거로 Reference String을 찾아본 결과, Correct와 Wrong이라는 스트링을 찾을 수 있다. Wrong을 콜하는 부분에 Break Point를 걸고 프로그램을 실행했더니 프로그램이 실행되기 전에 해당 부분에서 Break가 걸린다.
인풋박스에 문자를 입력할 때 마다 해당 부분에 Break가 걸린다. 이 말은 문자를 하나씩 입력할 때 마다 Name과 Serial을 검사한다고 생각할 수 있다. 문제를 다시 보면 파일과 함께 있던 텍스트 파일에 Serial이 76876-77776인 경우의 name을 찾으라고 명시되어 있다. 이제 디버거에서 어느 부분에서 어떻게 이름과 시리얼을 비교하여 판별하는지를 알아야 한다. 프로그램에 일단 Serial을 76876-77776으로 입력하고 Name을 임의로 입력한다. 그 다음 트레이싱을 하다보면 이름을 비교하는 부분이 나온다. 해당 부분이 이름의 값을 가지고 연산한다는 것은 Comment의 Name과 입력값을 확인하면서 알 수 있다.
위의 부분이 바로 이름값을 가지고 판단하는 부분이다. 이름을 가지고 처음으로 판단하는 것은 길이이다. 40179F의 위치에서 트레이싱을 해보면(name값을 가져오길래 여기서 해봄) 바로 다음 명령어(cmp)가 중요해진다 여기서 je 조건을 만족시키지 못하면 Wrong을 출력한다. 그렇다면 ecx-0xc의 값이 4이여야 하는데 ecx-0xc의 값을 보면 입력한 문자의 길이이다(여러 문자를 넣어가면서 변화하는 값을 살펴봄). 그 다음 명령어들을 보면 길이가 4인경우 4017E0 부분으로 점프한다. 이 부분을 보면 이름의 패턴을 체크하는것을 알 수 있다. 아래 사진을 보면 name을 체크한다고 디버거가 알려준다.
해당 부분을 분석하는것이 이 문제의 핵심인듯!! 위의 그림에서 xor esi, esi ~ jl short 00401806부분을 분석하면 4개의 문자가 모두 달라야한다. 그 다음부분을 보면 Serial값을 가져와 어셈 연산을 하는데 이곳을 분석하는것이 매우 힘들었다.
시리얼넘버를 가져와 첫번째 문자 그리고 아래에 내려보면 두번째 문자를 가져와 연산을 한다. 이 부분을 분석하다가 어셈블리어로 시간도 오래걸리고 쉽지 않다고 판단되어 IDA프로그램을 이용하였다. IDA를 보면 Sub_401CD0 함수가 Correct와 Wrong을 출력시키는 함수라는것을 확인할 수 있다. 그리고 그 위의 함수인 Sub_401740를 보면 이름과 시리얼을 확인하여 연산하는 부분인것을 알 수 있다.(해당 부분에서 비트 시프트 연산, 그리고 위의 어셈에서 시프트 연산을 했기 때문에)
해당 부분이 위에서 언급한 Ida로 확인한 name과 serial을 비교하는 부분이다. 맨 위의 if문이 위에서 분석한 name의 길이가 4라는 부분이다. 그 다음 while문 내의 첫번째 if문(v1 != v5를 비교한느 부분)에서 name의 각 문자가 같으면 안된다는 코드이다. 여기까지는 어셈블리어로 해석한 부분이고 사ㅏ진의 가운데에 있는 if문((&v62,5)!=45 를 비교하는 부분)을 보면 Serial의 6번째 글자가 아스키코드로 45(-)임을 알 수 있다. v62가 Serial이라는 것은 위에서 v61이 name이고 GetWindowText함수를 통해 v62에 값을 저장한것으로 보아 Serial임을 알 수 있다.
아래 부분을 보면 v7과 v9에 이름의 앞 2글자를 받아와 연산을 한다. 그 이후에 v63이라는 버퍼에 저장한다. 그리고 v62와 v63이 같아야하는것으로 보아 name의 값으로 serial을 만들고 만든 serial과 입력받은 serial이 같아야한다는것을 알 수 있다. 다시 위의 코드를 보면 문자를 2개 받아와서 비트 연산을 하는데 연산값을 보면 v7로 연산을하는 부분과 v9로 연산하는 부분으로 나눌 수 있다. 아래 부분은 다음과 같다.
연산 과정을 보면 시리얼 넘버의 자리수를 위의 name의 비트연산으로 만들고 있다. 순서에 차이가 있어 혼동될 수 있으나 이를 주의하여 연산을 해보면 시리얼을 만들 수 있다. 비트연산을 보면 위의 5개는 5,6의 2가지의 경우만 나오고 아래의 5개는 0,1의 2가지의 경우만 존재한다 이를 이용하여 연산한다는것을 알았고 우리는 결과값인 serial을 알고 있으니 이를 역으로 짜서 코딩해보면 name 값을 알 수 있다. 필자는 이를 C언어를 사용하여 코드를 작성하였고 결과값이 나올 수 있는 모든 경우를 출력하여 확인해보았다. 위의 과정은 처음 2글자의 과정만 있고 다음 2글자는 이 코드 아래부분에 있다. 방법은 같으므로 여기서부터는 직접 해보길,,,
문제 해결!!!
'Reversing' 카테고리의 다른 글
[PCTF2016]quick (0) | 2017.06.01 |
---|---|
[reversing.kr] Replace (0) | 2016.12.25 |
Reversing 시작하기 (0) | 2016.12.25 |