
Ponte de proxy SOCKS5 para HTTP que tunela streams TCP arbitrárias (SSH, SMTP, TLS) através de requisições HTTP padrão, possibilitando ofuscação de tráfego de rede e evasão de firewall.

Escrevi este programa como uma prova de conceito para testar a ideia de ser capaz de enviar pacotes de fluxo TCP sobre requisições HTTP simples como PUT, PATCH, POST, GET, sem usar uma forma de proxy como o método CONNECT. Também como um exercício prático para treinar minha habilidade iniciante na linguagem Rust.
Esta ferramenta é composta por duas partes: o servidor e um cliente.
O servidor é apenas um arquivo PHP com alguma lógica para manter conexões com estado usando sockets TCP, e lidar com as requisições HTTP recebidas; por enquanto essa lógica funciona apenas em servidores Linux.
Testei com Apache+mod_php, Nginx+php-fpm e o servidor PHP embutido (php -S)
O cliente é um servidor Socks5 que escuta conexões de clientes recebidas, empacota as strings de bytes e envia a requisição HTTP para o servidor, e quando recebe a resposta, escreve de volta para o cliente.
Este cliente é escrito em Rust, peguei emprestada a implementação Socks5 deste projeto v2socks, então agradecimentos a ylxdzsw
Proxychains é necessário para executar este exemplo.
Faça upload do arquivo do servidor hbserver/hbserver.php para um servidor web em execução com suporte a PHP, ou execute um localmente da seguinte forma, isso criará um contêiner Docker escutando na porta 8080.
docker run --rm -it --net host --name apache-webserver -v "$PWD/hbserver:/app -v "$PWD/tools/ports.conf:/etc/apache2/ports.conf" webdevops/php-apache:7.3
O cliente precisa ser compilado, então você precisa ter um compilador Rust instalado ou obter um aqui rustup
cd client &&\
cargo build &&\
./target/debug/hbsc
configure o proxychains para apontar para a porta socks5 local:
echo "socks5 127.0.0.1 1986" >> $HOME/.proxychains/proxychains.conf
Com tudo no lugar, alguns testes:
icanhazip.com
alejandro@0x2e ~ $ proxychains curl -v icanhazip.com
[proxychains] config file found: /home/alejandro/.proxychains/proxychains.conf
[proxychains] preloading /usr/lib64/libproxychains.so.4.14
* Trying 224.0.0.1:80...
* Connected to icanhazip.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: icanhazip.com
> User-Agent: curl/7.72.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 25 Feb 2021 18:08:04 GMT
< Content-Type: text/plain
< Content-Length: 15
< Connection: close
< Set-Cookie: __cfduid=dd994605ef1b77d0aa6dc46b6fdbb4c8d1614276484; expires=Sat, 27-Mar-21 18:08:04 GMT; path=/; domain=.icanhazip.com; HttpOnly; SameSite=Lax
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET
< X-RTFM: Learn about this site at http://bit.ly/icanhazip-faq
< X-THANK-YOU: Many thanks to the fine people at Cloudflare for keeping this site afloat!
< cf-request-id: 087bf977730000e790d13c4000000001
< Server: cloudflare
< CF-RAY: 62735e9f1ec9e790-MDE
< alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
<
XXX.33.235.XXX
* Closing connection 0
http://httpbin.org/headers
alejandro@0x2e ~ $ proxychains curl -v http://httpbin.org/headers
[proxychains] config file found: /home/alejandro/.proxychains/proxychains.conf
[proxychains] preloading /usr/lib64/libproxychains.so.4.14
* Trying 224.0.0.1:80...
* Connected to httpbin.org (127.0.0.1) port 80 (#0)
> GET /headers HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.72.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 25 Feb 2021 18:05:51 GMT
< Content-Type: application/json
< Content-Length: 173
< Connection: keep-alive
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
<
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.72.0",
"X-Amzn-Trace-Id": "Root=1-6037e6ff-06059b933c2d8c495ecee43a"
}
}
* Connection #0 to host httpbin.org left intact
https://mozilla.org
alejandro@0x2e ~ $ proxychains curl -v https://mozilla.org
[proxychains] config file found: /home/alejandro/.proxychains/proxychains.conf
[proxychains] preloading /usr/lib64/libproxychains.so.4.14
* Trying 224.0.0.1:443...
* Connected to mozilla.org (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=mozilla.org
* start date: Jan 1 19:11:54 2021 GMT
* expire date: Apr 1 19:11:54 2021 GMT
* subjectAltName: host "mozilla.org" matched cert's "mozilla.org"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x562758dbab60)
> GET / HTTP/2
> Host: mozilla.org
> user-agent: curl/7.72.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 301
< date: Thu, 25 Feb 2021 18:03:56 GMT
< content-type: text/html
< content-length: 162
< location: https://www.mozilla.org/
< strict-transport-security: max-age=60; includeSubDomains
< x-backend-server: TS
< cache-control: max-age=3600
< x-frame-options: SAMEORIGIN
< content-security-policy: frame-ancestors 'none'
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host mozilla.org left intact
smtp.gmail.com
alejandro@0x2e ~ $ proxychains nc -v smtp.gmail.com 25
[proxychains] config file found: /home/alejandro/.proxychains/proxychains.conf
[proxychains] preloading /usr/lib64/libproxychains.so.4.14
Connection to smtp.gmail.com 25 port [tcp/smtp] succeeded!
220 smtp.gmail.com ESMTP z1sm4022921qtu.83 - gsmtp
EHLO smtp.gmail.com
250-smtp.gmail.com at your service, [XXX.33.235.XXX]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
^C
alejandro@0x2e ~ $ proxychains ssh localhost 'ps axl --sort=-pcpu|tail -n 5'
[proxychains] config file found: /home/alejandro/.proxychains/proxychains.conf
[proxychains] preloading /usr/lib64/libproxychains.so.4.14
Password:
4 0 65375 1242 20 0 9516 6988 - Ss ? 0:00 sshd: alejandro [priv]
5 1000 65420 65375 20 0 9516 4320 - S ? 0:00 sshd: alejandro@notty
0 1000 65421 65420 20 0 218168 3260 - Ss ? 0:00 bash -c ps axl --sort=-pcpu|tail -n 5
4 1000 65422 65421 20 0 220568 3484 - R ? 0:00 ps axl --sort=-pcpu
0 1000 65423 65421 20 0 216756 748 - S ? 0:00 tail -n 5
alejandro@0x2e ~ $