
간접 동적 시스템 콜, 수정된 TartarusGate 방식을 통한 SSN + 시스템 콜 주소 정렬 + APC Early Bird를 통한 원격 프로세스 인젝션 + 희생 프로세스를 대상 프로세스로 생성 + 생성된 프로세스에 (ACG+BlockDll) 완화 정책 적용 + PPID 스푸핑 + TIB에서 API 해석 + API 해싱
Windows를 대상으로 하는 사용자 정의 가능한 드로퍼 도구입니다.
단점: 스레드가 재개되면 이벤트 로거 중단 중에 발생한 모든 이벤트가 다시 기록됩니다!
그래서 대신 종료하는 것을 생각했습니다!
"중단보다 더 침습적이지만 결정은 항상 운영자에게 달려 있습니다. 게다가 스레드를 종료하면 커널 수준에서 기록됩니다." - @SEKTOR7net
VS 컴파일러를 통해 직접:


./compile.bat
PS C:> .\x64\Release\indirect.exe
[!] Wrong!
[->] Syntax: .\x64\Release\indirect.exe <PPID to spoof>
https://github.com/reveng007/DarkWidow/assets/61424547/62a90c5b-84af-4389-8ddc-9f7926debdcf

TIB:
GS 및 FS 레지스터:
PEB LDR 구조:
TIB -> TEB -> PEB -> Nt API 해결 및 API 해싱
https://stackoverflow.com/questions/41277888/iterating-over-peb-dllname-shows-only-exe-name
https://doxygen.reactos.org/d7/d55/ldrapi_8c_source.html#l01124
위 링크의 코드 조각 사진으로, 오프셋을 하드코딩하지 않고 API를 동적으로 해결하는 데 사용했습니다:

적용한 API 해싱 코드:
#include <stdint.h>
#include <stdio.h>
#include <Windows.h>
DWORD64 djb2(const char* str)
{
DWORD64 dwHash = 0x7734773477347734;
int c;
while (c = *str++)
dwHash = ((dwHash << 0x5) + dwHash) + c;
return dwHash;
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("[!] Wrong!\n");
printf("[->] Syntax: .\\%s <NTFuncName>\n\n", argv[0]);
return 1;
}
const char* string = argv[1];
DWORD64 hashvalue = djb2(string);
printf("Hash Value: 0x%llX\n", hashvalue);
return 0;
}
ACG(Arbitrary Code Guard)/BlockDll 완화 정책:

PPID 스푸핑 탐지:
Moneta 탐지 및 PESieve 탐지:\
Moneta:

PESieve:

Capa 스캔:

임플란트 프로세스의 스레드 스택 모양:
| 임플란트 프로세스 | 정상 Cmd 프로세스 |
|---|---|
![]() | ![]() |
"간접 시스템 콜 POC에서 ntdll.dll 메모리 내에서 반환 명령을 실행함으로써 반환 주소를 성공적으로 스푸핑하고, ntdll.dll을 호출 스택 최상단에 배치하여 EDR이 더 높은 합법성을 해석하도록 할 수 있습니다." - @VirtualAllocEx의 DirectSyscall Vs Indirect Syscall
또한 @peterwintrsmith님께 감사드립니다!


다음으로:
