How IPv6 Helps Routers Break

Foreword
I woke up today with the thought that a huge number of instructions for configuring NAT are advised to use a line of the form:
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEMany understand the problems of this design, and are advised to add:
iptables -A FORWARD -i ppp0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPTBut, often, they forget to set the FORWARD table to the default DROP action, or add the REJECT rule to the end of the table.
At first glance, everything seems to be normal. However, this is not the case. The fact is that if you do not prohibit routing traffic from the WAN port to the WAN port, someone from your WAN network (suppose the provider puts the entire entrance in one / 24) can route traffic through you by simply registering your IP as a gateway. All modern SOHO routers take this into account, but the inexperienced administrator who makes the router under normal linux may not know or forget about it. There were no such routers in the subnet of my provider, and my plan to take over the world failed. However, the article is not about that at all.
Magical colons
As you may know, many modern programs and services are binded to IP :: (two colons), and not to 0.0.0.0 , as it was before. IPv6 address :: means the same as IPv4 0.0.0.0 , i.e. “Listen to all interfaces”. Many people think that if a program listens ::, then this socket can only accept IPv6 connections, but this is far from the case.
In IPv6, there is the so-called mapping of IPv4 addresses to the IPv6 range. If the program listens on socket :: and is accessed from the IPv4 address 1.2.3.4 , then the program will receive a connection from the address :: ffff: 1.2.3.4 . This can be avoided by doing:
sysctl -w net.ipv6.bindv6only=1But this is not always necessary, because it is usually convenient that the program listens on one socket, and can receive connections via two protocols at once. In almost all distributions, IPv6 sockets behave just like that, i.e. bindv6only = 0.
fe80 and his friend ff02
If you are not stuck in the 90s, you are guaranteed to encounter IPv6 without knowing it yourself. Absolutely in all modern operating systems, IPv6 support is enabled by default, which means that for every interface (except for rare exceptions), an IPv6 Link-Local address is automatically assigned that starts with fe80 :: . Moreover, in some cases, this address is obtained simply by encoding the MAC address.
It would seem that finding Link-Local addresses should be problematic, but they are still long and scary, but here the multicast range ff02 :: comes to our aid .
There is such a cool address: ff02 :: 1 . If you ping it (be sure to indicate the interface, because this is the Link Local address), then all computers on the network will respond:
% ping6 ff02::1%enp4s0
PING ff02::1%enp4s0(ff02::1) 56 data bytes
64 bytes from fe80::21f:d0ff:fea2:46a3: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from fe80::fe8b:97ff:fe66:9100: icmp_seq=1 ttl=64 time=1.60 ms (DUP!)
64 bytes from fe80::226:9eff:fe6d:22a0: icmp_seq=1 ttl=64 time=1.62 ms (DUP!)
64 bytes from fe80::f2de:f1ff:fe27:3685: icmp_seq=1 ttl=64 time=1.70 ms (DUP!)
64 bytes from fe80::62a4:4cff:fe7b:1c90: icmp_seq=1 ttl=64 time=2.95 ms (DUP!)
64 bytes from fe80::fac0:91ff:fe32:5bbe: icmp_seq=1 ttl=64 time=3.02 ms (DUP!)
64 bytes from fe80::226:18ff:fe9e:4b3a: icmp_seq=1 ttl=64 time=3.09 ms (DUP!)
64 bytes from fe80::ba70:f4ff:fe8b:8dda: icmp_seq=1 ttl=64 time=3.14 ms (DUP!)
64 bytes from fe80::62a4:4cff:fea2:aee0: icmp_seq=1 ttl=64 time=3.27 ms (DUP!)
64 bytes from fe80::224:54ff:fedb:d17d: icmp_seq=1 ttl=64 time=3.93 ms (DUP!)
64 bytes from fe80::2a1:b0ff:fe40:904: icmp_seq=1 ttl=64 time=4.21 ms (DUP!)
64 bytes from fe80::76d0:2bff:fe69:31d8: icmp_seq=1 ttl=64 time=6.09 ms (DUP!)
As we can see, 11 devices responded. By the way, this address is very convenient to use if, for example, you have a server configured to receive an address through DHCP, and DHCP has fallen, or if you are directly connected to the server port, but you don’t want to raise DHCP. You just have to go to fe80-address on ssh.
If you ping the address ff02 :: 2 , then all IPv6 routers on the network will respond. Unfortunately, in my case there were none.
We scan routers
I decided to scan these addresses through nmap, and this is what happened:
% nmap -6 -T4 --open -n -iL list.txtStarting Nmap 6.46 ( http://nmap.org ) at 2014-06-07 16:53 MSK
Nmap scan report for fe80::f2de:f1ff:fe27:3685
Host is up (0.0014s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
53/tcp open domain
Nmap scan report for fe80::fe8b:97ff:fe66:9100
Host is up (0.0012s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
Nmap scan report for fe80::226:9eff:fe6d:22a0
Host is up (0.0012s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
Nmap scan report for fe80::62a4:4cff:fea2:aee0
Host is up (0.00099s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::226:18ff:fe9e:4b3a
Host is up (0.00094s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::62a4:4cff:fe7b:1c90
Host is up (0.00085s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::76d0:2bff:fe69:31d8
Host is up (0.00072s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::fac0:91ff:fe32:5bbe
Host is up (0.00037s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::ba70:f4ff:fe8b:8dda
Host is up (0.00059s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::2a1:b0ff:fe40:904
Host is up (0.00077s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap scan report for fe80::224:54ff:fedb:d17d
Host is up (0.0012s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
23/tcp open telnet
Nmap done: 11 IP addresses (11 hosts up) scanned in 4.04 secondsOver IPv4, all of these ports are closed.
As we can see, many routers have Telnet, a web interface, and DNS from outside via IPv6.
What does this mean? It's simple - the developers of the firmware of the router simply forgot about IPv6.
Open telnet routers:
- ASUS RT-N10 (2.0.3.2)
- ASUS RT-G32
- ASUS RT-G32.C1 (2.0.2.6)
- Upvel UR-312N4G
Web-based routers:
- D-Link DIR-615 (E4, 5.11NV)
- D-Link DIR-615 (E4, 5.11RU)
Many of them had standard admin / admin passwords.
On most of these routers, ip6tables (iptables for IPv6) were simply missing. The developers had to either disable IPv6 support in the kernel altogether, or make sure that http and telnet daemons were listening on 0.0.0.0 and not :: but, for some reason, they didn’t do this.
What if…?
If IPv6 was somehow configured on the router and, accordingly, IPv6 packet routing was enabled (net.ipv6.conf.all.forwarding = 1), and ip6tables is either not configured at all or is configured incorrectly, then it would be possible for sure just like with IPv4, route packets through this router.
Conclusion
I have already sent letters to some companies about these vulnerabilities, but I have not yet managed to some. In any case, letters will be sent to everyone.
Use IPv6, don't forget about it.
PS
It came as a surprise to me that browsers cannot open addresses with an interface. I couldn’t manage to open a link like http: // [fe80 :: a: b: c: d% enp4s0] in all browsers. They say that the percent sign needs to be escaped, i.e. http: // [fe80 :: a: b: c: d% 25enp4s0], but it still didn’t work out for me. I had to use port forwarding.