Proxychains

Forces any TCP application to go through a SOCKS or HTTP proxy. The glue between your tunneling tool (Chisel, Ligolo, SSH) and the rest of your toolkit. Prefix any command with proxychains and its traffic routes through the tunnel.

CPTS Linux
LevelIntermediate. Pairs with Chisel or an SSH tunnel, so set those up first.
Know firstWhat a SOCKS proxy is, and that TCP, UDP and ICMP are different protocols.
You will learn toroute a tool through an existing SOCKS proxy, and know which scans and protocols will not work through it.

What is it?

Proxychains is a LD_PRELOAD wrapper. It intercepts the network calls of any dynamically-linked program and redirects them through one or more proxy servers (SOCKS4, SOCKS5, or HTTP). You configure it to point at your SOCKS proxy (created by Chisel, Ligolo, or SSH), and then prefix any command with proxychains.

The modern version is proxychains-ng (proxychains4), which is what ships with Kali and most pentesting distros. The config file is /etc/proxychains4.conf.

Without proxychains, you'd need to manually configure proxy settings for every tool individually, and many tools don't even support SOCKS proxies natively. Proxychains solves this by working at the system call level, making it transparent to the application.

Critical limitation

Proxychains only works with TCP. It cannot proxy UDP traffic or ICMP (ping). This means: no UDP Nmap scans (-sU), no DNS resolution through the proxy by default, and ping won't work through the tunnel. You must use TCP connect scans (-sT) with Nmap and disable host discovery (-Pn).

Run this first

Prefix any command with proxychains once a SOCKS proxy is listening, for example from Chisel or an SSH -D tunnel.

bash: your first routed command
$ proxychains nmap -sT -Pn -p 22,80,445,3389 172.16.1.0/24
  • proxychains routes the command through the proxy defined in /etc/proxychains4.conf.
  • -sT -Pn required for Nmap here: SOCKS only carries full TCP connections, and ping does not work through it.

Only TCP works through proxychains. No UDP scans, no ICMP ping, and DNS needs proxy_dns enabled in the config or the hostname added to /etc/hosts.

When do you use it?

Every time you set up a SOCKS proxy tunnel (Chisel, SSH -D, Ligolo with SOCKS) and need to run tools through it:

  • After setting up a Chisel reverse SOCKS proxy: your tunnel is up on 127.0.0.1:1080, now route Nmap/evil-winrm/smbmap through it
  • Through an SSH dynamic port forward: ssh -D 1080 user@pivot-host, then proxychains to use that tunnel
  • Double pivot scenarios: chain multiple proxies to reach networks three hops away

Configuration

The config file is /etc/proxychains4.conf. There are only two things you usually need to change: the chain type and the proxy list at the bottom.

config: /etc/proxychains4.conf
# Choose ONE of these chain types (uncomment one, comment others):

# strict_chain: goes through proxies in order, fails if any is down
#strict_chain

# dynamic_chain: skips dead proxies, tries each in order
dynamic_chain

# random_chain: picks proxies randomly (for anonymity, not pentesting)
#random_chain

# Quiet mode: suppress proxychains status messages
quiet_mode

# Timeouts (ms): increase if connections are slow through tunnel
tcp_read_time_out 15000
tcp_connect_time_out 8000

# DNS: resolve through proxy (prevents DNS leaks)
proxy_dns

# Proxy list: your SOCKS proxy goes here
[ProxyList]
socks5 127.0.0.1 1080

Chain types explained

TypeBehaviorUse case
strict_chainEach proxy in list must be alive and used in orderSingle proxy setup (most common in pentesting)
dynamic_chainSkips dead proxies, uses live ones in orderWhen you have multiple proxies and some might go down
random_chainPicks random proxy each connectionAnonymity (not relevant for pentesting)
Use dynamic_chain for pentesting

Even with a single proxy, dynamic_chain is more forgiving. If your tunnel drops momentarily, strict_chain will fail immediately, while dynamic_chain will retry. It's also essential for double-pivot setups where you chain through two proxies.

Using with Chisel

The most common combo. Set up a Chisel reverse SOCKS proxy, then use proxychains to route traffic through it.

bash: complete Chisel + proxychains workflow
# 1. Start Chisel server on your attacker box
$ ./chisel server -p 8081 --reverse

# 2. On compromised host: connect and create SOCKS proxy
$ ./chisel client 10.10.14.5:8081 R:socks

# 3. Ensure proxychains is configured (one-time)
$ tail -2 /etc/proxychains4.conf
[ProxyList]
socks5 127.0.0.1 1080  <-- must match the port Chisel/Ligolo actually opened

# 4. Use tools through the tunnel
$ proxychains nmap -sT -Pn -p 22,80,445,3389 172.16.1.0/24
$ proxychains evil-winrm -i 172.16.1.10 -u admin -p 'Password1'
$ proxychains curl http://172.16.1.20/
$ proxychains smbclient //172.16.1.10/share -U admin%Password1

Using with Ligolo-ng

With Ligolo-ng, you typically don't need proxychains because Ligolo creates a TUN interface that routes traffic natively. However, if you set up Ligolo in SOCKS mode or use the listener feature:

bash: Ligolo listener + proxychains
# If Ligolo is set up with a route through the TUN interface,
# you DON'T need proxychains, tools work directly:
$ nmap -sC -sV 172.16.1.10    # works without proxychains!

# Only use proxychains with Ligolo if you're using its SOCKS mode
# or if the TUN interface isn't configured
Ligolo advantage over Chisel+Proxychains

This is the main reason to choose Ligolo: no proxychains needed, SYN scans work, ICMP works, UDP works. If you're doing heavy internal scanning, Ligolo + TUN interface saves you from all the proxychains limitations.

DNS leak prevention

By default, DNS queries might bypass the proxy and go directly to your system's DNS resolver, this leaks information about what internal hostnames you're looking up.

config: fix DNS leaks
# In /etc/proxychains4.conf, ensure this line is uncommented:
proxy_dns

# This makes DNS resolve through the SOCKS proxy
# Note: only works with SOCKS5 (not SOCKS4)
bash: alternative: use IP addresses directly
# If proxy_dns causes issues, add internal hostnames to /etc/hosts
$ echo "172.16.1.10 dc01.corp.local" >> /etc/hosts

# Then tools resolve locally without DNS queries at all
$ proxychains evil-winrm -i dc01.corp.local -u admin -p Pass

Speed tips

Proxychains is slower than a direct connection. Each TCP connection goes through the SOCKS proxy, adding latency. Here's how to minimize the pain:

Making proxychains faster
  • Nmap: limit ports. Don't run -p- through proxychains: it takes hours. Scan specific ports: proxychains nmap -sT -Pn -p 22,80,88,135,389,445,3389,5985 172.16.1.0/24
  • Enable quiet mode. Add quiet_mode to the config: it suppresses the per-connection status messages that slow down output
  • Reduce Nmap timing. Use --min-parallelism 10 to run more connections simultaneously, but don't go too high or the SOCKS proxy gets overwhelmed
  • Skip host discovery. Always use -Pn with Nmap: ICMP doesn't work through SOCKS, so host discovery just wastes time waiting for timeouts
  • Use specific tools over full scans. Instead of an Nmap sweep, try: proxychains crackmapexec smb 172.16.1.0/24 to quickly identify live Windows hosts
  • Increase timeouts. Set tcp_read_time_out 15000 and tcp_connect_time_out 8000 if connections drop due to slow tunnels

Common issues

Things that go wrong
  • "Timeout" on every connection: Your SOCKS proxy isn't running, or proxychains is pointing at the wrong port. Check that Chisel/SSH tunnel is active and the port in proxychains4.conf matches
  • Nmap shows all ports filtered: You're using SYN scan (default). Use -sT for TCP connect scan. Also add -Pn to skip host discovery
  • DNS resolution fails: Either enable proxy_dns in the config, or add the target hostname to /etc/hosts manually
  • UDP tools don't work: Proxychains can't proxy UDP. Use Ligolo-ng if you need UDP, or run UDP tools directly from the compromised host
  • "Dynamic chain ... connection refused": The proxy is down. Check your Chisel server/client are still connected
  • Extremely slow: Add quiet_mode, limit your port range, and increase parallelism. Or switch to Ligolo for heavy scanning
  • Some tools ignore proxychains: Statically compiled tools (like some Go binaries) don't use libc and bypass the LD_PRELOAD hook. Run those tools directly from the compromised host instead
Quick proxy test

Before running complex tools, verify the tunnel works: proxychains curl http://172.16.1.10 or proxychains nc -zv 172.16.1.10 445. If these fail, the tunnel is the problem, not the tool.

Check yourself

Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.

Why must you use -sT and not the default SYN scan through proxychains?
SOCKS only supports full TCP connections at the application level. The default SYN scan sends raw packets, which proxychains cannot route.
Nmap through the tunnel reports every port filtered. What is the fix?
Switch to -sT and add -Pn, since ICMP host discovery does not work through the proxy.
A UDP tool refuses to work through proxychains. Is that fixable?
No. Proxychains cannot proxy UDP at all. Run UDP tools directly from the compromised host, or use Ligolo instead, which supports it.
Hostnames do not resolve through the tunnel. What are your two options?
Enable proxy_dns in proxychains4.conf, or add the hostname to /etc/hosts manually.
A statically compiled Go binary ignores proxychains entirely. Why?
Proxychains works by intercepting libc's networking calls (LD_PRELOAD). A statically linked binary does not use libc that way, so the hook never fires. Run it directly from the compromised host instead.