Skip to content

Commit 6831fda

Browse files
renamed some methods, updated README.md withn instructions on how to test UDP connection
1 parent 60169bf commit 6831fda

File tree

7 files changed

+69
-41
lines changed

7 files changed

+69
-41
lines changed

README.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- [Transparent proxy](#transparent-proxy)
2121
- [redirect (via NAT and SO_ORIGINAL_DST)](#redirect-via-nat-and-so_original_dst)
2222
- [tproxy (via MANGLE and IP_TRANSPARENT)](#tproxy-via-mangle-and-ip_transparent)
23+
- [UDP support](#udp-support)
2324
- [ARP spoofing](#arp-spoofing)
2425
- [Traffic sniffing](#traffic-sniffing)
2526
- [JSON format](#json-format)
@@ -62,8 +63,11 @@ Specify http server in proxy configuration of Postman
6263
- **Transparent proxy**\
6364
Supports `redirect` (SO_ORIGINAL_DST) and `tproxy` (IP_TRANSPARENT) modes
6465

66+
- **TCP and UDP Transparent proxy**\
67+
`tproxy` (IP_TRANSPARENT) handles TCP and UDP traffic
68+
6569
- **Traffic sniffing**\
66-
Proxy is able to parse HTTP headers and TLS handshake metadata
70+
Proxy is able to parse HTTP headers, TLS handshake, DNS messages and more
6771

6872
- **ARP spoofing**\
6973
Proxy entire subnets with ARP spoofing approach
@@ -101,7 +105,7 @@ You can download the binary for your platform from [Releases](https://github.com
101105
Example:
102106

103107
```shell
104-
GOHPTS_RELEASE=v1.9.4; wget -v https://github.com/shadowy-pycoder/go-http-proxy-to-socks/releases/download/$GOHPTS_RELEASE/gohpts-$GOHPTS_RELEASE-linux-amd64.tar.gz -O gohpts && tar xvzf gohpts && mv -f gohpts-$GOHPTS_RELEASE-linux-amd64 gohpts && ./gohpts -h
108+
GOHPTS_RELEASE=v2.0.0; wget -v https://github.com/shadowy-pycoder/go-http-proxy-to-socks/releases/download/$GOHPTS_RELEASE/gohpts-$GOHPTS_RELEASE-linux-amd64.tar.gz -O gohpts && tar xvzf gohpts && mv -f gohpts-$GOHPTS_RELEASE-linux-amd64 gohpts && ./gohpts -h
105109
```
106110

107111
Alternatively, you can install it using `go install` command (requires Go [1.24](https://go.dev/doc/install) or later):
@@ -168,6 +172,7 @@ Options:
168172
TProxy:
169173
-t Address of transparent proxy server (it starts along with HTTP proxy server)
170174
-T Address of transparent proxy server (no HTTP)
175+
-Tu Address of transparent UDP proxy server
171176
-M Transparent proxy mode: (redirect, tproxy)
172177
-auto Automatically setup iptables for transparent proxy (requires elevated privileges)
173178
-arpspoof Enable ARP spoof proxy for selected targets (Example: "targets 10.0.0.1,10.0.0.5-10,192.168.1.*,192.168.10.0/24;fullduplex false;debug true")
@@ -521,6 +526,30 @@ sudo bettercap -eval "net.probe on;net.recon on;set arp.spoof.fullduplex true;ar
521526
522527
Check proxy logs for traffic from other devices from your LAN
523528
529+
### UDP support
530+
531+
`GoHPTS` has UDP support that can be enabled in `tproxy` mode. For this setup to work you need to connect to a socks5 server capable of serving UDP connections (`UDP ASSOCIATE`). For example, you can use [https://github.com/wzshiming/socks5](https://github.com/wzshiming/socks5) to deploy UDP capable UDP server on some remote or local machine. Once you have the server to connect to, run the following command:
532+
533+
```shell
534+
sudo env PATH=$PATH gohpts -s remote -Tu :8989 -M tproxy -auto -mark 100 -d
535+
```
536+
537+
This command will configure your operating system and setup server on `0.0.0.0:8989` address.
538+
539+
To test it locally, you can combine UDP transparent proxy with `-arpspoof` flag. For example:
540+
541+
1. Setup VM on your system with any Linux distributive that supports `tproxy` (Kali Linux, for instance).
542+
2. Enable `Bridged` network so that VM could access your host machine.
543+
3. Move `gohpts` binary to VM (via `ssh`, for instance) or build it there in case of different OS/arch.
544+
4. On your VM run the following command:
545+
546+
```shell
547+
# Do not forget to replace <socks5 server> and <your host> with actual addresses
548+
sudo ./gohpts -s <socks5 server> -T 8888 -Tu :8989 -M tproxy -sniff -body -auto -mark 100 -d -arpspoof "targets <your host>;fullduplex true;debug false"
549+
```
550+
551+
4. Check connection on your host machine, the traffic should go through Kali machine.
552+
524553
## Traffic sniffing
525554
526555
[[Back]](#table-of-contents)

gohpts.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -520,14 +520,14 @@ func (p *proxyapp) Run() {
520520
if p.tproxyAddr != "" {
521521
tproxyServer = newTproxyServer(p)
522522
if p.auto {
523-
tproxyServer.applyRedirectRules(opts)
523+
tproxyServer.ApplyRedirectRules(opts)
524524
}
525525
}
526526
var tproxyServerUDP *tproxyServerUDP
527527
if p.tproxyAddrUDP != "" {
528528
tproxyServerUDP = newTproxyServerUDP(p)
529529
if p.auto {
530-
tproxyServerUDP.applyRedirectRules(opts)
530+
tproxyServerUDP.ApplyRedirectRules(opts)
531531
}
532532
}
533533
if p.proxylist != nil {
@@ -554,7 +554,7 @@ func (p *proxyapp) Run() {
554554
if tproxyServer != nil {
555555
p.logger.Info().Msgf("[tcp %s] Server is shutting down...", p.tproxyMode)
556556
if p.auto {
557-
err := tproxyServer.clearRedirectRules()
557+
err := tproxyServer.ClearRedirectRules()
558558
if err != nil {
559559
p.logger.Error().Err(err).Msg("Failed clearing iptables rules")
560560
}
@@ -564,7 +564,7 @@ func (p *proxyapp) Run() {
564564
if tproxyServerUDP != nil {
565565
p.logger.Info().Msgf("[udp %s] Server is shutting down...", p.tproxyMode)
566566
if p.auto {
567-
err := tproxyServerUDP.clearRedirectRules()
567+
err := tproxyServerUDP.ClearRedirectRules()
568568
if err != nil {
569569
p.logger.Error().Err(err).Msg("Failed clearing iptables rules")
570570
}
@@ -621,7 +621,7 @@ func (p *proxyapp) Run() {
621621
if tproxyServer != nil {
622622
p.logger.Info().Msgf("[tcp %s] Server is shutting down...", p.tproxyMode)
623623
if p.auto {
624-
err := tproxyServer.clearRedirectRules()
624+
err := tproxyServer.ClearRedirectRules()
625625
if err != nil {
626626
p.logger.Error().Err(err).Msg("Failed clearing iptables rules")
627627
}
@@ -631,7 +631,7 @@ func (p *proxyapp) Run() {
631631
if tproxyServerUDP != nil {
632632
p.logger.Info().Msgf("[udp %s] Server is shutting down...", p.tproxyMode)
633633
if p.auto {
634-
err := tproxyServerUDP.clearRedirectRules()
634+
err := tproxyServerUDP.ClearRedirectRules()
635635
if err != nil {
636636
p.logger.Error().Err(err).Msg("Failed clearing iptables rules")
637637
}

tproxy_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func (ts *tproxyServer) Shutdown() {
243243
}
244244
}
245245

246-
func (ts *tproxyServer) applyRedirectRules(opts map[string]string) {
246+
func (ts *tproxyServer) ApplyRedirectRules(opts map[string]string) {
247247
_, tproxyPort, _ := net.SplitHostPort(ts.p.tproxyAddr)
248248
var setex string
249249
if ts.p.debug {
@@ -420,7 +420,7 @@ func (ts *tproxyServer) applyRedirectRules(opts map[string]string) {
420420
_ = createSysctlOptCmd("net.ipv4.tcp_fin_timeout", "15", setex, opts, ts.p.debug).Run()
421421
}
422422

423-
func (ts *tproxyServer) clearRedirectRules() error {
423+
func (ts *tproxyServer) ClearRedirectRules() error {
424424
var setex string
425425
if ts.p.debug {
426426
setex = "set -ex"

tproxy_nonlinux.go

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ package gohpts
55

66
import (
77
"net"
8-
"os/exec"
98
"sync"
10-
"syscall"
119
)
1210

1311
type tproxyServer struct {
@@ -23,39 +21,15 @@ func newTproxyServer(p *proxyapp) *tproxyServer {
2321
}
2422

2523
func (ts *tproxyServer) ListenAndServe() {
26-
ts.serve()
27-
}
28-
29-
func (ts *tproxyServer) serve() {
30-
ts.handleConnection(nil)
31-
}
32-
33-
func (ts *tproxyServer) getOriginalDst(rawConn syscall.RawConn) (string, error) {
34-
_ = rawConn
35-
return "", nil
36-
}
37-
38-
func (ts *tproxyServer) handleConnection(srcConn net.Conn) {
39-
_ = srcConn
40-
ts.getOriginalDst(nil)
4124
}
4225

4326
func (ts *tproxyServer) Shutdown() {}
4427

45-
func (ts *tproxyServer) createSysctlOptCmd(opt, value, setex string, opts map[string]string) *exec.Cmd {
46-
_ = opt
47-
_ = value
48-
_ = setex
28+
func (ts *tproxyServer) ApplyRedirectRules(opts map[string]string) map[string]string {
4929
_ = opts
5030
return nil
5131
}
5232

53-
func (ts *tproxyServer) applyRedirectRules() map[string]string {
54-
_ = ts.createSysctlOptCmd("", "", "", nil)
55-
return nil
56-
}
57-
58-
func (ts *tproxyServer) clearRedirectRules(opts map[string]string) error {
59-
_ = opts
33+
func (ts *tproxyServer) ClearRedirectRules() error {
6034
return nil
6135
}

tproxy_udp_linux.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ func (tsu *tproxyServerUDP) getOriginalDst(oob []byte) (*net.UDPAddr, error) {
533533
return nil, fmt.Errorf("original destination not found")
534534
}
535535

536-
func (tsu *tproxyServerUDP) applyRedirectRules(opts map[string]string) {
536+
func (tsu *tproxyServerUDP) ApplyRedirectRules(opts map[string]string) {
537537
_, tproxyPortUDP, _ := net.SplitHostPort(tsu.p.tproxyAddrUDP)
538538
var setex string
539539
if tsu.p.debug {
@@ -607,7 +607,7 @@ func (tsu *tproxyServerUDP) applyRedirectRules(opts map[string]string) {
607607
}
608608
}
609609

610-
func (tsu *tproxyServerUDP) clearRedirectRules() error {
610+
func (tsu *tproxyServerUDP) ClearRedirectRules() error {
611611
var setex string
612612
if tsu.p.debug {
613613
setex = "set -ex"

tproxy_udp_nonlinux.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//go:build !linux
2+
// +build !linux
3+
4+
package gohpts
5+
6+
type tproxyServerUDP struct{}
7+
8+
func newTproxyServerUDP(p *proxyapp) *tproxyServerUDP {
9+
_ = p
10+
return nil
11+
}
12+
13+
func (tsu *tproxyServerUDP) ListenAndServe() {
14+
}
15+
16+
func (tsu *tproxyServerUDP) Shutdown() {
17+
}
18+
19+
func (tsu *tproxyServerUDP) ApplyRedirectRules(opts map[string]string) {
20+
_ = opts
21+
}
22+
23+
func (tsu *tproxyServerUDP) ClearRedirectRules() error {
24+
return nil
25+
}

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package gohpts
22

3-
const Version string = "gohpts v1.9.4"
3+
const Version string = "gohpts v2.0.0"

0 commit comments

Comments
 (0)