0. Windows 11 에서 정상적인 실행이 되지 않으므로, hyper-V 등을 통해서 windows 10에서 실행하는 것을 권장한다.

1. 다운로드 : Python3, Visual studio 2022, DynamoRIO(https://github.com/DynamoRIO/dynamorio/releases)

2. 적절한 경로에 DynamoRIO 압축 해제

3. config.h 에서 input 파일 최대 사이즈 수정  (1*1024*1024 를 아래와 같이 수정)

/* Maximum size of input file, in bytes (keep under 100MB): */

#define MAX_FILE            (100 * 1024 * 1024)

4. x64 Native Tools Command Prompt for VS 2022 열기

git clone https://github.com/googleprojectzero/winafl
cd winafl
git submodule update --init --recursive
mkdir build64
cd build64
cmake -G"Visual Studio 17 2022" -A x64 .. -DDynamoRIO_DIR=I:\DynamoRIO\cmake -DTINYINST=1 -DUSE_DRSYMS=1 -DINTELPT=1 -DUSE_COLOR=1
cmake --build . --config Release

5. harness 작성

#include <iostream>
#include <windows.h>

typedef int(__stdcall* _OHMYGOD)(const char* data); 
_OHMYGOD func;

extern "C" __declspec(dllexport) __declspec(noinline) int fuzzme(const char* path)
{   
    int result = func(path);
    return result;
}

int main(int argc, char *argv[])
{    
    HMODULE hMod = GetModuleHandle(0);
   
    hMod = LoadLibrary(L"I:\\victim\\x64\\Release\\victim.dll");
    if (NULL == hMod)
    {
        printf("dll load error\n");
        return 0;
    }
   
    func = (_OHMYGOD)GetProcAddress(hMod, "ohmygod");
    fuzzme(argv[1]);    
}

6. victim 작성 (타겟 DLL)

#include "pch.h"
#include <iostream>

extern "C" __declspec(dllexport) int ohmygod(const char* path)
{
    std::cout << path << std::endl;
    char data[40] = { 0, };
    char buf[30] = { 0, };
    
    HANDLE hFile = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile)
    {
        DWORD dwRead;
       
        ReadFile(hFile, data, sizeof(data), &dwRead, NULL);
        std::cout << "read : " << dwRead << std::endl;
        if (dwRead)
        {
            memcpy(buf, data, dwRead+40);
            std::cout << buf;
        }
        CloseHandle(hFile);
    }
    return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

원활한 crash 발생을 위해 각각 Release 로 빌드한다.

7. 입출력 디렉토리 설정

afl은 사용자가 지정한 입력 디렉토리에 있는 파일들을 퍼징 데이터로 사용한다. 

crash를 유발하지 않는 정상 입력 데이터이어야 첫 실행 시 에러가 발생하지 않는다.

아래 데이터를 1.txt로 저장한다.

abcd

8. 공격

afl-fuzz.exe -D I:\\dynamorio\\bin64  -i "d:\\fuzz_input" -o "d:\\fuzz_output" -t 1000 -- -coverage_module victim.dll -target_module harness.exe -target_method fuzzme -fuzz_iterations 10 -nargs 1 -- I:\\harness\\x64\\Release\\harness.exe @@

실행은 반드시 afl-fuzz.exe 디렉토리에서 하여야 한다. 그렇지 않다면 아래와 같은 에러가 발생한다.

주의 : -coverage_module 및 -target_module 에는 파일명만 기입한다.

아래와 같은 화면이 나오면 실행 성공이다.

crash가 발생할 경우, i:\fuzz_output\crashes 경로에 상세 정보가 저장된다.

만약 CPU가 인텔인 경우, -D 옵션 대신 -P옵션을 사용하도록 하자. 속도가 압도적으로 빠르다. (내 PC에서는 5배 이상 차이가 났다.)

afl-fuzz.exe -P -i "d:\\fuzz_input" -o "d:\\fuzz_output" -t 1000 -- -coverage_module victim.dll -target_module harness.exe -target_method fuzzme -fuzz_iterations 10 -nargs 1 -- I:\\harness\\x64\\Release\\harness.exe @@

 

먼저 PowerShell이 무엇인지 잠깐 짚고 넘어가봅니다.

윈도 파워셸(Windows PowerShell)마이크로소프트가 개발한 확장 가능한 명령줄 인터페이스(CLI) 스크립트 언어이다. 객체 지향에 근거해 설계되고 있어 닷넷 프레임워크 2.0을 기반으로 하고 있다. 이전에는 마이크로소프트 셸(MSH, 코드네임 Monad)로 불리고 있었다.현재 윈도 XP, 윈도 서버 2003, 윈도 비스타, 윈도 서버 2008, 윈도 7, 윈도 8, 윈도 서버 2008 R2를 모두 지원한다.

위키백과에서 발췌한 내용입니다.

그냥 쉽게 말하면 리눅스의 bash 같은 쉘입니다.

파워쉘은 Windows에서 기본으로 제공하는데 여기에 쉘코드를 인젝션 시키는 것이 가능합니다.

이는 타겟 시스템의 기본 자원을 가지고 공격을 수행할 수 있다는 것을 의미합니다. 

실제 동작을 확인하기 위해 Metasploit으로 파워쉘용 쉘코드 스크립트를 작성해보겠습니다.

메시지박스를 실행시키는 페이로드를 불러온 뒤 파워쉘 스크립트로 저장합니다.

 

스크립트 파일이 생성되었습니다.

파워쉘을 실행시킨 뒤 생성된 내용을 그대로 붙여 넣기 합니다. 해당 코드는 x86이므로 wow64 파워쉘로 실행해야 합니다. (Windows x64의 경우)

(wow64 경로 : c:\windows\syswow64\windowspowershell\v1.0\powershell.exe)

 

아래는 결과입니다.

스크립트를 보면 알겠지만 쉘코드 스레드를 생성하여 실행시키는 간단한 내용입니다.

위의 스크립트를 페이로드로 활용하기엔 2% 부족합니다. 이를 Veil-Framework로 간단히 해결할 수 있습니다.

https://www.veil-framework.com/

Veil-Framework에서 제공하는 파워쉘 옵션과 다양한 페이로드를 결합하여 강력한 파워쉘 페이로드를 생성할 있습니다. 

첫 실행화면입니다. 39개의 페이로드가 로드되었다고 나옵니다. 이를 list 명령어로 확인할 수 있습니다.

이제부터 동일한 기능을 수행하는 페이로드를 생성할 것입니다.

파워쉘 쉘코드 인젝션을 이용할 것이므로 use 21을 입력합니다. 

 Generate를 입력합니다.

 디폴트 옵션을 사용합니다.

쉘코드를 선택하는데 tab 키를 누르면 리스트가 나타납니다. 그림과 같이 windows/messagebox 를 기입 후 적당한 값을 입력합니다.

 저장할 파일 이름을 입력합니다. 해당 파일은 bat확장자로 저장됩니다.

성공적으로 파일이 저장되었습니다.

해당 배치 파일을 실행하면 메시지박스 창이 나타납니다.

 

공격사례 : 작년에 발표된 "godmode" 익스플로잇입니다.

GradiusX, b33f 닉네임을 사용하는 해커들이 기존 발표된 익스플로잇에 파워쉘을 얹었습니다.

여기에 사용된 파워쉘은 위 실습 내용과 같으므로 패치되지 않은 IE 브라우저에서 실행해보시길 바랍니다.

http://www.exploit-db.com/exploits/35308/

프로세스 트리를 살펴보면 iexplore.exe -> powershell.exe 형태입니다.

이처럼 커맨드라인 RCE 공격 형태에서 매우 효과적인데, JRE 공격의 경우 대부분이 커맨드라인 형태이므로 유용할 것이라 생각됩니다.

 

이번에는 zip 파일 퍼징하는 방법을 포스팅 하겠습니다.

아래의 사이트를 토대로 테스트 하였습니다.

http://www.flinkd.org/2011/07/fuzzing-with-peach-part-1/

준비물 :

1. Peach 2.3.9 

작성된 plt이 2.3.9에서만 동작합니다. 이 버전에는 소스만 제공됩니다.

http://sourceforge.net/projects/peachfuzz/files/Peach/2.3.9/

2. Actice Python 2.7

http://www.activestate.com/activepython/downloads

3. 의존성 패키지

아래 파일들을 전부 다운로드합니다.

http://svn.code.sf.net/p/peachfuzz/svn/branches/Peach2.3/dependencies/py2.7-win32/

4. zip plt 파일

zip을 퍼징하기 위한 plt 파일입니다. 주요 경로 및 프로그램을 자신의 환경에 맞게 설정합니다. 

zip.xml

5. 타겟 프로그램

command 명령이 가능한 zip 프로그램을 사용하시면 됩니다.

 


 

Active Python 2.7을 설치 후, 의존성 패키지의 install.bat을 실행하면 패키지들이 한 번에 설치됩니다.

퍼징 전에 유효성 검사를 해보아야 합니다.

peach.bat -t zip.xml

만약 SEED 문제가 발생한다면,

<Strategy class="rand.RandomMutationStrategy" switchCount="1500" maxFieldsToMutate="7"/>

해당 라인을 제거해 주세요. 제거하지 않아도 퍼징은 가능합니다.

Peach Fuzzer는 매우 강력한 퍼징 프레임워크 입니다.

wav/pdf/doc 등 다양한 포맷을 퍼징할 수 있고, WinDbg와 연동하여 상세한 크래쉬 정보를 볼 수 있습니다.

본 포스팅을 따라하면  wav 포맷을 가지고 간단한 퍼징을 실습할 수 있습니다.

우선 .NET Framework 4와 WinDbg, Peach Fuzzer가 필요합니다.

저는 Windows 7 x64에서 테스트했으므로 WinDbg x64를 설치하였습니다. 정상 동작하기 위해선 반드시 64비트엔 64비트 디버거를 설치하여야 합니다.

다운로드 ::

Debugging Tools for Windows (x86) version 6.12.2.633

Debugging Tools for Windows (x64) version 6.12.2.633

http://peachfuzzer.com/ 


퍼징 준비물

1. WAV 플레이어

퍼징 타겟은 Sounder라는 프로그램으로 Command Line에서 재생 가능하고, 심플합니다.

http://www.elifulkerson.com/projects/commandline-wav-player.php

 

2. WAV 파일

퍼징을 위한 wav 샘플 파일입니다. 다운로드 한 뒤 Sounder.exe와 같은 디렉토리에 넣어주세요.

 sample.zip

 

3. PIT 파일

퍼징을 하기 위한 Peach XML 파일입니다. 뮤테이션 할 오프셋을 설정할 수 있습니다. 다운로드 한 뒤 peach 설치 디렉토리에 넣어주세요.

1.xml

본 파일을 다운로드 한 뒤 약간의 수정이 필요합니다.

<Data fileName="d:\\sample_fuzzer\\sample.wav"/>

<Param name="CommandLine" value="D:\\sample_fuzzer\\sounder.exe fuzzed.wav" />

<Param name="Executable" value="D:\\sample_fuzzer\\sounder.exe"/>

<Param name="WinDbgPath" value="C:\\Program Files\\Debugging Tools for Windows (x64)" />

빨간 부분을 자신의 경로에 맞게 수정합니다. WinDbgPath는 두 군데 수정하여야 합니다. 


이제 퍼징을 할 차례입니다.

cmd.exe를 관리자 권한으로 실행합니다.

d:\peach> peach 1.xml

이렇게 한 줄 입력하면 퍼징이 시작됩니다.

 

각종 로그는 logs 디렉토리에서 확인하면 됩니다.

자세한 튜토리얼은 http://old.peachfuzzer.com/v3/TutorialFileFuzzing.html 에서 확인하실 수 있습니다.

 

 

 

 

MiniFuzz는 마이크로소프트에서 제작된 파일 퍼징 툴입니다.

매우 단순한 툴이므로, ZIP/HWP/PDF 와 같이 정형화 된 파일 포맷을 가진 경우는 이 툴을 사용하여 만족할 만한 결과를 얻어낼 수 없습니다.

가장 심플한 버퍼 오버플로우 유발 예제를 가지고 퍼징 테스트를 해보겠습니다.

 target_fuzzer.exe

return 시 address를 덮어 씌우는 전형적인 BoF 예제입니다.

 

사용방법은 매우 간단합니다.

Browse로 타겟을 선택하고, Start Fuzzing 을 누르면 끝입니다.

퍼징 중 Access Violation을 잡아내면 로그가 남게 됩니다.

 

보다 자세한 사항은 로그파일에 남게 되는데, 그림의 logs 디렉토리에 로그가 남습니다.

 

<클릭하면 확대됩니다>

크래쉬 당시의 다양한 정보가 로그에 남게됩니다. 어느 파일을 가지고 퍼징을 했는지도 기록되는데요, 해당 샘플은 crashes 디렉토리에 있습니다.

 

 

 

 

본 포스팅은 기존 제작된 익스플로잇을 무작정 따라하는 내용을 담고 있습니다.

(천만 스크립트 키드 양성을 위한 그날까지..!) 

 


 

유형 : Stack Buffer Overflow

타겟 프로그램 : BlazeDVD Pro Player 6.1

테스트 환경 : Windows XP SP3 Eng

링크 : http://www.exploit-db.com/exploits/32737/ (제작자 : Deepak Rathore)

설명 : Playlist를 열때 Stack Buffer Overflow를 일으킵니다.


[재현]

  

[그림1 - 프로그램 실행 화면]

 

링크에서 타겟 프로그램과 Exploit을 다운로드 합니다.

Perl 설치가 귀찮으신 분은blazeExpl.plf<-- 이것을 다운로드 해 주세요.

 

[그림2 - Playlist Exploit 파일]

해당 파일을 Hex Editor로 열면 위의 그림과 같이 나옵니다.

위의 박스친 부분의 주소를 사용자PC에 맞게 고쳐줘야 하는데, ASLR이 적용되지 않은 모듈에서 jmp esp를 찾으면 됩니다.

 

[그림3 - JMP ESP 찾기]

저는 0x7C86467B에 있는 jmp esp를 사용했습니다.

 

[그림4 - Exploit 성공]

Playlist 를 열어서 그림4와 같이 나오면 성공입니다.

[분석] 

[그림5 - 버퍼를 스택에 복사]

Playlist를 로드하면 위의 코드에서 스택에 Playlist의 버퍼를 복사합니다. 

(스샷을 연속적으로 찍지 않아서 스택의 주소가 그림마다 다릅니다. 양해를..)

[그림6 - 스택 비교]

위의 그림은 스택 버퍼가 쓰여지기 전과 후의 모습입니다.

 [그림7 - RETN]

계속해서 Step over를 하면 최종적으로 그림7과 같은 코드를 만나게 되어 리턴합니다.

 

[그림 8 - RETN 시 스택]

RETN 직전 스택을 보면 ESP가 0x7C86467B를 가리키고 있는데 해당 주소는 JMP ESP 를 담고 있습니다.

말 그대로 ESP로 점프하라는 것이며, 한번 더 Step over 하면 스택에 0x10이 더해진 0x12F0D0으로 이동합니다.

 

[그림 9 - 쉘코드]

NOP후 쉘코드가 실행됩니다.

테스트 환경 : Windows XP SP3 Eng / Python 2.7.1

관련 링크 : http://www.exploit-db.com/exploits/32585/

취약점 유발 파일 :victim.m3u

 

해당 취약점은 Read Only 영역에 Writing을 시도할 때 발생합니다. (즉, stack limit를 뚫고 입력하는 상황)

PoC를 실행시키면 victim.m3u가 생성되는데, 이것을 AudioCoder에 넣고 돌리면 계산기가 실행됩니다.

정크 코드 'A'에 걸려서 메모리가 뻑난(?) 모습입니다. 해당 영역은 Read Only 입니다.

 

SEH 를 확인해보니 Overwrite 되었습니다. 바로 쉘코드로 점프합니다.

 

 

브라우저 취약점 쉘코드를 작성하여, html의 unescape 부분에 %ue8fc%u00c3%u0000%u8960 이런 형태로 붙여넣었습니다. 그런데 작동이 되지 않았습니다.

원인을 찾아봤는데, bad character라고 하여 \x00 이 들어가면 동작이 되지 않던 것이었습니다.

이는 메타스플로잇에서 공개한 브라우저 취약점 공격 PoC에서도 확인할 수 있습니다.

http://www.exploit-db.com/exploits/23785/

 

 

아래는 메타스플로잇에서 제공하는 어셈블리어 코드로 쉘코드를 생성하는 방법입니다. LoadLibrary기능을 하는 쉘코드이며, generate 로 생성이 가능합니다. bad char 0x00 이 포함되어있어서 브라우저에서 정상동작하지 않습니다. 

https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/single/single_loadlibrary.asm

그대로 디버거에 붙여넣은 화면입니다.  

 

아래는 옵션을 주어 0x00을 제거하였습니다. 디폴트로 시카타가 나이라는 인코더가 선택됩니다. (일본어로, "어쩔수가 없지". 이름을 재미있게 지었군요. 

 그대로 디버거에 붙여넣은 화면입니다.  

디코더가 처음 부분에 삽입되어 있어서 한 라인씩 실행하다 보면, 평문으로 복호화가 됩니다. 

# 쉘코드 인코딩 하는 방법

msfencode라는 프로그램이 내장되어 있습니다.

옵션 설명

-e x86/shikata_ga_nai : 인코더 선택

-b '\x00' : Bad Character 제거

-i /root/loadlibrary.bin : 경로명 (쉘코드를 바이너리로 저장해주세요)

-t c : C언어 변수 타입으로 출력

 Windows 7은 기본적으로 DLL이 랜덤한 주소로 매핑되지만, 컴파일 시 고정된 주소를 설정할 수 있습니다. JAVA 1.6버전의 MSVCR71.dll이 그 대표적인 예 인데, 항상 0x7C340000에 매핑됩니다.

EMET 에는 MandatoryASLR이라는 기능이 있는데, 이 옵션을 키면 NON-ASLR DLL을 랜덤한 주소로 매핑시켜 줍니다.

이렇게 주소가 바뀌게 되면, ROP 시 NON-ASLR DLL을 사용할 수 없게 됩니다.

 

 

+ Recent posts