Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
HintInject — Hint/Name Table에 shellcode를 임베딩하기 위한 PoC 프로젝트 | Kitploit
도구/GitHubGitHub/frkngksl/hintinject
Payload GenerationExploitationShellcodePenetration TestingBinary AnalysisPayload Development
GitHubfrkngksl/hintinject

HintInject

Hint/Name Table에 shellcode를 임베딩하기 위한 PoC 프로젝트

저장소 보기
1142225개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

HintInject

HintInject은 제가 PE 파일과 Import Directory Table 구조를 가지고 실험하면서 개발한 셸코드 임베더 및 로더입니다. 로더 실행 파일에 가짜로 추가된 DLL 엔트리의 Import Lookup Table을 통해 접근 가능한 Hint/Name Table 항목에 셸코드를 덩어리로 넣습니다. 로더는 이 덩어리들을 병합하여 셸코드를 실행합니다. 이 기술이 새로운 것인지는 모르지만 재미로 공유하고 싶었습니다.

DLL 로딩 프로세스

HintInject가 어떻게 작동하는지 설명하기 전에, Stack Overflow의 게시물을 참고하여 DLL 로딩 프로세스에 대해 간략히 언급하고자 합니다.

필요한 DLL 및 함수/임포트에 대한 정보를 얻으려면 먼저 Import Directory Table을 살펴봐야 합니다. Import Directory Table은 항목들의 테이블로, 임포트된 각 DLL마다 하나의 항목이 있습니다. 이러한 항목들은 임포트된 DLL 이름에 대한 포인터, Import Lookup Table에 대한 포인터, Import Address Table에 대한 포인터 및 기타 다양한 정보 필드를 포함합니다.

간단히 말해, Import Lookup Table은 임포트에 대한 정보를 가리키고, Import Address Table은 임포트의 주소를 가리킵니다. 그러나 실행 파일이 디스크에 있을 때, 즉 DLL 로딩 프로세스 직전에는 Import Address Table이 Import Lookup Table과 동일합니다. Import Address Table의 내용은 DLL 로딩 프로세스 중에 임포트의 주소로 덮어씌워집니다.

자세한 내용은 생략하고, 아래 다이어그램을 통해 세 테이블 간의 관계를 살펴볼 수 있습니다.

조금 더 자세히 들어가면, Import Lookup Table은 임포트 이름을 직접 보유하지 않습니다. 이름으로 임포트되는 함수의 경우, Hint/Name Table 항목의 RVA를 보유합니다. 이러한 항목은 함수 이름을 Null 종료 ASCII 문자열로 저장합니다. 따라서 Hint/Name Table 항목의 구조체 정의는 다음과 같습니다:

root@kitploit:~
typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 

여기서 Hint 필드는 실제로 DLL의 내보내기 이름 포인터 테이블에 대한 인덱스입니다. 해당 임포트의 위치를 찾는 속도를 높이는 데 사용됩니다. 따라서 아래 다이어그램으로 Import Lookup Table과 Hint/Name Table 간의 관계를 요약할 수 있습니다.

결론적으로, DLL과 그 임포트를 찾으려면 다음 단계를 따라야 합니다:

  1. Optional Header의 DataDirectory 배열에서 Import Directory Table로 이동합니다.
  2. 이름 필드를 확인하여 원하는 DLL을 찾기 위해 Import Directory Table 항목을 탐색합니다.
  3. 올바른 항목을 찾은 후 OriginalFirstThunk 필드를 사용하여 해당 Import Lookup Table로 이동합니다.
  4. Import Lookup Table의 모든 항목(각각 Hint/Name Table 항목에 대한 포인터)을 탐색합니다.
  5. Hint/Name Table 항목의 Name 필드에서 임포트 이름을 확인합니다.

HintInject는 어떻게 작동하나요?

최근에 x86matthew가 공유한 ImportDLLInjection 기술을 조사하면서, 메모리에 로드된 DLL의 Import Directory에 가짜 항목을 추가하는 방법을 보게 되었습니다. 그 후, 디스크에 있는 바이너리의 임포트 테이블에 직접 가짜 항목을 추가하는 작은 프로젝트를 재미와 지식 복습을 겸해 개발하고 싶었습니다. 이 프로젝트를 개발하기 위해 DLL 로딩 프로세스를 검토하는 과정에서, 이 프로세스에 사용되는 Hint/Name Table 항목의 Hint 필드가 눈에 띄었습니다.

MSDN 문서에 따르면, 이 필드는 Windows Loader가 이름으로 임포트된 해당 임포트의 주소를 DLL의 내보내기 이름 테이블에서 직접 찾는 데 사용된다고 배웠습니다. 그러나 같은 문서에서 이 필드를 사용하여 함수를 찾을 수 없는 경우, 해당 함수는 DLL의 내보내기 이름 테이블에서 이진 검색을 통해 검색된다고 명시되어 있었습니다. 이 문장을 바탕으로, 이 필드에 잘못된 값을 넣어도 DLL 로딩 프로세스에 문제가 생기지 않을 것이라고 생각했습니다.

위에서 언급했듯이, 임포트할 각 함수에 해당하는 Hint/Name 테이블 항목이 있습니다. 즉, 각 임포트마다 사용 가능한 2바이트가 있습니다. 여러 임포트를 결합하면 악성 셸코드를 저장할 수 있을 만큼 충분한 Hint 필드를 얻을 수 있습니다. 결과적으로, 로더 바이너리를 사용하여 가짜 임포트 DLL 항목의 Hint/Name 항목에 셸코드를 임베드할 수 있습니다. 해당 로더 바이너리는 런타임에 실행될 셸코드를 병합하기 위해 이러한 항목에 접근할 수 있습니다.

HintInject는 Hint/Name 테이블에 셸코드를 보유하는 이러한 로더를 생성하는 데 사용할 수 있습니다. 먼저 .rrdata라는 새 섹션을 만들고 현재 임포트 디렉터리를 이 섹션에 복사합니다. 그런 다음, 해당 임포트가 입력 셸코드를 보유하는 데 사용될 새로운 가짜 항목을 추가합니다. 섹션의 나머지 바이트는 새 가짜 항목의 Import Lookup Table, Import Address Table, DLL 이름 및 Hint/Name 테이블을 저장하는 데 사용됩니다. 마지막 단계로, HintInject는 임포트의 Hint 필드를 사용하여 입력 셸코드의 덩어리를 배치합니다.

로더 바이너리의 임포트 예시:

Screen Shot 2022-05-08 at 11 43 42

사용법

  1. Release 옵션으로 프로젝트를 빌드합니다.
  2. 원시 형식의 셸코드와 출력 경로를 사용하여 HintInject.exe를 실행하여 셸코드 로더를 만듭니다: HintInject.exe <Shellcode File> <Output Name>
  3. 로더를 실행하여 셸코드를 직접 실행하거나, PID를 제공하여 셸코드를 인젝션할 수 있습니다: Loader.exe <PID>
  4. 원한다면 HintInjectLoader/Main.cpp 파일의 InjectShellcode 함수를 수정하여 셸코드 인젝션 방법을 변경할 수 있습니다.

Windows 10 19044 및 Visual Studio 2019에서 테스트함:

제한사항

  1. 셸코드를 실행하는 로더의 가짜 DLL 항목과 관련하여, DLL과 임포트된 함수 이름이 모두 실제로 존재해야 합니다. 그렇지 않으면 로더 실행 파일을 시작할 때 Missing DLL 오류가 발생합니다. 따라서 프로젝트에서 System32 아래의 몇 가지 합법적인 DLL을 사용했습니다.
  2. 셸코드 크기가 더 커서 셸코드용 로더를 생성할 수 없는 경우, DllNamesForFakeImports.h 파일의 dllNames 배열에 다른 DLL을 추가할 수 있습니다.
  3. 생성된 각 로더에 대해 임포트된 함수는 무작위로 선택됩니다. 그러나 가짜 항목을 만드는 데 사용되는 DLL의 순서를 변경하려면 DllNamesForFakeImports.h 파일의 dllNames 배열도 편집해야 합니다. 기본적으로 HintInject는 배열 순서에 따라 DLL에서 함수를 선택합니다. 즉, 도구는 먼저 user32.dll에서 내보낸 함수를 선택하고, 셸코드 크기가 2 * user32.dll 내보내기 수보다 크면 advapi32.dll 및 다른 DLL의 내보내기도 사용하기 시작합니다.
root@kitploit:~
static LPCSTR dllNames[] = {"user32.dll","advapi32.dll","gdi32.dll","wininet.dll","comctl32.dll","shell32.dll","wsock32.dll","oleaut32.dll","ws2_32.dll","urlmon.dll"};

참고자료

  • https://stackoverflow.com/questions/32841368/whats-the-difference-between-the-import-table-import-adress-table-and-import
  • https://0xrick.github.io/win-internals/pe6/
  • https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#hintname-table
  • https://www.x86matthew.com/view_post?id=import_dll_injection

면책 조항

승인된 보안 테스트 용도로만 사용하십시오. 명시적 허가 없이 시스템에 이 도구를 오용하는 것은 불법입니다.

도구 다운로드