처음부터 차근차근
Crack(코드우회) 본문
우회 리버싱이란 틀려도 맞는걸로 처리하는 것이다.
우회리버싱에 익숙해지기 위해 실패메세지를 우회하는 크랙파일을 만드는 연습과
직접 키값을 찾는 연습을 해보았다.
실습1
성공 메세지를 출력하는 우회리버싱
-> 비교하는 부분 JMP 코드로 변경
C드라이브의 type이 CD-ROM이 아니지만 CD-ROM 타입으로 인식되도록 우회하게함
CMP명령어를 찾은 후 JE -> JMP로 수정하여 무조건 'HD is a CD-ROM'을 출력하는 문장으로 이동하도록 코드를 수정
성공 메세지 박스 출력하는 부분 시작 주소 : 0040103D
실패 메세지 박스 출력하는 부분 시작 주소 : 00401028
JE 40103D --> JMP 40103D로 변경하여 실패해도 성공 메세지 박스 출력하는 부분으로 JUMP하여 성공했다고 처리한다.
원래 exe 파일 : get함수로 하드디스크 타입을 읽어 C드라이브의 TYPE이 CD-ROM이 아니면 실패 메시지를, CD-ROM이면 성공 메세지를 띄우는 파일이다.
파일 소스 설명
CALL <JMP.&USER32.MessageBoxA> : 시작 메세지 박스 호출하는 함수
CALL <JMP.&KERNEL32.GetDriveTypeA> : 현재 C드라이브가 어떤 형태인가의 값을 인자로 받아, 드라이브의 타입을 반환하는 함수 -> C드라이브가 HDD이므로 3을 반환하여 EAX에 저장
CMP EAX, ESI : EAX는 현재 나의 hdd 타입, ESI는 CD-ROM 타입. 두 값이 같은지 비교JE 0040103D : 같은 값이면 0040103D으로 점프
결과 크랙 파일
실습2
성공 메세지를 출력하는 우회리버싱
원래 파일 : 내부의 JLE 명령어로 인해 실패 메세지(Fail...ㅠㅠ)를 출력하는 파일
실패 메세지 있는 곳 주소 : 0040101F
메세지 박스 위에 JLE 명령어(JLE 0040101F)를 찾은 다음
이 명령어 자체를 NOP으로 변경해준다.
JLE 0040101F --> NOP
이렇게 하면 JLE 명령어가 실행되지 않고, 바로 밑의 줄의 명령어를 계속해서 실행해 나가서 결국 성공 메세지(Success)를 출력하게 된다.
결과 크랙 파일
실습3
키값을 찾는 리버싱 실습
원래 파일 : 비밀번호를 입력하는 창이 뜨면 비밀번호를 입력하고, 이 비밀 번호가 맞으면 성공메세지를, 틀리면 실패메세지를 출력하는 파일이다.
CALL 명령어를 찾는다.
그중 밑에 CMP랑 JE있는 CALL 명령어 부분을 찾는다.
PUSH abexcm5.00402324 //402324번지에 [입력한 값]과 [실제 비밀번호 값] 중 하나의 값이 저장됨
PUSH abexcm5.00402000 //402000번지에 [입력한 값]과 [실제 비밀번호 값] 중 하나의 값이 저장됨
CALL <JMP.&KERNEL32.lstrCMPiA> // 입력한 값과 실제 비밀번호를 비교하는 함수 호출. 같으면 0 반환. 이 부분에서 Break Point를 걸어서 뒤에 있는 값들을 확인하면 된다!
CMP EAX, 0 // 함수에서 반환된 값이 0과 같은지 비교
JE 00401117 // 결과값이 같으면 00401117 주소로 이동
00401117 : 성공메세지있는 주소임
덤프창(메모리 창)에서 해당 주소(402324랑 402000)를 검색하여 저장된 값을 찾는다.
찾은 실제 비밀 번호를 입력하면 성공메세지가 뜨는 것을 볼 수 있다.
실습4
키값을 찾는 리버싱 실습2
위에서 했던 실습과 비슷한 실습이다.
”You failed” 문자열(실패 메세지)을 찾는다.
출력함수 윗 부분에 있는 코드 중 CMP, JNZ명령을 찾는다.
CMP명령어에서 Break Point를 설정하고, 실행해봐서
CMP명령어에 어떤 값과 어떤 값을 비교하는 지 확인한다.
하나는 키값, 또 하나는 입력값일 것임을 예상할 수 있다.
MOV EAX,DWORD PTR SS:[EBP+8]
CMP EAX,DWORD PTR SS:[EBP+C]
EBP의 주소->[EBP]->0010FF34
EBP+8의 주소->[EBP+8]->0010FF3C
EBP+C의 주소->[EBP+C]->0010FF40
EAX에는 주소[EBP+8]에 저장된 값이 들어있고, 이 값은 내가 입력했던 값이 16진수로 변환되어 들어있다.
그러므로 EBP+C에 키값이 있는 것을 알 수 있다.
EBP+C인 0010FF40로 찾아가서 키값을 확인한다. 이때 키값이 16진수로 나와있는데 10진수로 변환해야 실제 키값이 나온다.
키값을 입력해서 성공메세지를 출력한다.
(저기서 내 학번이라 표시된 부분은 필자가 입력한 값이다.)
실습5
조별 실습 : 성공 메세지를 출력하도록 하는 우회리버싱
위의 실습에서 했던 내용을 바탕으로 조원의 프로그램에서 키값을 찾아내는 활동을 해보았다.
각 팀원의 프로그램 코드는 아래와 같다.
#include <stdio.h>
#include <windows.h>
void main() {
int num = 21524;
int inputNum;
printf("키값을 입력하세요 : ");
scanf_s("%d", &inputNum);
if (num == inputNum) {
printf("딩동댕동");
}
else {
printf("땡!");
}
Sleep(3000);
}
키값을 입력하라고 출력한느 부분을 찾아서 그 위에 있는 CMP와 JNZ 명령어를 찾는다.
그리고 분기하는 부분 코드를 NOP으로 바꾼다.
이렇게 하면 틀린 비밀번호를 입력해도 결과는 성공 메세지가 떴다.
조별 실습 : 키값 찾기
위에서 했던 실습과 마찬가지로 JNZ 명령어 위를 보면 입력값과 실제 비밀번호값이 들어있는 주소를 발견할 수 있다.
CMP 명령어에서 Break Point를 걸어 키값을 확인했다.
출처 : 정보보안(22-1학기)고수정교수 강의 내용 변형 및 요약
'정보보안' 카테고리의 다른 글
웹 해킹 - 사용자 인증 (0) | 2022.04.13 |
---|---|
Crack(지뢰게임, music player 리버싱) (0) | 2022.04.10 |
리버싱과 어셈블리어 (0) | 2022.03.27 |
Patch (0) | 2022.03.19 |
리버싱 (0) | 2022.03.12 |