Security – How to stop SipVicious (‘friendly-scanner’) from flooding the SIP server

Securitysip

I run an SIP server which listens on UDP port 5060, and needs to accept authenticated requests from the public Internet.

The problem is that occasionally it gets picked up by people scanning for SIP servers to exploit, who then sit there all day trying to brute force the server. I use credentials that are long enough that this attack will never feasibly work, but it is annoying because it uses up a lot of bandwidth.

I have tried setting up fail2ban to read the Asterisk log and ban IPs that do this with iptables, which stops Asterisk from seeing the incoming SIP REGISTER attempts after 10 failed attempts (which happens in well under a second at the rate of attacks I'm seeing). However, SipVicious derived scripts do not immediately stop sending after getting an ICMP Destination Host Unreachable – they keep hammering the connection with packets. The time until they stop is configurable, but unfortunately it seems that the attackers doing these types of brute force attacks generally set the timeout to be very high (attacks continue at a high rate for hours after fail2ban has stopped them from getting any SIP response back once they have seen initial confirmation of an SIP server).

Is there a way to make it stop sending packets at my connection?

Best Answer

The publicly available SipVicious script that many of these attackers use stops the attack instantly if it receives an invalid SIP response with no From: line. You can identify SipVicious because it sets its User-Agent in the SIP requests to friendly-scanner.

Using this technique against a real-world attacker, I have been able to immediately stop the flood of packets. You can send such a packet with a simple script. For example:

cat >UnfriendlyScannerStopper.scala <<END
import java.net._

object UnfriendlyScannerStopper {
  def main(args : Array[String]) : Unit = {
    if (args.length < 2) {
      System.out.println("Usage: FriendlyScannerStopper ipAddr port")
      return
    }

    val udpSocket : DatagramSocket = new DatagramSocket();
    val packetContents : String = "SIP/2.0 400 Go Away!!!\r\n\r\n"
    udpSocket.send(new DatagramPacket(packetContents.getBytes("utf-8"), packetContents.size,
      InetAddress.getByName(args(0)), Integer.parseInt(args(1))))
  }
}
END
scala UnfriendlyScannerStopper.scala 188.138.107.179 5102

You will need to substitute 188.138.107.179 and 5102 for the address and port in the Via header of the SIP packets you are being sent in the attack.