Chapter 2. The Network: Basics
The network is and always will be the sexiest arena for a hacker. 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. But if you are an attacker who has worked your way into the deepest depths of an
enterprise target, you may find yourself in a bit of a conundrum: you have no tools to execute network
attacks. No netcat. No Wireshark. No compiler and no means to install one. However, you might be
surprised to find that in many cases, you’ll find a Python install, and so that is where we will begin.
This chapter will give you some basics on Python networking using the
socket
[
5
]
module. Along the
way, we’ll build clients, servers, and a TCP proxy; and then turn them into our very own netcat,
complete with command shell. 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. Let’s get started.
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
. This module exposes all of the necessary pieces
to quickly write TCP and UDP clients and servers, use raw sockets, and so forth. For the purposes of
breaking in or maintaining access to target machines, this module is all you really need. Let’s start by
creating some simple clients and servers, the two most common quick network scripts you’ll write.
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. If you are working within the
confines of large enterprise environments, you won’t have the luxury of networking tools or
compilers, and sometimes you’ll even be missing the absolute basics like the ability to copy/paste or
an Internet connection. This is where being able to quickly create a TCP client comes in extremely
handy. But enough jabbering — let’s get coding. Here is a simple TCP client.
import socket
target_host = "www.google.com"
target_port = 80
# create a socket object
➊ client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect the client
➋ client.connect((target_host,target_port))
# send some data
➌ client.send("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")
# receive some data
➍ response = client.recv(4096)
print response
We first create a socket object with the
AF_INET
and
SOCK_STREAM
parameters ➊. 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. We then connect the client to the server ➋ and send it some
data ➌. The last step is to receive some data back and print out the response ➍. This is the simplest
form of a TCP client, but the one you will write most often.
In the above code snippet, we are making some serious assumptions about sockets that you definitely
want to be aware of. The first assumption is that our connection will always succeed, and the second
is that the server is always expecting us to send data first (as opposed to servers that expect to send
data to you first and await your response). Our third assumption is that the server will always send us
data back in a timely fashion. We make these assumptions largely for simplicity’s sake. 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.
|