일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 보안
- ftz
- 리버싱
- Burp Suite
- python flask
- 웹 해킹
- 웹해킹 실습
- 부트스트랩
- 포렌식
- 테이블명 수집
- Burp Suite Intruder
- 시스템 해킹
- 게시판 만들기
- 해커팩토리
- 해커팩토리 8번
- 파일 다운로드 취약점
- Blind Sql Injection
- CTF-d
- 레나 튜토리얼
- SANS
- 해커팩토리 10번
- 해커 팩토리
- SQL Injection
- 디스크 포렌식
- 리버싱 기초
- 해커 팩토리 6번
- union sql injection
- 로그 분석
- 네트워크 포렌식
- 해커팩토리 7번
- Today
- Total
Cha4SEr Security Study
[레나 튜토리얼] - 2. 라이센스 키 알고리즘 분석하기 본문
레나 튜토리얼 실습파일을 2번을 풀어봅시다.
2번 폴더에 들어가면 reverseMe.exe 파일이 있는데 파일 자체는 1번이랑 똑같습니다.
그리고 클릭해보면
You really did it Contratz 라는 메세지가 뜹니다.
일단 폴더에 있는 Keyfile이 이미 있는데 이 파일을 만드는게 2번의 목적이니 실습을 위해 지워줍시다.
지우고 다시 파일을 열어보니 1번문제와 유사한 메세지가 떴습니다.
일단 올리디버거로 한번 열어봅시당
역시 같은 파일이라 익숙한 화면이 나오네요.
복습을 위해 F8을 눌러서 진행을 한번 해봅시다.
CreateFileA까지 왔습니다. 이 함수는 Keyfile.dat 파일을 불러오는데 파일이 없기 때문에 오류가 났었죠.
이제 파일을 만들러 가봅시다.
우선 실습파일이 있는 폴더에 빈 텍스트 파일을 하나 만들어 줍니다.
그리고 파일 이름을 Keyfile.dat 라고 바꿔줍시다.
(경고창이 나와도 무시하시고 확인 누르시면 됩니다.)
그 다음 메모장을 켜서 Keyfile.dat 파일을 열어봅니다.
우선 아무런 문자 abcd를 넣고나서 올리디버거로 돌아가봅시다.
이번엔 Keyfile.dat 파일이 있으니 CreateFileA 함수가 실패하지 않겠죠?
1번에서는 함수가 실패하여 EAX에 "FFFFFFFF" 가 들어갔는데, 지금은 성공해서 44가 들어갔습니다.
그럼 밑에 CMP 명령을 통한 JNZ가 정상적으로 실행되면서 점프가 됩니다!
쭉쭉 진행한 다음 ReadFile이 있는 곳까지 왔습니다.
hFile을 보시면 44가 들어가있는데 아까 CreateFileA를 실행한 결과로 EAX에 들어가 있는 값과 동일한 값인 것을 알 수 있습니다.
우선 F8로 ReadFile 함수도 정상적으로 진행되는지 확인해봅시다.
왼쪽 밑에있는 덤프창을 클릭 후 Ctrl + G를 누르고 ReadFile의 버퍼가 있는 곳인 0040211A 를 입력해 이동해봅시다.
확인해 보시면 우리가 임의로 입력했던 abcd가 잘 들어간 것을 볼 수 있습니다.
또한 ReadFile 함수에 pBytesRead라는 변수가 있는데 이는 몇 바이트를 읽었는지를 저장하는 변수입니다.
위치는 위에 나온것 처럼 00402173 이니 이것도 Ctrl + G로 찾아서 확인해봅시다.
입력한 대로 4Byte가 저장이 되었습니다.
다음 F8로 진행하면 JNZ 명령어가 나오는데 ReadFile 또한 정상적으로 되었기 때문에 임의로 플래그를 수정하지 않아도 정상적으로 점프하게 됩니다.
다음으로 XOR 연산이 두번 나옵니다.
여기 나오는 XOR 연산의 목적은 레지스터를 초기화 하기 위함입니다.
XOR 연산은 비트연산으로 같으면 0, 다르면 1인데,
"XOR EBX EBX" 처럼 같은 값을 XOR 연산을 하니까 당연히 0이 되겠죠?
여기서도 마찬가지로 콤마를 기준으로 오른쪽에 있는 데이터를 왼쪽에 넣는 것이니 XOR 연산을 한 결과를
EBX에 넣는다 라는 의미가 됩니다.
실제로 실행해 보면 EBX와 ESI가 0으로 바뀐 것을 볼 수 있습니다.
쉽게 C언어로 설명드리자면
int EBX = 0;
int ESI = 0;
과 같은 개념입니다.
다음은 CMP 명령어인데, 402173 자리에 있는 수와 10과 비교를 하는 명령어입니다.
402173은 위에서 본 것 처럼 pBytesRead가 들어가 있는 곳으로, 읽어들인 바이트 수 입니다.
현재 402173에 저장된 것은 4바이트 인데, 10과 비교를 하면 4가 더 작습니다.
이 상황에서 CMP 명령을 했을 때의 결과를 한 번 봅시다.
1번 문제를 풀 때와 같이 10보다 4가 더 작기 때문에 S 플래그가 1로 셋팅되었습니다.
때문에 JL 명령이 활성화 되었고, 점프하게되면 키 파일이 올바르지 않다는 메세지박스를 띄우는 곳으로 가게 됩니다.
*여기서 주의할 점은 저기 나와있는 10은 16진수를 의미하기 때문에 10바이트가 아닌 16바이트로 해석해야 합니다.
(CMP 명령을 할 때도 사실은 10과 4를 비교하는 것이 아니라 16과 4를 비교하는 셈이죠)
그럼 여기서 할 수 있는 일은 키 파일을 수정하는 것입니다.
키 파일은 우리가 좀전에 "abcd"의 4바이트를 넣어놨었는데, CMP와 JL을위해 16바이트를 넘겨서 저장 후 다시 돌려봅시다!
키 파일을 적당히 16바이트 이상으로 저장을 하고 새로 올리디버거로 돌려봅시다.
다시 돌려본 후 402173 자리에 가보면 16진수로 11 즉, 17바이트가 저장되었다 라고 볼 수 있고, S플래그도 0으로 되어 JL 명령어가 활성화되지 않았습니다.
다음으로 넘어가봅시다.
다음은 MOV AL, BYTE PTR DS: [EBX + 40211A] 입니다.
MOV는 오른쪽에 있는 값을 왼쪽에 넣는 명령어 입니다.
이 명령어는 40211A와 EBX를 더한 위치에 있는 값을 AL에 넣는 것 입니다.
우선 EBX는 위에서 XOR을 통해 0으로 초기화를 해주었으니 40211A에 있는 값을 다시 확인해봅시다.
보시면 아까 임의로 넣었던 키 파일의 내용이 들어가있습니다.
즉, 40211A + 0 이 위치한 자리의 값 => '0'을 AL에 저장하는 명령입니다.
제대로 들어갔는지 확인해봅시다.
EAX의 AL 부분을 보면 30이 들어갔습니다.
0이 아닌 30이 들어간 이유는 위의 HEX dump 창에서도 알 수 있듯이 숫자 0은 아스키 코드로 '30'이고, 이 30이 40211A의 위치에 저장된 것입니다. 따라서 AL에는 숫자 0이 아닌 문자'0'을 뜻하는 Hex값 30이 들어간거죠.
때문에 다음 명령어인 CMP AL, 0 을 실행하게 되면 서로 다르다라는 결과가 나오고, JE 명령어도 활성화되지 않습니다.
(JE 명령어가 활성화 되려면 문자 '0'이 아닌 Hex값으로 0이 AL에 저장되어야 합니다.)
실행해봅시당.
실제로 값이 다르기 때문에 Zero 플래그가 0으로 남아있고, JE 명령어도 활성화되지 않았습니다.
그 다음 명령은 CMP AL, 47로, AL과 47을 비교하는 명령어 입니다.
여기 나오는 47은 위에 0과 마찬가지로 Hex값의 47을 의미하고, 이는 아스키코드 표를 참고하면 알파벳 'G' 입니다.
즉, 키 파일에서 읽어들인 문자가 'G'인지 아닌지를 비교하는 명령어 입니다.
만약 'G'라면 제로 플래그가 1이 될것이고, 바로 아래에 있는 JNZ 명령어가 활성화 되지 않고, INC ESI와 INC EBX를 모두 실행할 것이고, 'G'가 아니라면 INC EBX만 실행하게 될 것입니다.
(JNZ는 제로 플래그가 0일때 점프를 하며, 제로 플래그는 CMP 명령을 통해 값이 같으면 1, 다르면 0입니다.
즉, 값이 다르면 점프를 하게 됩니다.)
INC 명령어는 해당 레지스터에 1을 더해주는 명령입니다.
EBX와 ESI는 0으로 초기화 했으니
만약 읽어들인 문자가 'G'이면 점프를 안하기 때문에 ESI와 EBX 모두 1이 되고,
아니라면 점프를 하기 때문에 EBX만 1이고 ESI는 그대로 0이 되겠죠?
우리의 첫번째 문자는 '0'으로 'G'와 다르기 때문에 제로 플래그가 0이고, JNZ 명령이 활성화되면서 INC ESI는 건너뛰고 INC EBX만 실행됩니다.
다음은 4010C1의 위치에 있는 명령어로 점프하는 명령어 입니다.
이동한 위치의 명령어는 40211A 에 EBX를 더한 위치의 값을 AL에 넣는 곳 입니다.
처음에는 EBX가 0이었지만, 이제는 INC EBX를 통해 1이 되었습니다.
그럼 AL에는 40211A + 1의 위치에 있는 데이터를 넣게 됩니다.
40211A + 1을 하게되면 40211B가 될 것이고, 해당 위치를 보면
키 파일에 입력한 내용 중 두번째 문자 입니다.
따라서 AL은 문자 '1'의 아스키 값 31이 들어가게 되고 위에 했던 과정을 반복하게 됩니다.
현재 키 파일은 0123456789abcdefg 총 17개의 문자가 저장되어 있고,
40211A에서부터 저장된 문자를 모두 읽은 후에는 Hex 값 0이 저장되어 있습니다.
따라서 총 17번의 반복을 진행하면서 키 파일의 문자를 모두 읽은 다음,
CMP AL, 0의 명령을 통해 반복이 종료된 다는 것을 알 수 있습니다.
우선 모든 반복문을 진행한 후에 다음 명령어들을 살펴봅시다.
모든 반복이 끝나면 AL에 0이 들어가게 되면서 점프를 하게되는데, 점프를 하면
ESI와 8을 비교한 후에 ESI가 8보다 작으면 아래 JL 명령을 수행하게 되고,
8 이상일 경우 JL 명령은 활성화되지 않고 우리의 목표인 JMP 00401205 를 수행할 수 있습니다.
ESI는 위에서 키 파일의 내용 중 'G'라는 문자가 있을 경우에 1씩 증가했습니다.
즉, 키 파일의 내용에 'G' 문자가 총 8개 이상일 경우에 성공한다고 볼 수 있습니다.
위의 반복문을 보기 쉽게 C++ 언어로 표현하자면
이런식으로 나타낼 수 있을것 같습니다.
이제 키 파일을 다시 수정해봅시다.
G를 8번 이상 넣으면서, 키 파일의 첫 번째 조건이었던 16바이트 이상을 만족시켜준 후에 저장하고 새로 실행해봅시다.
첫 번째 문자가 'G'였으니 AL에 47이 들어갔고, INC ESI 명령이 정상적으로 수행된 후에 ESI가 1 증가하였음을 볼 수 있습니다. 이제 반복문을 끝내고 나와봅시다.
반복이 끝나면 ESI가 8을 넘었기 때문에 JL은 활성화되지 않고 바로 JMP 명령을 수행할 수 있게됩니다.
점프를 하게 되면
성공 메세지를 띄워주는 곳까지 오게됩니다.
다시 폴더로 돌아와서 reverseMe.exe. 파일을 실행해도 성공 메세지가 뜹니다.
이로써 2번 문제도 해결!
'Reversing > 레나 튜토리얼' 카테고리의 다른 글
[레나 튜토리얼] - 3. nag 제거하기 with PE 분석 (2) | 2020.04.25 |
---|---|
[레나 튜토리얼] - 1. 라이센스 루틴 지나가기 (0) | 2020.04.19 |
[레나 튜토리얼] - 0. 실습 준비 (1) | 2020.04.16 |