Hi All,
Having the following Header: Record-Route: sip:192.168.1.1;lr;did=637.07c7c2d7
How can i extract only IP value from this header? Thank You.
Hi,
On Sat, Oct 28, 2017 at 05:34:04PM +0300, Soltanici Ilie wrote:
Having the following Header: Record-Route: sip:192.168.1.1;lr;did=637.07c7c2d7
How can i extract only IP value from this header?
Generally, when presented with a URI, you can extract the host/domain component using the URI transformations, e.g.
$(hdr(Record-Route){nameaddr.uri}{uri.host})
If you are dealing with a single Record-Route header that has a singular URI value, this should work fine.
More generally, a concern here would be that Record-Routes can occur in a variety of configurations. For one, they can be stacked if the message has gone through multiple proxies which each add their own RR, e.g.
Record-Route: sip:proxy1;lr Record-Route: sip:proxy2;lr Record-Route: sip:proxy3;lr
If so, you will need to refer to the appropriate header subscript in order to extract the domain you really want, i.e. $hdr(name)[N]), as explained here:
https://www.kamailio.org/wiki/cookbooks/5.0.x/pseudovariables#hdr_name_-_hea...
SIP also allows the above to be compacted into a single RR header containing multiple URIs, i.e.
Record-Route: sip:proxy1;lr,sip:proxy2;lr,sip:proxy3;lr
So a truly bulletproof approach would have to make accommodations for that scenario as well.
In situations where a given approach can only work for a small subset of possibilities, I am inclined to ask: what is the real problem you are trying to solve? Could it perhaps be solved another way?
-- Alex
Hi Alex,
Thank You, i'm trying to use this config:
if($(hdr(Record-Route)[0]{nameaddr.uri}) != $si and $(hdr(Record-Route)[0]{nameaddr.uri}) != $null) { xlog("L_INFO","Spoofing attack detected from $si, blocking"); exit; } taken from here: https://www.kamailio.org/wiki/tutorials/security/kamailio-security
but, it is not working because as you said the record-route - can be different, like in my case: Record-Route: sip:192.168.1.1;lr;did=637.07c7c2d7
Temporarily, i solved using this configuration:
if($(hdr(Record-Route)[0]{nameaddr.uri}) != $null) { if ( search_hf("Record-Route", ";", "f") ) { $var(record_route) = $(hdr(Record-Route)[0]{nameaddr.uri}{re.subst,/^sip:([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3});.*/\1/}); if($var(record_route)) != $si { xlogl("L_ERR","Spoofing Attack detected, Blocking\n"); exit; } } else { if($(hdr(Record-Route)[0]{nameaddr.uri}) != $si) { xlogl("L_ERR","Spoofing Attack detected, Blocking\n"); exit; } } }; but, i'm not sure that this is right configuration - and maybe it could be done better. How would you solve this problem? Thank You.
Hi,
A cleaner solution might make use of this, when processing in-dialog requests where the Record-Route would have been turned into a Route set:
https://www.kamailio.org/wiki/cookbooks/5.0.x/pseudovariables#route_uri_-_ur...
You could set a dialog-persistent variable indicating the original source address of the caller and callee next-hops:
https://www.kamailio.org/wiki/cookbooks/5.0.x/pseudovariables#dlg_var_key
And then check in the onsend_route if the next-hop address,
https://www.kamailio.org/wiki/cookbooks/5.0.x/pseudovariables#next_hop_addre...
compares to one of those endpoints.
However, I would ask why you are so concerned about this particular spoof attack. Putting a third-party address in Record-Route only affects in-dialog requests (end-to-end ACK, BYE, re-INVITE, etc.), which, if they cannot be matched to an existing dialog known by that destination, will simply be discarded.
I would be more concerned about Contact spoofing in the registrar, if you are using it.
-- Alex