User Tools

Site Tools


tutorials:security:kamailio-security

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
tutorials:security:kamailio-security [2014/01/29 11:55]
davy.van.de.moere_gmail.com [Accept their traffic]
tutorials:security:kamailio-security [2019/05/03 19:39]
henningw add user agent header example
Line 5: Line 5:
 Davy Van De Moere Davy Van De Moere
   <davy.van.de.moere@gmail.com>   <davy.van.de.moere@gmail.com>
 +
 +Added info of the secfilter module:
 +Jose Luis Verdeguer
 +  <pepeluxx@gmail.com>
 </code> </code>
  
Line 92: Line 96:
 </code> </code>
  
-==== Change the server header ====+==== Change the server and user agent header ====
  
 When Kamailio sends you a packet back, it will be friendly enough to tell you which version of Kamailio is running. This informs the attacker which types of attacks might make sense. When Kamailio sends you a packet back, it will be friendly enough to tell you which version of Kamailio is running. This informs the attacker which types of attacks might make sense.
Line 106: Line 110:
 <code> <code>
 server_signature=no server_signature=no
 +</code>
 +
 +In the same category you have the sip_warning parameter, which is by default enabled. This setting exposes a lot of information about your infrastructure. In production it is advisable to just disable:
 +
 +<code>
 +sip_warning=0
 +</code>
 +
 +To change the user agent header (e.g. used from the dispatcher module to send out OPTIONS requests) use this parameter:
 +
 +<code>
 +user_agent_header="User-Agent: My SIP Server"
 </code> </code>
  
Line 246: Line 262:
  
 You can do something similar for pike alerts. You can do something similar for pike alerts.
 +
 +===== Active detection and monitoring =====
  
 ==== Accept their traffic ==== ==== Accept their traffic ====
Line 295: Line 313:
 } }
 </code> </code>
 +
 +==== Secfilter module ====
 +
 +Secfilter is a module that has been designed to offer an additional layer of security over our communications. To achieve this, the following features are available:
 +
 +  * Blacklist to block user agents, IP addresses, countries, domains and users.
 +  * Whitelist to allow user agents, IP addresses, countries, domains and users.
 +  * Blacklist of destinations where the called number is not allowed.
 +  * SQL injection attacks prevention.
 +
 +For example, to block IP addresses we have to use a database because it is very common to update the blacklist, since every day we receive many attacks from different places. The goal of this module is to avoid unnecessary queries to the database, so all the data will be in the memory.
 +
 +We can use RPC commands to update blacklists and whitelists. And also to see some statistics of blocked messages.
 +
 +Example of use:
 +
 +<code>
 +loadmodule    "geoip.so"
 +loadmodule    "secfilter.so"
 +
 +...
 +
 +modparam("secfilter", "db_url", DBURL)
 +modparam("secfilter", "dst_exact_match", 0)
 +
 +...
 +
 +route[SECURITY_CHECKS] {
 +        if (geoip_match("$si", "src")) {
 +                # return values ...
 +                #  2 = whitelisted
 +                #  1 = not found
 +                # -1 = error
 +                # -2 = blacklisted
 +                secf_check_country($gip(src=>cc));
 +                if ($? == -2) {
 +                        xalert("$rm from $si blocked because Country '$gip(src=>cc)' is blacklisted");
 +                        exit;
 +                }
 +        }
 +
 +        secf_check_ip();
 +        if ($? == -2) {
 +                xalert("$rm from $si blocked because IP address is blacklisted");
 +                exit;
 +        }
 +
 +        secf_check_sqli_all();
 +
 +        secf_check_ua();
 +        if ($? == -2) {
 +                xalert("$rm from $si blocked because UserAgent '$ua' is blacklisted");
 +                exit;
 +        }
 + 
 +        # return values ...
 +        #  4 = name whitelisted
 +        #  3 = domain whitelisted
 +        #  2 = user whitelisted
 +        #  1 = not found
 +        # -1 = error
 +        # -2 = user blacklisted
 +        # -3 = domain blacklisted
 +        # -4 = name blacklisted
 +        secf_check_from_hdr();
 +        switch ($?) {
 +                case -2:
 +                        xalert("$rm to $si blocked because From user '$fU' is blacklisted");
 +                        exit;
 +                case -3:
 +                        xalert("$rm to $si blocked because From domain '$fd' is blacklisted");
 +
 +                case -4:
 +                        xalert("$rm to $si blocked because From name '$fn' is blacklisted");
 +                        exit;
 +        };
 +
 +        secf_check_to_hdr();
 +        switch ($?) {
 +                case -2:
 +                        xalert("$rm to $si blocked because To user '$tU' is blacklisted");
 +                        exit;
 +                case -3:
 +                        xalert("$rm to $si blocked because To domain '$td' is blacklisted");
 +                        exit;
 +                case -4:
 +                        xalert("$rm to $si blocked because To name '$tn' is blacklisted");
 +                        exit;
 +        };
 +
 +        secf_check_contact_hdr();
 +        switch ($?) {
 +                case -2:
 +                        xalert("$rm to $si blocked because Contact user '$ct' is blacklisted");
 +                        exit;
 +                case -3:
 +                        xalert("$rm to $si blocked because Contact domain '$ct' is blacklisted");
 +                        exit;
 +        };
 +
 +        if (is_method("INVITE")) {
 +                secf_check_dst($rU);
 +                if ($? == -2) {
 +                        xalert("$rm from $si blocked because destination $rU is blacklisted");
 +                        exit;
 +                }
 +        }
 +}
 +</code>
 +
 +Some RPC commands:
 +
 +<code>
 +$ kamcmd secfilter.print ua
 +
 +User-agent
 +==========
 +[+] Blacklisted
 +    -----------
 +    0001 -> friendly-scanner
 +    0002 -> pplsip
 +    0003 -> sipcli
 +    0004 -> sundayddr
 +    0005 -> iWar
 +    0006 -> sipsak
 +    0007 -> VaxSIPUserAgent
 +    0008 -> SimpleSIP
 +    0009 -> SIP Call
 +    0010 -> Ozeki
 +    0011 -> VoIPSec
 +    0012 -> SIPScan
 +    0013 -> Conaito
 +    0014 -> UsaAirport
 +    0015 -> PortSIP VoIP SDK
 +    0016 -> zxcvfdf11
 +    0017 -> fdgddfg546df4g8d5f
 +
 +[+] Whitelisted
 +    -----------
 +    0001 -> my custom ua
 +</code>
 +
 +<code>
 +$ kamcmd secfilter.stats
 +
 +Blocked messages (blacklist)
 +============================
 +[+] By user-agent    : 1256
 +[+] By country       : 45
 +[+] By from domain   : 0
 +[+] By to domain     : 0
 +[+] By contact domain: 1
 +[+] By IP address    : 2552
 +[+] By from name     : 0
 +[+] By to name       : 0
 +[+] By contact name  : 0
 +[+] By from user     : 316
 +[+] By to user       : 134
 +[+] By contact user  : 0
 +
 +Allowed messages (whitelist)
 +============================
 +[+] By user-agent    : 0
 +[+] By country       : 478
 +[+] By from domain   : 0
 +[+] By to domain     : 0
 +[+] By contact domain: 0
 +[+] By IP address    : 0
 +[+] By from name     : 0
 +[+] By to name       : 0
 +[+] By contact name  : 0
 +[+] By from user     : 0
 +[+] By to user       : 0
 +[+] By contact user  : 0
 +
 +Other blocked messages
 +======================
 +[+] Destinations   : 0
 +[+] SQL injection  : 213
 +</code>
 +
 +
 +===== Digest authentication =====
 +
 +==== What is a digest ====
 +
 +Just in case the reader wouldn't know what a digest is (and yes you should read more on the topic), a digest is a simple cryptographic function, which is based on symmetrical encryption. 
 +
 +As a very simplified example, assume having two parties Alice and Bob. 
 +
 +Bob and Alice agree a 'secret' which only they know, for ease of the calculation we take e.g. the number 5.
 +
 +When Bob contacts Alice, Alice 'challenges' Bob, giving him a question which he has to answer with the secret. E.g. Bob, what is 13 minus the secret. As Bob only knows the secret (5), him giving the correct answer (8), is a guarantee it was Bob giving the 'response'.
 +
 +Offcourse, the math needs to be a bit more complex, and in SIP it's generally based on MD5  ;)
 +
 +A SIP digest looks like:
 +
 +<code>
 +Authorization: Digest username="replayuser", realm="mslync.com", nonce="Uu+v01LvrXvRLxDlRFmj8f+x1sDLIA2ERmialM3+jEm2cBJ0R33hCxp8zyeA", 
 +uri="sip:lync.com", response="c9295a60ag08554d26a7e17b7aac780b"
 +</code>
 +
 +Nonce == the challenge the server sends
 +Response == the Nonce + a cryptographic function + the secret as a variable.
 +
 +
 +==== The secret being too simple ====
 +
 +One of the inherit weaknesses of MD5 is that the calculation goes really fast. Which means if one is able to intercept a sip digest, the secret can be bruteforced. 
 +
 +Being the Nonce, the Response & the algoritm is known, the only unknown is the secret. So one can start guessing which secret it is. Today a password between 1 and 6 characters can be cracked on a normal PC in about an hour. To make matters worse, over Amazon EC2, it is claimed a password of 10 characters can be cracked for less then $100. There are even online services offering this, e.g. [[https://www.cloudcracker.com/|Cloudcracker]]
 +
 +As such, it is advisable to have your secrets be autogenerated, to be long (e.g. 14 characters) and to have a very wide character set.
 +
 +Also, it is advisable to always use TLS to exchange SIP messages. Do note that it is up to the client to verify the correct certificate is used (otherwise a man in the middle attack is not that difficult)
 +
 +==== Replay attack ====
 +
 +It is not sufficient for the server to check if the digest is correct. The server should also check if that digest has not been used already! Otherwise an attacker could at infinitum re-use the digest to make calls.
 +
 +Kamailio has stock already a few mechanisms to combat this, but it can be tweaked to be better. By default a digest can be replayed for 300 seconds, but Kamailio can do better. If you want to test, ngrep an INVITE which has a digest, and follow this [[http://www.applit.be/?page_id=102|quick and (very) dirty way to replay a SIP packet]]. 
 +
 +You can improve this by adding the following. This will break the possibility to do a replay attack from a different machine, and will reduce the timeframe in which a replay attack can be done. 
 +
 +<code>
 +modparam("auth_db", "db_url", DBURL)
 +modparam("auth_db", "calculate_ha1", yes)
 +modparam("auth_db", "password_column", "password")
 +modparam("auth_db", "load_credentials", "")
 +modparam("auth_db", "use_domain", MULTIDOMAIN)
 +
 +modparam("auth", "nonce_count", 1) # enable nonce_count support
 +modparam("auth", "qop", "auth"   # enable qop=auth
 +modparam("auth", "nonce_expire", 60)
 +modparam("auth", "nonce_auth_max_drift", 2)
 +
 +# For REGISTER requests we hash the Request-URI, Call-ID, and source IP of the
 +# request into the nonce string. This ensures that the generated credentials
 +# cannot be used with another registrar, user agent with another source IP
 +# address or Call-ID. Note that user agents that change Call-ID with every
 +# REGISTER message will not be able to register if you enable this.
 +modparam("auth", "auth_checks_register", 11)
 +
 +# For dialog-establishing requests (such as the original INVITE, OPTIONS, etc)
 +# we hash the Request-URI and source IP. Hashing Call-ID and From tags takes
 +# some extra precaution, because these checks could render some UA unusable.
 +modparam("auth", "auth_checks_no_dlg", 9)
 +
 +# For mid-dialog requests, such as re-INVITE, we can hash source IP and
 +# Request-URI just like in the previous case. In addition to that we can hash
 +# Call-ID and From tag because these are fixed within a dialog and are
 +# guaranteed not to change. This settings effectively restrict the usage of
 +# generated credentials to a single user agent within a single dialog.
 +modparam("auth", "auth_checks_in_dlg", 15)
 +
 +</code>
 +
tutorials/security/kamailio-security.txt ยท Last modified: 2019/05/23 12:42 by pepelux