Skip to content

Patching A Python Socket To Use SOCKS5 Protocol

Some projects require tunneling through a proxy system to connect to, monitor or probe a specific resource. If you are programming with Python sockets you will come to find the standard library’s socket class does not support sending data piped through a SOCKS5 server. Depending on your specifications, here are two ways to overcome the default behavior.

For this, have these Python packages installed on your system globally or in your project environment.

Just install with pip.

pip install pysocks requests urllib3 

Monkeypatching the socket

This allows you to have the same control over the socket like you normally would in Python. A benefit if you are tasked to fuzz a service with custom payloads, or are using a non standard protocol over the socket layer.

To patch the socket :

  • Set the proxy you want to use with the socks method setdefaultproxy.
  • Patch the socket module to use the Pysocks implementation of the socketsocket class.
  • Override the create_connection method.
import socks
import socket

def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    sock.connect(address)
    return sock

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050)

# patch the socket module
socket.socket = socks.socksocket
socket.create_connection = create_connection

import urllib3

try:
    s = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("bot.whatismyipaddress.com", 80))

    message = b'GET / HTTP/1.0\r\n\r\n'
    s.sendall(message)

    reply = s.recv(4069)
    print(reply)
except Exception as e:
    print(e)

If your SOCKS5 proxy address is returned when you run the script, you have successfully patched the module.

Request library

Request library is less granularity over your socket data. One advantage is it does support SSL out of the box. A benefit if you don’t want to implement yourself in the patch. The Request library allows you to do this with minimal lines of code. Just set your proxy details in a dictionary and supply as a parameter to your requests.get method.

import requests

proxies = {
    'http': 'socks5h://127.0.0.1:9050',
    'https': 'socks5h://127.0.0.1:9050'
}

data = requests.get("http://bot.whatismyipaddress.com",proxies=proxies).text

print(data)

Using the Request’s API, you can print out the return body with the .text method.

If you were having issues connecting your Python code to a SOCKS5 server, this should help you with your project requirements.

Michael has been a professional in the information technology field for over 10 years, specializing in software engineering and systems administration. He studied network security and holds a software engineering degree from Milwaukee Area Technical College with thousands of hours of self taught learning as well. He mainly writes about technology, current events, and coding. Michael also is the founder of Sof Digital, an U.S. based software development Firm. His hobbies are archery, turntablism, disc golf and rally racing.

Leave a Reply

Your email address will not be published. Required fields are marked *