I posted this issue already to the mailing list, but I like to document this on here as well.
TUDPBlockSocket.RecvPacket() produces a Race Condition with the Error "WSAECONNRESET" on Empty Packet Probes.
I tried to implement my Perl Prototype as the Synapse TUDPBlockSocket Service.
Trying the Service Connectivity I used the Command Line Tool "nmap" and "traceroute" on Centos6 and Centos7
With the "nmap" Probe:
# nmap -sU -p <service_port> <service_ip>
nmap sends an empty Probe Packet to the Port as for Port Scanning Purposes.
18:56:24.006809 IP (tos 0x0, ttl 42, id 36839, offset 0, flags [none], proto UDP (17), length 28) <nmap_scanner>.54364 > <service_host>.<service_port>: UDP, length 0 0x0000: 14da e996 343e f832 e487 a5c0 0800 4500 ....4>.2......E. 0x0010: 001c 8fe7 0000 2a11 6b04 c0a8 0a22 c0a8 ......*.k....".. 0x0020: 0a73 d45c 16a8 0008 7ef3 0000 0000 0000 .s.\....~....... 0x0030: 0000 0000 0000 0000 0000 0000 ............ 18:56:24.106994 IP (tos 0x0, ttl 37, id 18864, offset 0, flags [none], proto UDP (17), length 28) <nmap_scanner>.local.54365 > <service_host>.<service_port>: UDP, length 0 0x0000: 14da e996 343e f832 e487 a5c0 0800 4500 ....4>.2......E. 0x0010: 001c 49b0 0000 2511 b63b c0a8 0a22 c0a8 ..I...%..;...".. 0x0020: 0a73 d45d 16a8 0008 7ef2 0000 0000 0000 .s.]....~....... 0x0030: 0000 0000 0000 0000 0000 0000 ............
Perl produces these System Calls for this communication:
select(8, [3], NULL, NULL, {10, 0}) = 1 (in [3], left {0, 705687}) recvfrom(3, "", 4096, 0, {sa_family=AF_INET, sin_port=htons(44786), sin_addr=inet_addr("nmap_scanner_ip")}, [16]) = 0
Which the Application can recognize as empty message and go ahead with normal business.
Or even a malicious attacking IP can be blocked.
Now Synapse TUDPBlockSocket uses these System Calls:
32379 ioctl(3, FIONREAD, [0]) = 0 32379 select(4, [3], NULL, NULL, {2, 0}) = 1 (in [3], left {0, 309687}) 32379 ioctl(3, FIONREAD, [0]) = 0
Which is communicated to the Application as "WSAECONNRESET" Error: "Connection reset by Peer"
1) The Application does not know where this Probe came from
2) Ignoring the "WSAECONNRESET" Error leads to continues
32379 select(4, [3], NULL, NULL, {2, 0}) = 1 (in [3], left {1, 999998}) 32379 ioctl(3, FIONREAD, [0]) = 0
Race Condition.
The Empty UDP Packet is still on the Socket but the TUDPBlockSocket is unable to process it.
This is really a bad Security Bug because simple Port Scans would block the Service for ever and consume endless Server CPU Resources.
I found the Function
TBlockSocket.RecvBuffer(Buffer: TMemory; Length: Integer): Integer;
accomplishes exactly what I was missing.It reads forcefully on the Socket and processes the Empty Packet.
It reports a String of "0" Bytes read but
1) Senders IP Address is obtained
2) Socket is cleared
So the Service can recover and continue with normal operations.
Last edit: Hugo Domibay 2020-01-31