SoftIce를 이용한 간단한 Serial Crack
2004/08/22 22:09
시리얼 입력 예제 프로그램 작성

이 글의 주제가 SoftIce를 이용하여 간단한 Reverse Engineering을 해보자(나쁘게 이야기 하면 Crack 이기도 하고 ^^;)인데 그러기 위해서는 Serial 입력을 요구하는 프로그램이 있어야 겠다.
그래서 다른 프로그램을 이용하는것 보다는 간단하게 API로 CrackMe란 예제를 만들어 봤다.
이 프로그램을 실행을 시키면 위와 같은 화면이 나온다. 다른 Serial 등록 프로그램과 아주 똑같지는 않지만 비슷하게 구성하였다. 이 프로그램에서는 Serial Number를 입력하고 '확인'을 누르면 프로그램내에 있는 Serial Number와 비교하여 같으면 Success 라는 메세지 박스를 띄우고 종료한다. 만약 틀리게 되면 Fail이라는 대화상자를 띄우고 무한 반복을 하도록 하였다.
소스코드를 보면 알겠지만 Serial Number는 '1234abcd'로 되어 있다. 그러므로 Serial Nuber를 '1234abcd'라고 입력하고 '확인'을 누르면 Success라는 대화상자를 띄울것이다. 테스트 보기 바란다. 또한 GetDlgItem을 사용하여 입력된 Serial Number를 얻어온다는 사실과 2개의 Serial Number를 lstrcmp를 사용하여 비교 한다는걸 기억해두자.
자 그럼 우리는 Serial Number 인 '1234abcd'와 프로그램의 전반적인 흐름을 모른다는 가정하에 CrackMe란 테스트 프로그램을 Crack 이란 것을 해보자. 다시 한번 이야기하지만 우리는 그것이 MFC로 짜여 졌는지 두 Serial을 lstcmp를 사용하여 비교하는지 아무것도 모르고 아는건 오로지 Serial Number를 입력하라는 것밖에 모른다.
사실 먼저 약간의 어셈블러 지식, SoftIce의 사용법, STACK등에 관련된 지식이 필요하다.
하지만 이런한 지식이 없다해도 두려워 말자. 따라하다 보면 쉽게 할수 있다. (않되더라도 나를 원망하지 않기를...)

예제프로그램 : 다운받기

BreakPoint 설정하기

먼저 CrackMe를 실행시킨다. 그럼 위의 화면과 같이 사용자의 입력을 기다리며 대기할것이다.
이때 CTRL+D를 눌러 SoftIce를 띄우자. 그래서 CrackMe란 프로그램 내부에 BreakPoint를 설정해야 할것이다.
BreakPoint를 어떻게 설정할수 있을까?
답은 SoftIce 명령어중 bpx라는데에 있다.
BPX [address] [IF expression] [DO "command1;command2;..."]
ex) bpx 80023455 if eax>1ff do "db ds:dx"
0x80023455 주소에 BreakPoint를 설정하여 프로그램이 실행시키면 0x80023455 주소를 실행하게 되면 if문 이하 조건, 즉 eax가 0x1ff보다 큰지 작은지를 검사해서 크면 브레이크가 걸리면서 ds:dx의 내용을 출력한다.

이 'bpx'라는 명령어로 어떻게 BreakPoint를 설정할까?
API로 프로그래밍을 해본 사람이라면 맨위의 화면에서 Serial Number를 입력하는 Control이 EditBox라는 것을 알것이며 이 EditBox에 있는 값을 얻어오기 위해서는 GetDlgItemText 또는 GetWindowText라는 명령어를 사용하여야 한다는것도 알것이다.(모르겠다면 당장 API책을 한권 사서 보기 바란다. 관심이 있다면...)
그러면 CrackMe란 프로그램에서 이 함수들(GetDlgItemText, GetWindowText)을 호출할때 BreakPoint를 설정하면 우리는 CrackMe란 프로그램의 내부를 볼수 있을것이다. 비록 C언어가 아니고 어셈블러 이긴하지만 내부를 볼수 있다는게 어디인가?
GetDlgItemText, GetWindowText 의 주소를 알아야 하지만 일단 무식하게 'bpx GetDlgItemText'를 입력해보자. 아마도 에러가 날것이다. 왜냐하면 GetDlgItemText라는 함수는 내부적으로는 다시 Ansi용인 GetDlgItemTextA와 Unicode용인 GetDlgItemTextW로 나뉜다. -W는 Unicode를 지원하기위해 추가된 함수이다. 그러므로 우리는 'bpx GetDlgItemTextA' 'bpx GetDlgItemTextW' 를 입력해야 한다. 이번에는 에러가 나지 않았을것이다.
'bl'을 입력해보면 BreakPoint가 걸려 있는걸 볼수있다. 이처럼 SoftIce는 Symbol을 통해 함수의 주소를 알지않아도 우리는 윈도우 API 함수에 BreakPoint를 설정할수 있도록 해준다. 이 얼마나 멋진 도구인가.
이제부터는 힘든여정이 시작된다. Crack이란게 커피자판기에서 커피 뽑든 간단한 문제가 아니다. 거의 대부분이 노가다에 가까운 작업을 통해야만이 얻을수 있는 작업이다.
그럼 이제 다시 CTRL+D를 눌러 CrackMe란 프로그램으로 되돌아 가서 Serial Number로 대충 아무 숫자나 글씨를 넣고 '확인'을 눌러보자.
BreakPoint가 걸리는가? 만약 걸리지 않는다면 다시 처음부터 차근차근 다시 해보길 바란다.
아래 그림 오른쪽 아래에 보면 user32!.text+00044438 보일것이다. 이 부분은 현재 BreakPoint가 걸린 위치를 말한다. 즉 현재는 GetDlgItemTextA 함수내부인 커널모드인것이다.

BreakPoint 설정하기

자 그럼 이제부터는 F10(step over)을 눌러 단계 단계 짚어보자.
그런데 GetDlgItemText는 우리가 굳이 분석할 필요가 없다. 다만 이곳에서 리턴해서 되돌아가는 곳만 알면 된다.
그러면 'p ret'를 입력하자. 이 명령은 프로그램이 실행되다 'RET'이란 명령을 만나면 다시 BreakPoint가 걸린다.
'p ret'를 사용하여 아래화면의 오른쪽 아래가 CrackMe!.text+02BB로 바뀐것을 볼수 있을것이다. 이때가 CrackMe란 프로그램에서 GetDlgItemText를 호출하고 결과값을 받고 리턴된 시점이다. (코드 위를 보면 Call USER32!GetDlgItemTextA 라는게 보일것이다. )
입력된 Serial Number를 얻어왔으니 남은건 2개의 Serial Number를 비교하는 부분이 있을것이다. 우리는 이 부분을 살펴보고 수정한다면 우리가 원하는 바를 얻을수 있을것이다.

다시 F10을 눌러 코드를 분석해 보자.
먼저 ecx, edx에 ebp에 있는 각각의 값을 넣어 call kernel32!lstrcmp 호출한다. 그런다음에 test eax,eax를 실행한다음 jnz(zero flag가 0이 아니면, 즉 test eax,eax 결과 0이면 zero flag가 1이 된다)를 하여 xor eax를 통해 eax를 0을 만들고 jnz를 하지 않으면 eax에 1을 넣고 jmp 0x4012f2로 jump를 한다. jump를 하는곳에서는 stack을 정리하고 ret 한 다음 바로 Fail이란 대화상자를 띄운다. 뭔가 느낌이 오는가?
가정을 해보자. ecx,edx에 각각의 Serial Number를 담고 비교하는 함수(lstrcmp)를 호출한다면 분명 exc,edx 중 한곳에는 내가 입력한 값이 들어 있을것이다. 그렇다면 다른 한쪽은 진짜 Serial Number라는 이야기가 된다. 이제 알겠는가?
그렇다면 우리의 가정을 증명해보자.
자 다시 CrackMe를 실행하고 CTRL+D를 눌러 SoftIce를 실행하고 'p ret'를 수행하여 전과같은 위치에 오도록하자. 화면 4 처럼 push edx 까지 F10을 눌러 진행시켜보자. 그런 다음 'wd.0 ecx'와 'wd.1 edx'를 입력해보자.
내가 입력한 Serial Number와 진짜 Serial Number가 시원하게 보인다. 결국 우리에 가정이 맞았다는 이야기다.

조금더 진행 해보도록 하자. F10을 눌러 test까지 진행하도록 하여두고 이곳에서 Register를 임의로 조작하여 jnz가 되지 않도록 하자.
SoftIce에서 r을 눌러 상단에 있는 register로 zero flag로 커서를 옮긴후 INSERT 키를 눌러 zero flag가 setting 되도록하자(아래의 화면)
자 그런다음 F10을 눌러보자. jnz를 수행하지 않고 그 다음 명령어인 mov eax,1을 명령어를 실행하는가? 그럼 g를 눌러 프로그램을 계속 수행시켜보자.
Success라는 대화상자가 표시되는가?


자 성공이다. 여러분은 내가 예제로 만든 프로그램의 Serial Number를 훔쳐봤을뿐 아니라 Serial Number의 확인 부분을 임으로 조작하여 Success 대화상자를 띄웠다.
사실 예제 프로그램의 Serial Number를 알아내는 것이 너무도 간단하였지만 실제에 있어서는 지루하고 오래 걸리는 일이다. 뿐만 아니라 어셈블러를 분석한다는건은 그리 만만한 일이 아니다.
여러분이 할일이 또 하나 있다. 다운 받은 예제 프로그램을 디버깅 해보라. 브레이크 포인터를 걸어서 Disassembly 버튼을 눌러 SoftIce에서 나오는 코드와 비교해보자. 아마도 똑같지는 않더라도 유사한 코드가 나올것이다.
간단한 for문이나 if문, switch문등을 작성하여 그것들을 Disassembly해보면 많은 도움이 될것이다.
아래는 예제프로그램을 비주얼 스튜디오에서 Disassemble해본 화면이다.
2004/08/22 22:09 2004/08/22 22:09
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다


해커스랩 레벨별 공략법
2004/08/20 16:58
레벨0 -> 레벨1
문제
누군가 우리 시스템에 백도어를 설치하여 두었다. 여러분은 이 백도어를 악용하여 레벨0를 통과한다.
힌트
디바이스도 아닌것이 디바이스 드라이버 무리속에..
풀이
백도어(back door)란 해커가 시스템을 해킹한 후(해킹과정에는 보통 Local attack과 Remote attack이 있다. Local attack이란 해커가 해킹을 하려고 하는 시스템에 계정이 있는 경우 시스템 자체의 버그를 이용하여 해킹하는 방법이고, Remote attack이란 계정인 없는 경우 Protocol상의 문제점이나, 해킹하려고 하는 시스템의 여러가지 인터넷 서비스 설정 버그, 또는 다른 여러 방법을 동원하여 일단 대상 시스템에 침투하는 과정을 말한다.) 다음번에 다시 대상 시스템에 들어가기위해 복잡한 해킹 과정을 거치지 않고 쉽게 해킹할 수 있도록 대상시스템에 만들어 놓은 일종의 개구멍이라 할 수 있다.
일단 해당 백도어가 디바이스 무리속에 있기 때문에 유닉스의 파일시스템에서 디바이스 디렉토리인 /dev로 가서 숨겨진 백도어를 찾도록 한다.
[bluesky@bluestar bluesky]$telnet drill.hackerslab.org
login:level0
password:guest
.....
[level0@drill level0]$ pwd
/home/level0
[level0@drill level0]$ whoami
level0
[level0@drill level0]$ id
uid=2000(level0) gid=2000(level0) groups=2000(level0),9999(hackerszone)
[level0@drill level0]$ cd /dev
[level0@drill /dev]$

이제 숨겨진 백도어를 find 명령을 이용하여 찾아보자(다음레벨로 올라가기 위한 백도어이기 때문에 이 백도어의 user는 level1일 것이다. 현재위치(.)에서 user가 level1이고 group이 level0인 화일을 찾아서 화면상에 보여준다. 결과를 화일로 저장하고 싶은 경우는 find . -user level1 -group level0 -print > file와 같이 해준다.
[level0@drill /dev]$ find . -user level1 -group level0 -print
./.hi

[level0@drill /dev]$ ls -l .hi
-rwsr-x--- 1 level1 level0 12900 Aug 10 15:15 .hi
[level0@drill /dev]$ ./.hi
[level0@drill /dev]$ id
uid=2000(level0) gid=2000(level0) euid=2001(level1) groups=2000(level0),9999(hackerszone)
[level0@drill /dev]$ whoami
level1
[level0@drill /dev]$pass
---------------------------------------------------------------------
[ LEVEL 1 ]
---------------------------------------------------------------------
패스워드 : xxxxxxxx
---------------------------------------------------------------------


▶ 그외 레벨1부터14까지의 과정 보기


출저 : 모름, 아시는분 연락바람
2004/08/20 16:58 2004/08/20 16:58
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다

  • Longhorn 2004/09/18 18:00  댓글주소  수정/삭제  댓글쓰기
    좋군요. 예전에 얼마 까지 깼는데, 그것도 잘 기억이 안나네요.^^ 보고 참고 하겠습니다.
  • 홍가이버 2004/09/19 08:45  댓글주소  수정/삭제  댓글쓰기
    저도 한참 하다..지금 시들해져서..^^..처음에는 정말 재밌었죠?

  • 디바이스 드라이버를 개발하려면...
    2004/08/20 16:44
    OS의 전반적인 구조 파악

    ◈ 윈도우 2000/XP 커널
    - 윈도우 2000 개론
    - 윈도우 2000 커널 구조
    · Object 관리자, 프로세서와 쓰레드, 가상메모리 관리
    - I/O 서브시스템, Kernel Model I/O 처리 과정
    - 하드웨어 기초

    ◈ 윈도우 2000/XP 드라이버 개발도구
    - 디바이스 드라이버 개발도구

    가상메모리 관리 및 커널 자료구조 분석

    ◈ 가상 메모리 관리 및 선점레벨(IRQLs)
    ◈ 디바이스 드라이버의 종류와 구조
    - 디바이스 드라이버의 분류 및 전체구조
    - 디바이스 드라이버와 커널자료구조
    ◈ 커널 자료구조 분석(1)
    - Driver Object
    - DPC Object
    - Device Extension
    - IRP
    ◈ 간단한 커널 드라이버 작성 및 디버깅
    ◈ 커널 자료구조 분석(2)
    - Interrupt Objects
    - DPC Objects
    - Dispatcher Object
    ◈ 타이머
    - 빌트인(Built-In)타이머
    - 커스텀(CustomDPC)타이머
    ◈ 하드웨어 입출력(HAL)
    - Get PCI Configuration
    - HalTranslateBusAddress
    ◈ IRP Queueing vs Cancel, StartIO 처리기
    - Kernel Device Queue에 대한 이해
    - Queue와 IRP Cancel과의 동기화
    - IoStartPacket vs IoStartNextPacket
    ◈ StartIO를 이용 IRP 생성 및 전달
    - Model
    - IRP Completion Routine과 IRP Stack
    - System Thread 와 태스크스위칭
    - Busmaster DMA vs Slave DMA
    - Layered Model과 필터링

    디바이스 드라이버 프로그래밍

    ◈ 사용자 프로그램과 메모리 매핑을 통한 공유
    - 사용자측의 메모리를 이용한 커널과의 공유
    - 커널측의 메모리를 이용한 사용자와의 공유
    ◈ USB PnP 드라이버
    - Standart Control Pipe사용
    - Bulk In/Out Pipe사용
    ◈ PCI PnP 드라이버

    디바이스 드라이버

    ◈ 윈도우 2000 Virtual Serial Device Driver
    ◈ 윈도우 2000 파일 시스템 감시 Driver
    ◈ 윈도우 2000 USB Modem Device Driver
    ◈ 윈도우 2000 램디스크 Device Driver
    ◈ 윈도우 2000 API 감시 Device Driver
    ◈ 윈도우 2000 디스크 감시 Device Driver
    ◈ 윈도우 2000 시리얼 감시 Device Driver
    ◈ 윈도우 2000 Touch Screen Device Driver
    ◈ 윈도우 2000 디스플레이 감시 Device Driver
    2004/08/20 16:44 2004/08/20 16:44
    Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다