Brain Dump:Metasploit
From Matt's Network Monitor
Digging around through the Metasploit (msfweb) code, I discovered how to embed the Metasploit framework into this Rails project. For my own reference, in config/environment.rb, the following lines do the trick:
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__ $:.unshift(File.join(File.dirname(msfbase), '..', '..', '..', 'lib')) require 'rex' require 'msf/ui' require 'msf/base' $msfweb = Msf::Ui::Web::Driver.new({'LogLevel' => 5}) $msframework = $msfweb.framework
The second line denotes the path to the MSF lib/ directory, in this case, relative to the db/environment.rb file.
At first glance, it looks like the "autopwn" command is only accessible after you've spawned a msfconsole. The method responsible for autopwn is responsive to command line arguments. It may be possible to execute autopwn in one of two ways:
- Wrap command line calls to msfconsole and wait for stdout response
- Mimic cmd_db_autopwn behavior (lib/msf/ui/console/command_dispatcher/db.rb) in our own class - ideal
- Force ARGV data to cmd_db_autopwn method.
[edit] Populating Metasploit DB w/ Existing nmap XML Data
The Metasploit load_nmap_xml method requires an XML document in the form of:
- nmaprun
- host
- address (w/ addr attribute)
- ports
- port (w/ protocol and portid attributes)
- service (w/ name attribute)
- state
- port (w/ protocol and portid attributes)
- host
Rather than taking the nmap XML output and saving the relevant XML data, we could generate a single /nmaprun/host on the fly with the data we already populated in our database. Even better, however, is if we just do the following through our own data:
Pseudocode:
ports.each do | port | next if port.status != "open" next if port.service.empty? addr = port.host_id.ipaddr prot = port.protocol.downcase pnum = port.port.to_i name = port.service host = framework.db.get_host(nil, addr) next if not host service = framework.db.get_service(nil, host, prot, pnum) service.name = name service.save end
[edit] Vulnerability reference matching
The code below is used to find exploits matching a reference. The matches hash that is build is used to test against all hosts in the datastore. Reference matching will only work if Nessus vulnerability data exists in the Metasploit framework datastore.
[ [framework.exploits, 'exploit' ], [ framework.auxiliary, 'auxiliary' ] ].each do |mtype| mtype[0].each_module do |n,m| e = m.new e.references.each do |r| ref_name = r.ctx_id + '-' + r.ctx_val ref = framework.db.has_ref?(ref_name) if (ref) # append matches hash for autopwn later end end end end
"ref_name: CVE-2006-0900" "ref_name: CVE-2007-2446" "ref_name: CVE-2007-2446" "ref_name: CVE-2005-4797" "ref_name: BID-14510" "ref_name: OSVDB-18650" "ref_name: URL-http://sunsolve.sun.com/search/document.do?assetkey=1-26-101842-1" "ref_name: URL-http://archives.neohapsis.com/archives/fulldisclosure/2007-12/0440.html" "ref_name: BID-20804" "ref_name: CVE-2006-5614" "ref_name: CVE-2005-2120"
For first-pass exploit scanning, we can only test against default ports when we've just got nmap output to work with:
rport = e.datastore['RPORT'] if (rport) framework.db.services.each do |serv| next if not serv.host next if serv.port.to_i != rport.to_i xport = serv.port xprot = serv.proto xhost = serv.host.address next if (targ_inc.length > 0 and not range_include?(targ_inc, xhost)) next if (targ_exc.length > 0 and range_include?(targ_exc, xhost)) matches[[xport,xprot,xhost,mtype[1]+'/'+n]]=true end end end
