UDP Client - Black Hat Python

UDP Client
A Python UDP client is not much different than a TCP client; we need to make only two small changes
to get it to send packets in UDP form.
import socket
target_host = "127.0.0.1"
target_port = 80
# create a socket object
➊ client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# send some data
➋ client.sendto("AAABBBCCC",(target_host,target_port))
# receive some data
➌ data, addr = client.recvfrom(4096)
print data
As you can see, we change the socket type to
SOCK_DGRAM
➊ when creating the socket object. The
next step is to simply call
sendto()
➋, passing in the data and the server you want to send the data
to. Because UDP is a connectionless protocol, there is no call to
connect()
beforehand. The last
step is to call
recvfrom()
➌ to receive UDP data back. You will also notice that it returns both the
data and the details of the remote host and port.
Again, we’re not looking to be superior network programmers; we want to be quick, easy, and
reliable enough to handle our day-to-day hacking tasks. Let’s move on to creating some simple
servers.
TCP Server
Creating TCP servers in Python is just as easy as creating a client. You might want to use your own
TCP server when writing command shells or crafting a proxy (both of which we’ll do later). Let’s
start by creating a standard multi-threaded TCP server. Crank out the code below:
import socket
import threading
bind_ip = "0.0.0.0"
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
➊ server.bind((bind_ip,bind_port))
➋ 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.recv(1024)
print "[*] Received: %s" % request
# send back a packet
client_socket.send("ACK!")
client_socket.close()
while True:
➍ client,addr = server.accept()
print "[*] Accepted connection from: %s:%d" % (addr[0],addr[1])
# spin up our client thread to handle incoming data
client_handler = threading.Thread(target=handle_client,args=(client,))
➎ client_handler.start()
To start off, we pass in the IP address and port we want the server to listen on ➊. Next we tell the
server to start listening ➋ with a maximum backlog of connections set to 5. We then put the server
into its main loop, where it is waiting for an incoming connection. When a client connects ➍, we
receive the client socket into the
client
variable, and the remote connection details into the
addr
variable. 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. We then start the thread to handle the client connection ➎,
and our main server loop is ready to handle another incoming connection. The
handle_client
➌
function performs the
recv()
and then sends a simple message back to the client.
If you use the TCP client that we built earlier, you can send some test packets to the server and you
should see output like the following:
[*] Listening on 0.0.0.0:9999
[*] Accepted connection from: 127.0.0.1:62512
[*] Received: ABCDEF
That’s it! Pretty simple, but this is a very useful piece of code which we will extend in the next couple
of sections when we build a netcat replacement and a TCP proxy.
|