본문 바로가기

리버스-엔지니어링

리버싱 레나 튜토리얼28 - 서버 인증 우회

반응형
리버싱 레나 튜토리얼21 - UPX UnPackMe
 

 

해당 프로그램은 계정 등록 과정에서 서버 인증 체크를 하므로 이를 우회한다.


디버깅 시 저번 문제처럼 PUSHAD/POPAD가 존재하지 않지만,
시작점이 CODE영역 밖이기 때문에 실행코드가 패킹되어 있다고 의심된다.



PUSHAD/POPAD는 없지만, PUSH 명령어가 이어지기 때문에,
PUSHAD와 유사한 로직이 수행되고 있음을 추측해 볼 수 있다.

현재 스택에 저장된 원래 레지스터 값들이 언제 회수(POPAD) 되는지 확인하기 위해
ESP Trick을 시도할 것이다.

첫 시작점인 55F881에서는 ESP값이 존재하지 않으므로
1 step 실행해서 ESP 값을 생성한 후 HW Break Point를 걸어본다. 



ESP 우클릭 > Follower in dump

스택의 시작점에서 break point > HW on access > dword를 선택하여
ESP의 입출력 위치에 HW break point를 걸어 준다.



프로그램 실행 시 POP [레지스터값]을 수행하는 48D631까지 실행된다. 



CALL 이후 코드 다음 부분에는 외장함수 리스트를 초기화 하는 GETModuleHandle 함수가 존재하므로
이 시점이 OEP 인 것으로 추측 가능하다.
48D631에서 BP가 걸렸지만 POP 관련된 로직이 종료되는 RETN(48D62E) 다음 주소부터 OEP 이다(48D62F). 
이 지점을 새로운 OEP로 지정해준다.
※ 해당 주소에 우측키 – New origin here

이제 프로그램을 dump 해야한다.
Ollydbg dump는 오류가 발생하므로 LordPE를 이용한다. 



프로그램이 OEP까지 실행된 상태에서 LordPE로 dump(dump full)한다.
이후 ImportREC를 사용하여 제거된 IAT를 복구한다.



해당 프로그램은 실행하기전과 실행 후 계정을 입력했을 때 아래 오류 메시지 함수가 나타난다. 
이를 추적하기 위해 콜스택을 사용한다.



다음 화면은 콜스택으로 호출된 함수를 확인한 결과이다. 



각 메시지박스 함수 위치로 가보면 
아래 사진 446B97의 바로 위에 있던 함수가 오류 메시지 창을 띄우는 함수인 것을 알 수 있다.



해당 코드 밑부분으로 이동하면 인증 성공 루틴이 존재한다.



인증 성공/실패 분기점을 찾기 위해 446B92 윗부분으로 올라가면서 디버깅을 진행한다.
인증 성공 루틴은 인증 실패 함수(446B92) 이후에 존재할 확률이 높으므로
분기문이 446B92 이후의 주소값이 있는지 찾는다.



위 사진에서 보이다시피 446B92보다 큰 값인 JMP 446B9C를 발견하였으므로
인증 성공 루틴으로 이동하는 분기문이라 생각된다.
해당 분기문 위에 JNZ가 JMP를 결정하므로 4469C0을 JZ로 패치한다.

이후 프로그램을 실행했을 때 나타났던 오류 메시지가 제거되었고,
인증 체크 시도 또한 성공적으로 우회하였다.

 

반응형