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.

I have been programming for 7 years with over 10 years of systems administration. This is my blog to write about technology, current events, code, spread awareness, rant and rave and write the wrongs of the past. I am into new technology, programming, archery, turntablism, disc golf and rally racing.

Be First to Comment

Leave a Reply

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