Skip to content

Commit fdb43d3

Browse files
Merge pull request #20 from shadowy-pycoder/ndpspoof
added basic logic to handle ndp spoofing
2 parents 67dcd36 + c5d16e1 commit fdb43d3

11 files changed

Lines changed: 746 additions & 784 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ models/**/*
3232
*.model
3333
*.vocab
3434
*.yaml
35+
rules.sh
3536

README.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [UDP support](#udp-support)
2626
- [Android support](#android-support)
2727
- [IPv6 support](#ipv6-support)
28+
- [NDP spoofing](#ndp-spoofing)
2829
- [Traffic sniffing](#traffic-sniffing)
2930
- [JSON format](#json-format)
3031
- [Colored format](#colored-format)
@@ -75,6 +76,9 @@ Specify http server in proxy configuration of Postman
7576
- **ARP spoofing**\
7677
Proxy entire subnets with ARP spoofing approach
7778

79+
- **NDP spoofing**\
80+
Proxy IPv6 connections using Router/Neighbor Advertisement and RDNSS injections.
81+
7882
- **DNS Leak Protection**\
7983
DNS resolution occurs on SOCKS5 server side.
8084

@@ -108,7 +112,7 @@ You can download the binary for your platform from [Releases](https://github.com
108112
Example:
109113

110114
```shell
111-
GOHPTS_RELEASE=v1.12.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
115+
GOHPTS_RELEASE=v1.12.1; 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
112116
```
113117

114118
Alternatively, you can install it using `go install` command (requires Go [1.26](https://go.dev/doc/install) or later):
@@ -184,8 +188,10 @@ OPTIONS:
184188
-wu Number of instances of transparent UDP proxy server (Default: number of CPU cores)
185189
-auto Automatically setup iptables for transparent proxy (requires elevated privileges)
186190
-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")
191+
-ndpspoof Enable NDP spoof proxy for selected targets (Example: "ra true;na true;targets fe80::3a1c:7bff:fe22:91a4;fullduplex false;debug true")
187192
-mark Set mark for each packet sent through transparent proxy (Default: redirect 0, tproxy 100)
188193
-P Comma separated list of ports to ignore when proxying traffic (Example: "22,80,443,9092")
194+
-dump Dump iptables rules and other system settings generated by -auto flag
189195
```
190196
191197
### Configuration via CLI flags
@@ -541,6 +547,8 @@ sudo bettercap -eval "net.probe on;net.recon on;set arp.spoof.fullduplex true;ar
541547
542548
Check proxy logs for traffic from other devices from your LAN
543549
550+
For more information about arpspoof options see `gohpts -h` and [https://github.com/shadowy-pycoder/arpspoof](https://github.com/shadowy-pycoder/arpspoof)
551+
544552
### UDP support
545553
546554
[[Back]](#table-of-contents)
@@ -614,6 +622,63 @@ sudo ./gohpts -T 8888 -Tu 8889 -M tproxy -sniff -body -auto -d -6
614622
615623
3. Visit any website on your virtual machine and see traffic in proxy logs
616624
625+
### NDP spoofing
626+
627+
[[Back]](#table-of-contents)
628+
629+
`GoHPTS` has in-built functionality to perform NDP spoofing in IPv6 networks with Router Advertisement (RA) and Neighbor Advertisement (NA) packets. It also includes RDNSS option in RA packets to put host as a IPv6 nameserver for affected clients. When combined with transparent proxy mode (TCP/UDP), NDP spoofing allows `gohpts` to proxy traffic for clients in the local networks. As is the case with [ARP spoofing](#arp-spoofing), you can set ndp spoof options with single `-ndpspoof` flag:
630+
631+
Example:
632+
633+
```shell
634+
sudo env PATH=$PATH gohpts -d -T 8888 -M tproxy -sniff -body -auto -mark 100 -ndpspoof "ra true;na true;targets fe80::3a1c:7bff:fe22:91a4;fullduplex false;debug true"
635+
```
636+
637+
For more information about ndpspoof options see `gohpts -h` and [https://github.com/shadowy-pycoder/ndpspoof](https://github.com/shadowy-pycoder/ndpspoof)
638+
639+
Plese note that some options like `rdnss`, `gateway`, `interface` are set automatically by `gohpts` itself to properly function as a proxy.
640+
641+
Since `gohpts` proxies all connections via upstream SOCKS5 server, you need to have a working server with IPv4/IPv6 and TCP/UDP support. Obviously, a remote machine (e.g. VPS) should also have IPv6 connectivity working. Needless to say, the machine on which `gohpts` is installed should be part of network with IPv6 support.
642+
643+
Example setup for NDP spoofing to work correctly:
644+
645+
1. Connect to VPS
646+
647+
```shell
648+
ssh remote@203.0.113.10
649+
```
650+
651+
2. Install dependencies
652+
653+
```shell
654+
GO_VERSION=$(curl 'https://go.dev/VERSION?m=text' | head -n1)
655+
cd ~/Downloads/ && wget https://go.dev/dl/$GO_VERSION.linux-amd64.tar.gz
656+
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf $GO_VERSION.linux-amd64.tar.gz
657+
```
658+
659+
3. Setup SOCKS5 server (make sure firewall rules do not block used ports)
660+
661+
```shell
662+
git clone https://github.com/wzshiming/socks5.git && cd socks5
663+
go build -o ./bin/socks5_server ./cmd/socks5/*.go
664+
./bin/socks5_server -a :3000
665+
```
666+
667+
4. Go back to your host machine and install `gohpts` (see [Installation](#installation))
668+
669+
5. Run `gohtps`:
670+
671+
```shell
672+
sudo env PATH=$PATH gohpts -s 203.0.113.10:3000 -T 8888 -Tu 8889 -M tproxy -sniff -body -auto -mark 100 -arpspoof "fullduplex true;debug true" -ndpspoof "ra true;debug true
673+
" -6 -d
674+
```
675+
676+
6. Get another device (phone, tablet, etc) and connect it to the same network. Try to access Internet and check if some traffic appears on your host machine. Check public IP address with some online tools (it should match your VPS address `203.0.113.10` in this case or global IPv6 address)
677+
678+
7. Stop proxy by hitting Ctrl+C
679+
680+
8. Profit!
681+
617682
## Traffic sniffing
618683
619684
[[Back]](#table-of-contents)
@@ -800,6 +865,12 @@ Learn more about transparent proxies by visiting the following links:
800865
- [https://github.com/semigodking/redsocks](https://github.com/semigodking/redsocks)
801866
- [https://github.com/ginuerzh/gost](https://github.com/ginuerzh/gost)
802867
868+
IPv4/IPv6 network security:
869+
870+
- [https://caster0x00.com/legless/](https://caster0x00.com/legless/)
871+
- [https://caster0x00.com/intercept/](https://caster0x00.com/intercept/)
872+
- [https://www.prosec-networks.com/en/blog/ipv6-mitm/](https://www.prosec-networks.com/en/blog/ipv6-mitm/)
873+
803874
## Contributing
804875
805876
[[Back]](#table-of-contents)

cmd/gohpts/cli.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ const usageTproxy string = `
7070
-wu Number of instances of transparent UDP proxy server (Default: number of CPU cores)
7171
-auto Automatically setup iptables for transparent proxy (requires elevated privileges)
7272
-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")
73+
-ndpspoof Enable NDP spoof proxy for selected targets (Example: "ra true;na true;targets fe80::3a1c:7bff:fe22:91a4;fullduplex false;debug true")
7374
-mark Set mark for each packet sent through transparent proxy (Default: redirect 0, tproxy 100)
7475
-P Comma separated list of ports to ignore when proxying traffic (Example: "22,80,443,9092")
76+
-dump Dump iptables rules and other system settings generated by -auto flag
7577
`
7678

7779
func root(args []string) error {
@@ -152,12 +154,24 @@ func root(args []string) error {
152154
"",
153155
"Enable ARP spoof proxy for selected targets",
154156
)
157+
flags.StringVar(
158+
&conf.NDPSpoof,
159+
"ndpspoof",
160+
"",
161+
"Enable NDP spoof proxy for selected targets",
162+
)
155163
flags.StringVar(
156164
&conf.IgnoredPorts,
157165
"P",
158166
"",
159167
`Comma separated list of ports to ignore when proxying traffic (Example: "22,80,443,9092")`,
160168
)
169+
flags.BoolVar(
170+
&conf.Dump,
171+
"dump",
172+
false,
173+
"Dump iptables rules and other system settings generated by -auto flag",
174+
)
161175
}
162176
flags.StringVar(&conf.LogFilePath, "logfile", "", "Log file path (Default: stdout)")
163177
flags.BoolVar(&conf.Debug, "d", false, "Show logs in DEBUG mode")
@@ -226,6 +240,11 @@ func root(args []string) error {
226240
return fmt.Errorf("-wu requires -Tu flag")
227241
}
228242
}
243+
if seen["ndpspoof"] {
244+
if !seen["6"] {
245+
return fmt.Errorf("-ndpspoof requires -6 flag")
246+
}
247+
}
229248
if seen["mark"] {
230249
if !seen["t"] && !seen["T"] && !seen["Tu"] {
231250
return fmt.Errorf("-mark requires -t, -T or -Tu flag")
@@ -236,6 +255,11 @@ func root(args []string) error {
236255
return fmt.Errorf("-P requires -auto flag")
237256
}
238257
}
258+
if seen["dump"] {
259+
if !seen["auto"] {
260+
return fmt.Errorf("-dump requires -auto flag")
261+
}
262+
}
239263
if seen["f"] {
240264
for _, da := range []string{"s", "u", "U", "c", "k", "l", "i"} {
241265
if seen[da] {

colorize.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818

1919
var (
2020
ipPortPattern = regexp.MustCompile(
21-
`(?:\[(?:[0-9a-fA-F:.]+(?:%[a-zA-Z0-9_.-]+)?)\]|(?:\d{1,3}\.){3}\d{1,3})(?::(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4}))?`,
21+
`(?:(?:\[(?:[0-9a-fA-F:.]+(?:%[a-zA-Z0-9_.-]+)?)\]|(?:\d{1,3}\.){3}\d{1,3})(?::(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4}))?|(?:[0-9a-fA-F:]+:+[0-9a-fA-F:]+(?:%[a-zA-Z0-9_.-]+)?))`,
2222
)
2323
domainPattern = regexp.MustCompile(
2424
`\b(?:[a-zA-Z0-9-]{1,63}\.)+(?:com|net|org|io|co|uk|ru|de|edu|gov|info|biz|dev|app|ai|tv)(?::(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4}))?\b`,
@@ -30,7 +30,9 @@ var (
3030
credsPattern = regexp.MustCompile(
3131
`(?i)(?:"|')?(username|user|login|email|password|pass|pwd)(?:"|')?\s*[:=]\s*(?:"|')?([^\s"'&]+)`,
3232
)
33-
macPattern = regexp.MustCompile(`(?i)([a-z0-9_]+_[0-9a-f]{2}(?::[0-9a-f]{2}){2}|(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2})`)
33+
macPattern = regexp.MustCompile(
34+
`(?i)(?:\b[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}\b|\b[0-9a-f]{2}-[0-9a-f]{2}-[0-9a-f]{2}-[0-9a-f]{2}-[0-9a-f]{2}-[0-9a-f]{2}\b|\b[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}\b|\b[a-z0-9_]+_[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}\b)`,
35+
)
3436
portsPattern = regexp.MustCompile(
3537
`^\s*(?:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{0,4}|[1-9]\d{0,3})\s*(?:,\s*(?:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{0,4}|[1-9]\d{0,3})\s*)*$`,
3638
)
@@ -53,6 +55,10 @@ var rColors = []func(string) *colors.Color{
5355
colors.MagentaBg,
5456
colors.RedBgDark,
5557
colors.YellowBg,
58+
colors.NewColor(215),
59+
colors.NewColorBgDark(215),
60+
colors.NewColor(138),
61+
colors.NewColorBgDark(138),
5662
}
5763

5864
func randColor() func(string) *colors.Color {
@@ -408,6 +414,9 @@ func colorizeLogMessage(line string, nocolor bool) string {
408414
return line
409415
}
410416
result := ipPortPattern.ReplaceAllStringFunc(line, func(match string) string {
417+
if macPattern.MatchString(match) {
418+
return match
419+
}
411420
return colors.Gray(match).String()
412421
})
413422
result = domainPattern.ReplaceAllStringFunc(result, func(match string) string {
@@ -424,6 +433,9 @@ func colorizeErrMessage(line string, nocolor bool) string {
424433
return line
425434
}
426435
result := ipPortPattern.ReplaceAllStringFunc(line, func(match string) string {
436+
if macPattern.MatchString(match) {
437+
return match
438+
}
427439
return colors.Red(match).String()
428440
})
429441
result = domainPattern.ReplaceAllStringFunc(result, func(match string) string {

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
module github.com/shadowy-pycoder/go-http-proxy-to-socks
22

3-
go 1.26.0
3+
go 1.26.1
44

55
require (
66
github.com/goccy/go-yaml v1.18.0
77
github.com/google/uuid v1.6.0
88
github.com/rs/zerolog v1.34.0
9-
github.com/shadowy-pycoder/arpspoof v0.0.1
10-
github.com/shadowy-pycoder/colors v0.0.1
11-
github.com/shadowy-pycoder/mshark v0.0.20
9+
github.com/shadowy-pycoder/arpspoof v0.0.2
10+
github.com/shadowy-pycoder/colors v0.0.2
11+
github.com/shadowy-pycoder/mshark v0.0.21
12+
github.com/shadowy-pycoder/ndpspoof v0.0.1
1213
github.com/wzshiming/socks5 v0.5.2
1314
golang.org/x/sys v0.33.0
1415
golang.org/x/term v0.32.0

go.sum

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
3232
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
3333
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
3434
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
35-
github.com/shadowy-pycoder/arpspoof v0.0.1 h1:K5D+cVGc3SCTI4VxSB6oE2x8SJgxRjE72E8Payk2jJA=
36-
github.com/shadowy-pycoder/arpspoof v0.0.1/go.mod h1:dsVZh4gbbQFA4BQLEmL2qpsjtytKwxaf4oA2tRmvCW8=
37-
github.com/shadowy-pycoder/colors v0.0.1 h1:weCj/YIOupqy4BSP8KuVzr20fC+cuAv/tArz7bhhkP4=
38-
github.com/shadowy-pycoder/colors v0.0.1/go.mod h1:lkrJS1PY2oVigNLTT6pkbF7B/v0YcU2LD5PZnss1Q4U=
39-
github.com/shadowy-pycoder/mshark v0.0.20 h1:xZTvrh3nFHIagPsv756P4gNEz1IOj3Fc4+fRc0feWhc=
40-
github.com/shadowy-pycoder/mshark v0.0.20/go.mod h1:1XgkjUmooSY3p9ygd0iInTrijsYbcKMQ7RXJLNP0Ygs=
35+
github.com/shadowy-pycoder/arpspoof v0.0.2 h1:9GMyAcn8fuzZfftWGLEDJBQB/NJbxXnV0EQewy0nOZM=
36+
github.com/shadowy-pycoder/arpspoof v0.0.2/go.mod h1:TP2JF4acJTXC6MJ0mjCkR6NB1L2ov/hJQF5s5TCbiFk=
37+
github.com/shadowy-pycoder/colors v0.0.2 h1:l4zvGOTPS92oxPIo6g+6t8tbzhh/v+6yT5A/3TQp8rc=
38+
github.com/shadowy-pycoder/colors v0.0.2/go.mod h1:lkrJS1PY2oVigNLTT6pkbF7B/v0YcU2LD5PZnss1Q4U=
39+
github.com/shadowy-pycoder/mshark v0.0.21 h1:kRp8uk2NuQnL0ypzD/EjjK9Gq2fNSTzn2U0PJYOKNiU=
40+
github.com/shadowy-pycoder/mshark v0.0.21/go.mod h1:uH8wnzPH5VTeKRvCFpvMvnJmjSYY4L6RRgM1V5AnF5A=
41+
github.com/shadowy-pycoder/ndpspoof v0.0.1 h1:Q8gXDiBtzL09HEL0Do+Wc3fWrWw13Ld9xKllhsI3vpQ=
42+
github.com/shadowy-pycoder/ndpspoof v0.0.1/go.mod h1:f9nXuIck5oHR4Cm8z2Ry6NjEEsQBBKhZrLYDcHmU4HU=
4143
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
4244
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
4345
github.com/wzshiming/socks5 v0.5.2 h1:LtoowVNwAmkIQSkP1r1Wg435xUmC+tfRxorNW30KtnM=

0 commit comments

Comments
 (0)