Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UDP reflection amplification attack #1001

Closed
Alchiadus opened this issue Oct 17, 2019 · 10 comments
Closed

UDP reflection amplification attack #1001

Alchiadus opened this issue Oct 17, 2019 · 10 comments

Comments

@Alchiadus
Copy link

Alchiadus commented Oct 17, 2019

SoftEther is vulnerable to a UDP reflection amplification attack and can be abused to take on the role of the reflector.

We discovered the issue in production and were able to stop the attack at the firewall level by blocking all UDP traffic to SoftEther's listening ports, since we only support TCP at the moment.

Description

The attacker spoofs the IP address of the victim and uses it to send a UDP packet containing P_CONTROL_HARD_RESET_CLIENT_V2 to the server. SoftEther will respond to the victim with P_CONTROL_HARD_RESET_SERVER_V2. Since the victim will not reply with a P_ACK_V1, SoftEther assumes the packet got lost in transmission and will retransmit P_CONTROL_HARD_RESET_SERVER_V2 every OPENVPN_CONTROL_PACKET_RESEND_INTERVAL milliseconds (default 0.5 seconds) until the socket times out (default 30 seconds), resulting in an amplification factor of 60.

The attack is described in detail here: http://13.58.107.157/archives/8190.

Reproduction

I included a Python script that demonstrates the amplification attack (see udp_1194_amplification.py) and an example capture that shows the result (see udp_1194_amplification.pcapng).

udp_1194_amplification.zip

Mitigations

The attack could be mitigated by implementing an exponential backoff strategy similar to how OpenVPN does it (as shown on the page that describes the attack in detail), which would result in an amplification factor of 5 rather than 60.

Ideally, SoftEther would rate limit IPs, thus preventing the creation of a new session if that IP's limit has been reached.

@paulmenzel
Copy link
Contributor

Thank you for the analysis. Our instance was used for this kind of attack already.

@dnobori
Copy link
Member

dnobori commented Oct 17, 2019

Alchiadus,

Thank you for discovering it. It is OpenVPN original protocol's vulnerability.

I have an idea to address this protocol vulnerability.
In the processing of OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2, it is easy to disable the re-transmission mechanism completely. In this case, the packet loss of OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2 will be a connection problem. However, we can assume that the VPN client will re-send the P_CONTROL_HARD_RESET_CLIENT_V2 request packet soon, and the problem will solved.

How you you think about this idea?

@paulmenzel
Copy link
Contributor

@dnobori, yes, that sounds reasonable.

@dnobori
Copy link
Member

dnobori commented Oct 17, 2019

Good, good, I am willing to implement the above solution.

@Alchiadus
Copy link
Author

Alchiadus commented Oct 17, 2019

I think that would work. I tried to test what would happen if SoftEther were not to send the P_CONTROL_HARD_RESET_SERVER_V2 to simulate packet loss and the OpenVPN client indeed seems to retransmit the P_CONTROL_HARD_RESET_CLIENT_V2 about 3 times until a TLS timeout occurs after 10 seconds.

With the proposed change, SoftEther will still continue to transmit one P_CONTROL_HARD_RESET_SERVER_V2 for every P_CONTROL_HARD_RESET_CLIENT_V2 it receives (even if the same IP address sends it many times per second), so I still believe rate limiting would be a nice feature to have in SoftEther, but not retransmitting the P_CONTROL_HARD_RESET_SERVER_V2 will drastically reduce the impact of this particular attack.

@dnobori
Copy link
Member

dnobori commented Oct 17, 2019

SoftEther will still continue to transmit one P_CONTROL_HARD_RESET_SERVER_V2 for every P_CONTROL_HARD_RESET_CLIENT_V2 it receives (even if the same IP address sends it many times per second)

I suppose that the above behavior is not a problem. It doesn't behave as amplifier.

@davidebeatrici
Copy link
Member

Fixed in #1014.

@Alchiadus
Copy link
Author

Thank you for the quick response and fix.

@dnobori
Copy link
Member

dnobori commented Oct 22, 2019

Please kindly test it.

@Alchiadus
Copy link
Author

I can confirm the fix addresses the amplification issue: after sending a P_CONTROL_HARD_RESET_CLIENT_V2 I get at most one P_CONTROL_HARD_RESET_SERVER_V2 back.

Andy2244 added a commit to Andy2244/openwrt-extra that referenced this issue Nov 26, 2019
* 5.01.9672 release
* Cedar: handle UDP acceleration and R-UDP versions
* Mayaqua: implement R-UDP version 2, powered by ChaCha20-Poly1305
* Cedar: implement UDP acceleration version 2, powered by ChaCha20-Poly1305
* Cedar: serve new web management interface
* Cedar: implement detailed protocol info
* Mayaqua: add Windows Server 2019 to the supported operating systems list
* Cedar: various fixes
* Cedar: add "DisableIPsecAggressiveMode" option
* Make install dir for unit files configurable
* Protocol.c: adapt ClientConnectGetSocket() for new proxy functions
* Wpc.c: adapt WpcSockConnectEx() for new proxy functions
* Protocol: add ProxyCodeToCedar()
* Move generic proxy stuff from Cedar to Mayaqua
* Proto_OpenVPN.c: improve OvsProcessData(), fix out-of-bounds access found by Coverity
* Proto_OpenVPN.c: fix segmentation fault in OvsProceccRecvPacket()
* Addressing the UDP reflection amplification attack: SoftEtherVPN/SoftEtherVPN#1001
* Mayaqua.h: include <stdarg.h> for "va_list" on Illumos
* Protocol.c: fix bug in ClientConnectGetSocket() causing custom HTTP header not to work
* Mayaqua: move HTTP functions from "Network" to "HTTP"
* Move GetMimeTypeFromFileName() and related structure to Mayaqua
* Mayaqua.h: include <stdio.h> for "FILE"
* Mayaqua.h: include <stddef.h>, for "wchar_t"
* Bump mixin-deep in /src/bin/hamcore/wwwroot/admin/default
* - Fixed the problem occurs when RPC messages between Cluster Members exceed 64Kbytes. - Fixed the RADIUS PEAP client to use the standard TLS versioning. - Implementation of a function to fix the MAC address of L3 VPN protocol by entering e.g. "MAC: 112233445566" in the "Notes" field of the user information. - Implementation of a function to fix the virtual MAC address to be assigned to the L3 VPN client as a string attribute from RADIUS server when authentication.
* Updating built-in Win32 libraries - OpenSSL 1.1.1 -> 1.1.1d - zlib 1.2.3 -> 1.2.11
* Update strtable_cn.stb
* Avoid using hardcoded paths in log file enumeration
* Fix buffer overflow during NETBIOS name resolution
* Update SEVPN.sln
* Create strtable_pt_br.stb
* ci: display error if vpntest failed
* Fix several compile warnings on MS VC++ 2008.
* Enables crash minidump for Win32 vpntest. Minidump files will be saved to the 'C:\Users\<username>\AppData\Local\Temp\vpn_debug' (for normal user) or 'src\bin\vpn_debug\' (for administrator user).
* OpenVPN: use new protocol interface
* Add interface for easy protocol implementation
* add "no-deprecated" to openssl builds "no-deprecated" is widely used in openwrt devices
* Fix LibreSSL support
* Switch to OpenSSL THREADID API
* travis-ci: update openssl, libressl
* enable sonar-scan in travis-ci builds
* Virtual: fix race condition in DHCP server which resulted in multiple clients receiving the same IP
* Mayaqua: Fix compilation without deprecated OpenSSL APIs
* Mayaqua: Replace GNU specific sys/poll.h header with POSIX poll.h
* systemd: replace deprecated CAP_SYS_ADMIN with CAP_SYSLOG
Andy2244 added a commit to Andy2244/packages that referenced this issue Nov 26, 2019
* 5.01.9672 release
* Cedar: handle UDP acceleration and R-UDP versions
* Mayaqua: implement R-UDP version 2, powered by ChaCha20-Poly1305
* Cedar: implement UDP acceleration version 2, powered by ChaCha20-Poly1305
* Cedar: serve new web management interface
* Cedar: implement detailed protocol info
* Mayaqua: add Windows Server 2019 to the supported operating systems list
* Cedar: various fixes
* Cedar: add "DisableIPsecAggressiveMode" option
* Make install dir for unit files configurable
* Protocol.c: adapt ClientConnectGetSocket() for new proxy functions
* Wpc.c: adapt WpcSockConnectEx() for new proxy functions
* Protocol: add ProxyCodeToCedar()
* Move generic proxy stuff from Cedar to Mayaqua
* Proto_OpenVPN.c: improve OvsProcessData(), fix out-of-bounds access found by Coverity
* Proto_OpenVPN.c: fix segmentation fault in OvsProceccRecvPacket()
* Addressing the UDP reflection amplification attack: SoftEtherVPN/SoftEtherVPN#1001
* Mayaqua.h: include <stdarg.h> for "va_list" on Illumos
* Protocol.c: fix bug in ClientConnectGetSocket() causing custom HTTP header not to work
* Mayaqua: move HTTP functions from "Network" to "HTTP"
* Move GetMimeTypeFromFileName() and related structure to Mayaqua
* Mayaqua.h: include <stdio.h> for "FILE"
* Mayaqua.h: include <stddef.h>, for "wchar_t"
* Bump mixin-deep in /src/bin/hamcore/wwwroot/admin/default
* - Fixed the problem occurs when RPC messages between Cluster Members exceed 64Kbytes. - Fixed the RADIUS PEAP client to use the standard TLS versioning. - Implementation of a function to fix the MAC address of L3 VPN protocol by entering e.g. "MAC: 112233445566" in the "Notes" field of the user information. - Implementation of a function to fix the virtual MAC address to be assigned to the L3 VPN client as a string attribute from RADIUS server when authentication.
* Updating built-in Win32 libraries - OpenSSL 1.1.1 -> 1.1.1d - zlib 1.2.3 -> 1.2.11
* Update strtable_cn.stb
* Avoid using hardcoded paths in log file enumeration
* Fix buffer overflow during NETBIOS name resolution
* Update SEVPN.sln
* Create strtable_pt_br.stb
* ci: display error if vpntest failed
* Fix several compile warnings on MS VC++ 2008.
* Enables crash minidump for Win32 vpntest. Minidump files will be saved to the 'C:\Users\<username>\AppData\Local\Temp\vpn_debug' (for normal user) or 'src\bin\vpn_debug\' (for administrator user).
* OpenVPN: use new protocol interface
* Add interface for easy protocol implementation
* add "no-deprecated" to openssl builds "no-deprecated" is widely used in openwrt devices
* Fix LibreSSL support
* Switch to OpenSSL THREADID API
* travis-ci: update openssl, libressl
* enable sonar-scan in travis-ci builds
* Virtual: fix race condition in DHCP server which resulted in multiple clients receiving the same IP
* Mayaqua: Fix compilation without deprecated OpenSSL APIs
* Mayaqua: Replace GNU specific sys/poll.h header with POSIX poll.h
* systemd: replace deprecated CAP_SYS_ADMIN with CAP_SYSLOG

Signed-off-by: Andy Walsh <andy.walsh44+github@gmail.com>
Andy2244 added a commit to Andy2244/packages that referenced this issue Nov 26, 2019
* 5.01.9672 release
* Cedar: handle UDP acceleration and R-UDP versions
* Mayaqua: implement R-UDP version 2, powered by ChaCha20-Poly1305
* Cedar: implement UDP acceleration version 2, powered by ChaCha20-Poly1305
* Cedar: serve new web management interface
* Cedar: implement detailed protocol info
* Mayaqua: add Windows Server 2019 to the supported operating systems list
* Cedar: various fixes
* Cedar: add "DisableIPsecAggressiveMode" option
* Make install dir for unit files configurable
* Protocol.c: adapt ClientConnectGetSocket() for new proxy functions
* Wpc.c: adapt WpcSockConnectEx() for new proxy functions
* Protocol: add ProxyCodeToCedar()
* Move generic proxy stuff from Cedar to Mayaqua
* Proto_OpenVPN.c: improve OvsProcessData(), fix out-of-bounds access found by Coverity
* Proto_OpenVPN.c: fix segmentation fault in OvsProceccRecvPacket()
* Addressing the UDP reflection amplification attack: SoftEtherVPN/SoftEtherVPN#1001
* Mayaqua.h: include <stdarg.h> for "va_list" on Illumos
* Protocol.c: fix bug in ClientConnectGetSocket() causing custom HTTP header not to work
* Mayaqua: move HTTP functions from "Network" to "HTTP"
* Move GetMimeTypeFromFileName() and related structure to Mayaqua
* Mayaqua.h: include <stdio.h> for "FILE"
* Mayaqua.h: include <stddef.h>, for "wchar_t"
* Bump mixin-deep in /src/bin/hamcore/wwwroot/admin/default
* - Fixed the problem occurs when RPC messages between Cluster Members exceed 64Kbytes. - Fixed the RADIUS PEAP client to use the standard TLS versioning. - Implementation of a function to fix the MAC address of L3 VPN protocol by entering e.g. "MAC: 112233445566" in the "Notes" field of the user information. - Implementation of a function to fix the virtual MAC address to be assigned to the L3 VPN client as a string attribute from RADIUS server when authentication.
* Updating built-in Win32 libraries - OpenSSL 1.1.1 -> 1.1.1d - zlib 1.2.3 -> 1.2.11
* Update strtable_cn.stb
* Avoid using hardcoded paths in log file enumeration
* Fix buffer overflow during NETBIOS name resolution
* Update SEVPN.sln
* Create strtable_pt_br.stb
* ci: display error if vpntest failed
* Fix several compile warnings on MS VC++ 2008.
* Enables crash minidump for Win32 vpntest. Minidump files will be saved to the 'C:\Users\<username>\AppData\Local\Temp\vpn_debug' (for normal user) or 'src\bin\vpn_debug\' (for administrator user).
* OpenVPN: use new protocol interface
* Add interface for easy protocol implementation
* add "no-deprecated" to openssl builds "no-deprecated" is widely used in openwrt devices
* Fix LibreSSL support
* Switch to OpenSSL THREADID API
* travis-ci: update openssl, libressl
* enable sonar-scan in travis-ci builds
* Virtual: fix race condition in DHCP server which resulted in multiple clients receiving the same IP
* Mayaqua: Fix compilation without deprecated OpenSSL APIs
* Mayaqua: Replace GNU specific sys/poll.h header with POSIX poll.h
* systemd: replace deprecated CAP_SYS_ADMIN with CAP_SYSLOG

Signed-off-by: Andy Walsh <andy.walsh44+github@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants