1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00

Addressing the UDP reflection amplification attack: https://github.com/SoftEtherVPN/SoftEtherVPN/issues/1001

This commit is contained in:
Daiyuu Nobori 2019-10-22 11:14:05 +09:00
parent 46d8da6744
commit 4d42f450b2
2 changed files with 23 additions and 9 deletions

View File

@ -821,7 +821,7 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2: case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2:
// New connection (hard reset) // New connection (hard reset)
OvsSendControlPacket(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0); OvsSendControlPacketEx(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0, true);
c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY; c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY;
break; break;
@ -1552,6 +1552,10 @@ void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *
// Send the control packet // Send the control packet
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size) void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size)
{
OvsSendControlPacketEx(c, opcode, data, data_size, false);
}
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend)
{ {
OPENVPN_CONTROL_PACKET *p; OPENVPN_CONTROL_PACKET *p;
// Validate arguments // Validate arguments
@ -1562,6 +1566,8 @@ void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT da
p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET)); p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET));
p->NoResend = no_resend;
p->OpCode = opcode; p->OpCode = opcode;
p->PacketId = c->NextSendPacketId++; p->PacketId = c->NextSendPacketId++;
@ -2558,9 +2564,13 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list)
OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k); OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k);
if (cp->NextSendTime <= s->Now) if (cp->NextSendTime <= s->Now)
{
if (cp->NoResend == false || cp->NumSent == 0) // To address the UDP reflection amplification attack: https://github.com/SoftEtherVPN/SoftEtherVPN/issues/1001
{ {
OPENVPN_PACKET *p; OPENVPN_PACKET *p;
cp->NumSent++;
num = OvsGetAckReplyList(c, acks); num = OvsGetAckReplyList(c, acks);
p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks, p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks,
@ -2575,6 +2585,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list)
AddInterrupt(s->Interrupt, cp->NextSendTime); AddInterrupt(s->Interrupt, cp->NextSendTime);
} }
} }
}
// If the response with an ACK-only packet is required, respond such that // If the response with an ACK-only packet is required, respond such that
num = OvsGetAckReplyList(c, acks); num = OvsGetAckReplyList(c, acks);

View File

@ -108,6 +108,8 @@ struct OPENVPN_CONTROL_PACKET
UINT DataSize; // Data size UINT DataSize; // Data size
UCHAR *Data; // Data body UCHAR *Data; // Data body
UINT64 NextSendTime; // Scheduled next transmission time UINT64 NextSendTime; // Scheduled next transmission time
bool NoResend; // Disable re-sending
UINT NumSent; // How many times we have sent this packet
}; };
// OpenVPN packet // OpenVPN packet
@ -260,6 +262,7 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN
void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p); void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p);
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend);
void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p); void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p);
void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks); void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks);