python-programming-for-blackhats-2024-08-04-03-39-43
python-programming-for-blackhats-2024-08-04-03-39-43
Python Programming
for Black Hat
by 7cryx
AUTHOR DETAILS
Instagram : @7cryx
email : work7cryx@gmail.com
4
Table of Contents
Python Programming for Black Hat.................................................................................................... .2
Building a TCP Client in python ....................................................................................................... .5
Summary.............................................................................................................................................22
Building a UDP Client........................................................................................................................23
Summary.............................................................................................................................................29
Building a TCP Server........................................................................................................................30
Summary.............................................................................................................................................38
Intro to Replacing Netcat....................................................................................................................39
Summary.............................................................................................................................................50
Building a TCP Proxy.........................................................................................................................52
Summary.............................................................................................................................................60
5
socket.py
The socket module provides access to the BSD socket interface, which is
commonly used for networking-related tasks.
Here, we define the target host as "localhost" and the target port as 80.
"localhost" refers to the local machine, and port 80 is the default port for
HTTP.
This line connects the client socket to the specified target host and port using
the connect() method of the socket object.
Here, we send an HTTP GET request to the server. We encode the request string
to bytes using b"..." since sockets deal with bytes, not strings. The request
consists of the HTTP method ( GET), the requested path ( /), the HTTP version
(HTTP/1.1), and the Host header specifying the target host. \r\n
represents a carriage return and a line feed, which are used to terminate lines in
HTTP headers.
# Send some data to the client & \r\n use for line spacing
client.send( b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" )
This line receives the response from the server. It uses the recv() method of
the socket object to receive up to 4096 bytes of data from the server.
Finally, we close the connection to the server using the close() method of
the socket object.
client.close()
7
import socket
# Send some data to the client & \r\n use for line spacing
client.send(b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")
client.close()
Running nc -lvnp 80 starts netcat ( nc) in listen mode ( -l) on port 80 (-
p 80) for TCP connections ( -n). The -v option is used for verbose mode,
providing more detailed output. This command essentially sets up a simple
server that listens for incoming TCP
8
Let's expand the code to include more advanced features and increase its
complexity.
#importing modules
import asyncio
import ssl
import socket
import logging
from concurrent.futures import ThreadPoolExecutor
9
import asyncio
import asyncio
import aiohttp
if __name__ == "__main__":
asyncio.run(main())
11
In this example:
1. We define an async function fetch_page that asynchronously
fetches the content of a given URL using the aiohttp library. This
function takes an aiohttp.ClientSession object as an argument,
which allows us to reuse the same session for multiple requests.
2. We define another async function fetch_all_pages that takes a
list of URLs as input and asynchronously fetches the content of all the
URLs using fetch_page.
3. The main coroutine creates a list of URLs to fetch and then calls
fetch_all_pages to fetch the pages asynchronously.
4. Finally, we print the content of each fetched page.
This example demonstrates how to use asyncio to orchestrate asynchronous
operations and aiohttp to perform HTTP requests asynchronously. It allows
you to efficiently fetch multiple web pages concurrently, improving
performance and responsiveness.
import ssl
The ssl module in Python provides functions and classes for working with
SSL (Secure Sockets Layer) and TLS (Transport Layer Security) protocols,
allowing you to create secure network connections over the internet.
Here's a brief overview of the main components and features of the ssl
module:
1. SSL Contexts: SSL contexts ( ssl.SSLContext) represent the
configuration for SSL/TLS connections, including options for certificate
verification, encryption algorithms, and protocol versions.
2. SSL Certificates : SSL certificates are used to authenticate servers and
clients during the SSL/TLS handshake process. The ssl module
provides functions for loading, validating, and managing certificates.
12
3. Secure Socket Operations : The ssl module extends the socket API to
support secure socket operations ( ssl.wrap_socket()), allowing
you to create SSL/TLS-encrypted socket connections for secure
communication.
4. Protocol Versions and Cipher Suites : SSL contexts allow you to specify
the SSL/TLS protocol versions ( ssl.PROTOCOL_TLS) and cipher
suites (ssl.CIPHER_SUITE) to use for secure communication.
Server Side:
import ssl
import socket
while True:
client_socket, address = server_socket.accept()
print(f"Connection from {address}")
13
# Close connection
client_socket.close()
Client Side :
import ssl
import socket
# Close connection
client_socket.close()
In this example:
14
import logging
import logging
# Configure logging
logging.basicConfig(
level=logging.DEBUG, # Set the logging level to DEBUG
format="%(asctime)s - %(levelname)s - %(message)s", # Define the log
message format
filename="app.log", # Specify the log file name
filemode="w" # Set the file mode to write (overwrite existing content)
)
# Create a logger
logger = logging.getLogger("my_logger")
# Log messages
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
In this example:
16
When you run this code, it will log messages to both the console (stdout) and
the app.log file. You can customize the logging behavior by adjusting the
logging level, format, output destination, and other configuration options to suit
your needs.
def task(n):
time.sleep(n)
return f"Task {n} completed"
def main():
with ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, n) for n in range(1, 6)]
for future in futures:
print(future.result())
if __name__ == "__main__":
main()
In this example:
3. We submit multiple tasks (task function calls) to the executor using the
submit method, which returns a Future object representing the result
of each task.
4. We iterate over the list of Future objects and use the result method
to retrieve the result of each task. The result method blocks until the
task completes and returns the result.
import asyncio
import ssl
import socket
import logging
from concurrent.futures import ThreadPoolExecutor
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class TCPClient:
def __init__(self, hostname, port, message):
self.hostname = hostname
self.port = port
self.message = message
self.pool = ThreadPoolExecutor(max_workers=5)
This code is a Python script that demonstrates how to create multiple TCP client
instances using asyncio for asynchronous I/O. Each client connects to a server
using SSL/TLS encryption, sends a message, and then receives and logs the
response.
Here's a breakdown of the code:
1. Import necessary modules: asyncio, ssl, socket, logging, and
ThreadPoolExecutor from concurrent.futures.
2. Set up logging: Configure logging to display log messages with a level of
INFO or higher.
3. Define a TCPClient class: This class represents a TCP client. It takes a
hostname, port, and message as input. It uses
asyncio.open_connection() to establish a connection to the
server with SSL/TLS encryption.
4. The connect method tries to establish a connection to the server. If
successful, it returns the reader and writer objects for sending and
receiving data. If an error occurs, it logs the error message.
5. The send_message method sends the message to the server and waits
for a response. It logs the received data.
6. The run method coordinates the execution of the connect and
send_message methods. It connects to the server, sends the message,
and then closes the connection.
7. Define the main coroutine: This coroutine creates multiple instances of
the TCPClient class, each representing a separate TCP client. It runs
these clients concurrently using asyncio.gather().
21
Output :
Hello, World!
22
********************************************************************************
Summary
The chapter on TCP client implementation in Python explores the development
of a robust and efficient client-side application for communication over the TCP
protocol.
Beginning with an introduction to the necessary modules such as asyncio, ssl,
and socket, the chapter delves into the creation of a TCPClient class. This class
encapsulates the functionality required for establishing connections to servers,
sending messages, and handling responses asynchronously.
The TCP client utilizes asyncio to enable asynchronous I/O operations,
allowing for concurrent execution of multiple client instances. SSL/TLS
encryption is incorporated to ensure secure communication between the client
and server, enhancing data confidentiality and integrity.
Furthermore, the chapter demonstrates the integration of logging to facilitate
debugging and monitoring of the client's operation. By providing informative
log messages, developers gain insights into the connection process, message
transmission, and response handling.
Overall, the chapter equips readers with the knowledge and practical skills
needed to develop efficient TCP client applications in Python, leveraging
asynchronous programming, SSL/TLS encryption, and logging for enhanced
functionality and security.
********************************************************************************
23
UDP clients are often used in scenarios where speed and efficiency are
prioritized over reliability, such as in real-time multimedia applications or when
transmitting small amounts of data. However, since UDP does not provide built-
in mechanisms for error detection, correction, or flow control, developers need
to implement these features at the application level if required.
24
import socket
def main():
# Define the server address and port
server_address = "127.0.0.1" # Change this to the server's IP address
server_port = 12345 # Change this to the server's port
if __name__ == "__main__":
main()
an arbitrary port number chosen for communication with the server. You
would change these values to match the IP address and port of the UDP
server you want to communicate with.
4. Creating a UDP socket: The socket.socket() function is called
with socket.AF_INET to specify IPv4 addressing and
socket.SOCK_DGRAM to specify that this is a UDP socket. This
creates a UDP socket object called client_socket.
To make the UDP client even more advanced, we can implement multithreading
to handle both sending and receiving data simultaneously. This allows the client
to be more responsive and efficient. Here's an updated version of the code with
multithreading:
26
import socket
import threading
def receive_data(client_socket):
while True:
try:
# Receive data from the server
response, server_address = client_socket.recvfrom(1024)
print("Response from server:", response.decode())
except socket.timeout:
continue
except socket.error as e:
print("Error:", e)
break
def main():
# Define the server address and port
server_address = input("Enter the server address: ")
server_port = int(input("Enter the server port: "))
try:
# Create a UDP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.settimeout(5) # Set a timeout for receiving data (5 seconds)
while True:
# Send data to the server
message = input("Enter your message (type 'exit' to quit): ")
if message.lower() == "exit":
break
client_socket.sendto(message.encode(), (server_address, server_port))
except socket.error as e:
27
print("Error:", e)
finally:
# Close the socket
client_socket.close()
if __name__ == "__main__":
main()
The main differences between TCP (Transmission Control Protocol) and UDP
(User Datagram Protocol) clients lie in their characteristics, reliability, and use
cases:
1. Connection-Oriented vs Connectionless : TCP is connection-oriented,
meaning it establishes a reliable, two-way communication channel
between the client and server before data exchange begins. UDP, on the
other hand, is connectionless, meaning it does not establish a dedicated
connection and simply sends data packets without prior setup.
2. Reliability : TCP ensures reliable delivery of data by implementing
mechanisms such as acknowledgment of received packets, retransmission
of lost packets, and sequencing of data packets. UDP does not guarantee
delivery or order of packets, making it less reliable but more lightweight.
3. Packet Ordering : TCP guarantees that data packets will be delivered in
the order they were sent. UDP does not enforce packet ordering, so
packets may arrive out of order.
4. Overhead : TCP has higher overhead due to its reliability mechanisms,
including handshakes, acknowledgments, and flow control. UDP has
lower overhead because it lacks these mechanisms, making it faster and
more efficient for certain types of communication.
5. Use Cases: TCP is suitable for applications that require reliable, ordered
delivery of data, such as web browsing, email, file transfer (FTP), and
remote login (SSH). UDP is suitable for real-time applications that
prioritize speed and efficiency over reliability, such as video streaming,
online gaming, VoIP (Voice over IP), and DNS (Domain Name System)
resolution.
In summary, TCP clients provide reliable, ordered communication over a
dedicated connection, while UDP clients provide faster, connectionless
communication with less overhead but no guarantee of delivery or order. The
choice between TCP and UDP depends on the specific requirements of the
application and the trade-offs between reliability, speed, and efficiency.
29
*************************************************************************
Summary
The chapter on UDP (User Datagram Protocol) clients delves into the
fundamentals of UDP communication and explores the differences between
UDP and TCP (Transmission Control Protocol).
Firstly, it elucidates the concept of UDP as a connectionless protocol,
contrasting it with TCP's connection-oriented nature. Unlike TCP, which
establishes a reliable, two-way communication channel before data exchange,
UDP simply sends data packets without prior setup.
The chapter highlights the key characteristics of UDP, emphasizing its
lightweight nature and lower overhead compared to TCP. While TCP ensures
reliable delivery of data through mechanisms like acknowledgment,
retransmission, and packet sequencing, UDP lacks these mechanisms, making it
less reliable but faster and more efficient for certain applications.
Furthermore, the chapter discusses the use cases of UDP clients, elucidating
scenarios where speed and efficiency are prioritized over reliability. Real-time
applications such as video streaming, online gaming, VoIP, and DNS resolution
benefit from UDP's swift transmission of data packets.
In conclusion, the chapter provides a comprehensive understanding of UDP
clients, elucidating their differences from TCP clients, their characteristics, and
their suitable use cases. By grasping the fundamentals of UDP communication,
readers can make informed decisions about when to utilize UDP for their
specific networking requirements.
**************************************************************************
30
1. Listening for Connections : The TCP server creates a socket and binds it
to a specific IP address and port on the server machine. It then listens for
incoming connection requests from clients using the listen()
function.
2. Accepting Connections : When a client attempts to connect to the server,
the server accepts the connection using the accept() function. This
creates a new socket, known as the client socket, for communication with
that specific client.
3. Communicating with Clients : Once the connection is established, the
server and client can exchange data bidirectionally over the TCP
connection. The server can receive data from the client using the
recv() function and send data to the client using the send() or
sendall() function.
server socket remains open and continues listening for new client
connections.
TCP servers are commonly used in various networked applications such as web
servers, email servers, file transfer servers, and database servers. They provide
reliable, ordered delivery of data between clients and servers, making them
suitable for applications that require guaranteed delivery and integrity of data
transmission.
def main():
# Define the server's IP address and port
server_address = "127.0.0.1" # localhost
server_port = 12345 # Choose any available port
while True:
# Accept incoming connection
client_socket, client_address = server_socket.accept()
if __name__ == "__main__":
main()
In this script:
This script creates a basic TCP server that accepts connections from clients,
receives data, and sends a response back to the client. You can run this script
on your machine to start the server.
import socket
import threading
class TCPServer:
def __init__(self, host, port):
33
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
self.client_threads = []
def start(self):
try:
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
print(f"Server is listening on {self.host}:{self.port}")
while True:
client_socket, client_address = self.server_socket.accept()
print(f"Connection from {client_address}")
client_thread = threading.Thread(target=self.handle_client,
args=(client_socket,))
client_thread.start()
self.client_threads.append(client_thread)
except KeyboardInterrupt:
print("Server shutting down...")
self.server_socket.close()
for thread in self.client_threads:
thread.join()
if __name__ == "__main__":
HOST = "127.0.0.1"
PORT = 12345
server = TCPServer(HOST, PORT)
server.start()
import socket
import threading
import time
import ssl
class TCPServer:
def __init__(self, host, port, backlog=5):
self.host = host
self.port = port
self.backlog = backlog
36
self.server_socket = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(self.backlog)
self.clients = {}
def start(self):
print(f"Server is listening on {self.host}:{self.port}")
try:
while True:
client_socket, client_address = self.server_socket.accept()
print(f"Connection from {client_address}")
client_thread = threading.Thread(target=self.handle_client,
args=(client_socket,))
client_thread.start()
except KeyboardInterrupt:
print("Server shutting down...")
self.server_socket.close()
if __name__ == "__main__":
HOST = "127.0.0.1"
PORT = 12345
server = TCPServer(HOST, PORT)
server.start()
This advanced TCP server incorporates multithreading, error handling, timeouts, and a basic
message processing function. To achieve the highest complexity level (10), additional
features such as authentication, encryption, database integration, logging, custom protocols,
and real-time updates would need to be implemented separately, as each of these features
introduces significant complexity and requires careful design and implementation.
38
**************************************************************************
Summary
The chapter on advanced TCP server implementation explores the intricacies of
building a robust and feature-rich TCP server using Python. Through a step-by-
step approach, the chapter covers various advanced concepts and techniques
essential for developing high-performance network servers.
Firstly, the chapter begins by discussing the fundamental principles of TCP
communication, highlighting its reliability, connection-oriented nature, and
bidirectional data exchange capabilities. It emphasizes the importance of
understanding TCP's underlying mechanisms to build efficient and scalable
server applications.
The chapter then introduces the concept of multithreading to handle multiple
client connections concurrently, enhancing the server's responsiveness and
scalability. Through threading, the server can effectively manage client requests
in parallel, improving overall performance and throughput.
Error handling is another critical aspect covered in the chapter, ensuring the
server gracefully handles unexpected situations such as client timeouts,
connection resets, and general exceptions. Robust error handling mechanisms
help maintain the server's stability and reliability under various conditions.
Additionally, the chapter explores the implementation of timeouts to prevent
blocking indefinitely during client communication. By setting appropriate
timeouts for client connections, the server can efficiently manage resources and
mitigate potential issues such as stale connections and denial-of-service attacks.
Furthermore, the chapter touches upon advanced topics such as authentication,
encryption, database integration, logging, custom protocols, and real-time
updates, which further enhance the server's functionality, security, and
extensibility. These features enable the development of sophisticated server
applications capable of meeting diverse requirements and use cases.
In conclusion, the chapter provides a comprehensive overview of building an
advanced TCP server, covering essential concepts, techniques, and best
practices. By mastering these advanced topics, developers can create robust,
scalable, and feature-rich server applications capable of handling complex
network communication tasks effectively.
**************************************************************************
39
• It's useful for network testing, firewall testing, and advanced packet
manipulation tasks.
5. SBd (Secure Backdoor) :
import socket
print("Received:", received_data.decode())
41
except socket.error as e:
print("Socket error:", e)
finally:
# Close the socket connection
s.close()
if __name__ == "__main__":
# Replace these values with your desired hostname, port, and content
hostname = "example.com"
port = 12345
content = "Hello, this is a message from Netcat replacement!"
import argparse
import argparse
def main():
# Create ArgumentParser object
parser = argparse.ArgumentParser(description='Process some integers.')
# Add arguments
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
# Parse arguments
args = parser.parse_args()
42
if __name__ == '__main__':
main()
In this example:
• We import the argparse module.
• We define a main function where the main logic of our script resides.
• Inside the main function, we create an ArgumentParser object
called parser with a description.
• We add two arguments to the parser:
• integers: An argument that takes one or more integer values.
• --sum: An optional argument that specifies whether to sum the
integers or find the maximum value.
• We parse the command-line arguments using
parser.parse_args().
• We access the parsed arguments through the args object and perform
the desired action based on the provided arguments.
• Finally, we call the main function if the script is executed directly.
You can run this script from the command line and pass integer values as
arguments, along with the optional --sum flag to specify whether to find the
sum or the maximum value of the integers.
import shlex
The shlex module in Python is used for parsing shell-like syntax. It provides
functions for splitting strings into tokens, taking into account quoting rules and
43
escape characters similar to how a Unix shell would parse command lines.
Here's a basic example of how to use shlex:
import shlex
def main():
# Define a shell-like command
command_line = 'echo "Hello, World!"'
if __name__ == '__main__':
main()
In this example:
• We import the shlex module.
• We define a shell-like command line as a string, where the command is
echo and the argument is "Hello, World!".
• We use shlex.split() to parse the command line into a list of
tokens.
• We print the tokens, which represent the individual components of the
command line (e.g., the command and its arguments).
The textwrap module in Python is used for formatting and wrapping text to
fit within a specified width. It provides functions for formatting paragraphs of
text in various ways, such as wrapping text to a certain number of characters
per line, adding indentation, and more. Here's a basic example of how to use
textwrap:
import textwrap
def main():
# Define a long paragraph of text
paragraph = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat."
if __name__ == '__main__':
main()
In this example:
• We import the textwrap module.
• We define a long paragraph of text.
• We use textwrap.fill() to wrap the paragraph text to fit within 40
characters per line.
• We print the wrapped text.
more. It helps ensure that text is presented in a readable and visually appealing
manner, especially when dealing with long or multiline strings.
import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading
def execute(cmd):
cmd = cmd.strip()
if not cmd:
return
output = subprocess.check_output(shlex.split(cmd),
stderr=subprocess.STDOUT)
return output.decode()
def client_sender(buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to the target host
client.connect((args.target, args.port))
if buffer:
client.send(buffer.encode())
while True:
# Wait for data from the target host
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response += data.decode()
if recv_len < 4096:
46
break
def server_loop():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((args.target, args.port))
server.listen(5)
while True:
client_socket, addr = server.accept()
client_thread = threading.Thread(target=client_handler,
args=(client_socket,))
client_thread.start()
def client_handler(client_socket):
if args.upload:
file_buffer = ""
try:
with open(args.upload, "wb") as f:
f.write(file_buffer)
client_socket.send("File uploaded successfully.\n".encode())
except Exception as e:
client_socket.send(f"Failed to upload file: {e}".encode())
if args.execute:
output = execute(args.execute)
client_socket.send(output.encode())
if args.command:
while True:
# Display a simple prompt
client_socket.send("<BHP:#> ".encode())
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='BHP Net Tool',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''Example:
netcat.py -t 192.16.1.108 -p 55551c #command shell
netcat.py -t 192.16.1.108 -p 5555 -u mytest.txt #upload file
netcat.py -t 192.16.1.108 -p 5555 -e "cat /etc/passwd" #execute
command
echo 'ABC' | ./netcat.py -t 192.168.1.108 -p 135 #echo text to server
port 135
netcat.py -t 192.168.1.108 -p 5555 #connect to server
''')
48
2. Main Functionality : The script checks if it's being run as the main
program (if __name__ == "__main__":). It then parses the
command-line arguments and proceeds to either act as a client or a server
based on the provided options.
3. Client Functionality : If the script is not set to listen ( args.listen)
and a target IP is provided, it reads input from stdin and sends it to the
49
target host on the specified port. It also continuously listens for data from
the target and displays any received data.
4. Server Functionality : If the script is set to listen ( args.listen), it
creates a server socket bound to the specified IP and port. It listens for
incoming connections and spawns a new thread to handle each client
connection. The client_handler function handles various actions
based on the provided command-line options, such as executing
commands, uploading files, and providing a command shell interface.
5. Executing Commands and Uploading Files : The execute function
executes commands using subprocess.check_output, and the
client_handler function handles executing commands
(args.execute) and uploading files ( args.upload).
**************************************************************************
Summary
The chapter "Replacing Netcat with Python" delves into the process of creating
a Python script as a replacement for Netcat, a versatile networking utility. It
explores the motivation behind developing such a script, the design
considerations, and the implementation details necessary to replicate Netcat's
functionalities using Python.
1. Introduction to Netcat :
**************************************************************************
52
4. Monitoring and Logging: TCP proxies can intercept and log network
traffic for monitoring, analysis, debugging, and troubleshooting
purposes. They can provide insights into network performance, usage
patterns, and potential issues.
53
import socket
import threading
while True:
# Receive data from the client
client_data = client_socket.recv(4096)
if not client_data:
break
client_socket.close()
remote_socket.close()
54
while True:
client_socket, _ = server.accept()
print(f"[*] Accepted connection from {client_socket.getpeername()[0]}:
{client_socket.getpeername()[1]}")
proxy_thread = threading.Thread(target=handle_client,
args=(client_socket, remote_host, remote_port))
proxy_thread.start()
if __name__ == "__main__":
local_host = "127.0.0.1"
local_port = 8888
remote_host = "www.example.com"
remote_port = 80
main(local_host, local_port, remote_host, remote_port)
This code creates a basic TCP proxy that listens for incoming connections on a
specified local host and port. When a client connects, it establishes a connection
to a remote host and port, then forwards data between the client and the remote
host bidirectionally.
To use the proxy, replace remote_host and remote_port with the
desired remote host and port, then run the script. Clients can connect to the
proxy on local_host and local_port, and their traffic will be
forwarded to the remote host.
import socket
import threading
# Start a loop to continuously forward data between the client and the
remote host
while True:
# Read from local client, send to remote host
local_buffer = receive_from(client_socket)
if len(local_buffer):
print("[<==] Received %d bytes from local client." %
len(local_buffer))
hexdump(local_buffer)
remote_socket.send(local_buffer)
client_socket.close()
remote_socket.close()
print("[*] No more data. Closing connections.")
break
print(b'\n'.join(result))
def receive_from(connection):
buffer = ""
# Set a 2-second timeout; adjust as needed
connection.settimeout(2)
try:
# Read data until no more data or timeout occurs
while True:
data = connection.recv(4096)
if not data:
break
buffer += data
except:
pass
return buffer
while True:
57
def usage():
print("Usage: ./proxy.py [local_host] [local_port] [remote_host]
[remote_port] [receive_first]")
print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
if __name__ == '__main__':
if len(sys.argv[1:]) != 5:
usage()
# Set up parameters
local_host = sys.argv[1]
local_port = int(sys.argv[2])
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
receive_first = True if "True" in sys.argv[5] else False
This TCP proxy script sets up a server that listens for incoming connections on
a specified local host and port. When a client connects, the server forwards data
between the client and a remote host specified by the user. It can optionally
receive data from either the client or the remote host first. The script utilizes
multithreading to handle multiple client connections concurrently.
To use the script, run it with the following command-line arguments:
58
This code implements a basic TCP proxy in Python. It listens for incoming
connections on a specified local host and port, and forwards data between
clients and a remote host and port.
Here's a breakdown of how it works:
5. Usage Function : This function prints usage instructions for running the
script with the correct command-line arguments.
6. Script Execution : The script checks if the correct number of command-
line arguments is provided, parses them, and starts the proxy server with
the specified parameters.
To use the proxy, run the script with the following command-line arguments:
For example:
**************************************************************************
Summary
The chapter introduces a basic implementation of a TCP proxy in Python,
which acts as an intermediary between clients and remote servers. The proxy is
designed to handle incoming connections, forward data bidirectionally between
clients and servers, and optionally receive data from the server first before
forwarding it to the client.
Key components of the implementation include:
point for building more advanced proxy solutions with additional features and
optimizations.
********************************************************************************
62
@7cryx