Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
-------------------------------------------------------------------------- attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order <-- 500 Req Out of Order --------------------------------------------------------------------------
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
I think this is *VERY* dangerous and I hope I'm wrong.
Would help the dialog module here? does the dialog module check the CSeq of the BYE in some way and could it prevent Kamailio from generating the ACC STOP action? (I don't think so).
I've also asked in SIP-implementors and an idea could be generating the ACC STOP action when receiving the 200 OK for the BYE (and not when receiving the BYE itself). Of course this will be valid when the gateway is the recipient of the BYE (and we know the gateway is not an "attacker"), but this is not valid when the recipient of the BYE is an user since it could send no reply for the BYE.
The only solution I see is:
- Using the dialog module, Kamailio should check the CSeq value in the BYE. 1) Kamailio should forward the BYE just in case the CSeq is higher than the actual CSeq for this dialog direction. 2) Kamailio should generate the ACC STOP action just in case the CSeq is higher than the actual CSeq for this dialog direction.
Both 1) and 2) are needed since a gateway could accept a BYE with wrong CSeq. In this case the call is ended but the accounting STOP action doesn't exist (infinite call).
But I think this is too complex, isn't it?
On Thursday 18 December 2008, Iñaki Baz Castillo wrote:
Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
But I think this is too complex, isn't it?
It is complex, but not impossible.
I think is is feasable to do accounting on the proxy _IF_ you can trust your gateways and make use of that trust.
Start accounting on receipt of a 200 OK on an INVITE request.
Stop accounting: 1) On 200 OK (or maybe 481 or other response) from the gateway in response to a BYE. 2) On BYE from the gateway
2008/12/18 Alex Hermann alex@speakup.nl:
On Thursday 18 December 2008, Iñaki Baz Castillo wrote:
Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
But I think this is too complex, isn't it?
It is complex, but not impossible.
I think is is feasable to do accounting on the proxy _IF_ you can trust your gateways and make use of that trust.
Start accounting on receipt of a 200 OK on an INVITE request.
Stop accounting:
- On 200 OK (or maybe 481 or other response) from the gateway in response to
a BYE. 2) On BYE from the gateway
Is it feasible with the acc module? Can the acc be stoped depending on the response? is it valid to set the acc flag in on_reply_route?
Iñaki Baz Castillo wrote:
Stop accounting:
- On 200 OK (or maybe 481 or other response) from the gateway in response to
a BYE. 2) On BYE from the gateway
Is it feasible with the acc module? Can the acc be stoped depending on the response? is it valid to set the acc flag in on_reply_route?
You could do it manually by checking $T_reply_code and using acc_db_request() from a failure route.
Andreas
2008/12/18 Andreas Granig agranig@sipwise.com:
Iñaki Baz Castillo wrote:
Stop accounting:
- On 200 OK (or maybe 481 or other response) from the gateway in
response to a BYE. 2) On BYE from the gateway
Is it feasible with the acc module? Can the acc be stoped depending on the response? is it valid to set the acc flag in on_reply_route?
You could do it manually by checking $T_reply_code and using acc_db_request() from a failure route.
Yes, but it doesn't explain how to do the accounting when receiving the 200 OK for the BYE.
Iñaki Baz Castillo wrote:
2008/12/18 Andreas Granig agranig@sipwise.com:
Iñaki Baz Castillo wrote:
Stop accounting:
- On 200 OK (or maybe 481 or other response) from the gateway in
response to a BYE. 2) On BYE from the gateway
Is it feasible with the acc module? Can the acc be stoped depending on the response? is it valid to set the acc flag in on_reply_route?
You could do it manually by checking $T_reply_code and using acc_db_request() from a failure route.
Yes, but it doesn't explain how to do the accounting when receiving the 200 OK for the BYE.
Uh, well... register a new failure route and don't set the flag for automatic accounting when receiving the BYE, and in your failure route, do something like
if($T_reply_code == 200 || $T_reply_code == 481) # or whatever you want to account { acc_db_request("something", "acc"); }
Or am I missing something?
Andreas
2008/12/18 Andreas Granig agranig@sipwise.com:
Yes, but it doesn't explain how to do the accounting when receiving the 200 OK for the BYE.
Uh, well... register a new failure route and don't set the flag for automatic accounting when receiving the BYE, and in your failure route, do something like
if($T_reply_code == 200 || $T_reply_code == 481) # or whatever you want to account { acc_db_request("something", "acc"); }
Or am I missing something?
Well, failure_route will not be called when receiving a 200 OK in this BYE transaction. failure_route is only invoked for [3456]XX responses. 200 can only be handled in on_reply_route, but I don't know if acc flag can be set in on_reply_route.
Iñaki Baz Castillo wrote:
Well, failure_route will not be called when receiving a 200 OK in this BYE transaction. failure_route is only invoked for [3456]XX responses. 200 can only be handled in on_reply_route, but I don't know if acc flag can be set in on_reply_route.
Ah, yeah, you're right :) I think I was discussing this with Daniel some time ago, and as far as I remember, he thought it was save to do so (although it's not enabled for reply route, so you could call a route block from within your reply route to get around this instead of using failure route, but no guarantees for that)...
Andreas
Andreas Granig wrote:
I think I was discussing this with Daniel some time ago, and as far as I remember, he thought it was save to do so (although it's not enabled for
Save to call acc_db_request() is what I mean here...
2008/12/18 Andreas Granig agranig@sipwise.com:
Andreas Granig wrote:
I think I was discussing this with Daniel some time ago, and as far as I remember, he thought it was save to do so (although it's not enabled for
Save to call acc_db_request() is what I mean here...
Ah, ok, it makes sense. I will try it.
Thanks.
Hello,
On 12/18/08 17:09, Andreas Granig wrote:
Iñaki Baz Castillo wrote:
Well, failure_route will not be called when receiving a 200 OK in this BYE transaction. failure_route is only invoked for [3456]XX responses. 200 can only be handled in on_reply_route, but I don't know if acc flag can be set in on_reply_route.
Ah, yeah, you're right :) I think I was discussing this with Daniel some time ago, and as far as I remember,
AFAIK, we discussed about what happens if BYE comes in, proxy is restarted and then 200OK. BYE transaction was not accounted. So I suggested the usage of the acc_db_request(). A failed transaction (e.g., BYE with a negative reply) can be accounted.
But this one is a case that cannot be solved by using different flags from acc module. For INVITE, using the t_check_trans() for reply in onreply_route with latest kamailio version gives the possibility to drop the reply if there is no ongoing transaction, therefore you can force the call to fail.
For BYE is different, as you can lost the STOP event, while the call was established.
he thought it was save to do so (although it's not enabled for reply route, so you could call a route block from within your reply route to get around this instead of using failure route, but no guarantees for that)...
The problem with this approach is that acc_*_request() is looking at first line to get the method type. However, this can be extended to take it from CSeq if it is reply not request.
Cheers, Daniel
Hello,
On 12/18/08 13:48, Iñaki Baz Castillo wrote:
Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order
<-- 500 Req Out of Order
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
If you use the flags, the BYE will be accounted only if it gets a 200OK. If you set the failed transaction flag, then BYEs with negative replies are accounted as well.
However, this does not stop kamailio to account another BYE, which may have 200ok or other reply code. It is the job of your billing application to select the right BYE for computing the call duration.
I think this is *VERY* dangerous and I hope I'm wrong.
You can set accounting for each request withing a dialog (e.g., re-INVITE), and you can get many times same type of event (as it is based on method type). So keep accounting all BYEs you get in your proxy and chose the latest that match the dialog.
I see a potential issue with NAT traversal, if the session is ended upon receiving of a BYE, then no audio will go on even the BYE is negatively answered, which might be good as it forces end of call by parties (therefore a correct BYE).
Cheers, Daniel
Would help the dialog module here? does the dialog module check the CSeq of the BYE in some way and could it prevent Kamailio from generating the ACC STOP action? (I don't think so).
I've also asked in SIP-implementors and an idea could be generating the ACC STOP action when receiving the 200 OK for the BYE (and not when receiving the BYE itself). Of course this will be valid when the gateway is the recipient of the BYE (and we know the gateway is not an "attacker"), but this is not valid when the recipient of the BYE is an user since it could send no reply for the BYE.
The only solution I see is:
- Using the dialog module, Kamailio should check the CSeq value in the BYE.
- Kamailio should forward the BYE just in case the CSeq is higher
than the actual CSeq for this dialog direction. 2) Kamailio should generate the ACC STOP action just in case the CSeq is higher than the actual CSeq for this dialog direction.
Both 1) and 2) are needed since a gateway could accept a BYE with wrong CSeq. In this case the call is ended but the accounting STOP action doesn't exist (infinite call).
But I think this is too complex, isn't it?
El Jueves, 18 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
If you use the flags, the BYE will be accounted only if it gets a 200OK. If you set the failed transaction flag, then BYEs with negative replies are accounted as well.
Ok, I just imagine failed transaction flag for INVITE requests, but clearly it's also util for BYE accouting :)
However, this does not stop kamailio to account another BYE, which may have 200ok or other reply code. It is the job of your billing application to select the right BYE for computing the call duration.
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
Thanks a lot.
On 12/18/08 22:36, Iñaki Baz Castillo wrote:
El Jueves, 18 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
If you use the flags, the BYE will be accounted only if it gets a 200OK. If you set the failed transaction flag, then BYEs with negative replies are accounted as well.
Ok, I just imagine failed transaction flag for INVITE requests, but clearly it's also util for BYE accouting :)
However, this does not stop kamailio to account another BYE, which may have 200ok or other reply code. It is the job of your billing application to select the right BYE for computing the call duration.
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
I don't really get it ... would it select the first or last BYE for a call? Will it accept many BYEs for same call or will trigger failure?
Cheers, Daniel
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
I don't really get it ... would it select the first or last BYE for a call? Will it accept many BYEs for same call or will trigger failure?
You can configure the SQL "UPDATE" query for the accounting STOP action in radius, so for example: - The first matching BYE will fill a row field "completed" and set it to "1". - At the same time the SQL query has a "WHERE completed = 0".
In this way, just the first BYE will trigger an UPDATE SQL query. Any other BYE will be discarded by MySQL server because doesn't honor the "WHERE" clausule and will no "re-update" the accounting row.
On 12/20/08 11:55, Iñaki Baz Castillo wrote:
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
I don't really get it ... would it select the first or last BYE for a call? Will it accept many BYEs for same call or will trigger failure?
You can configure the SQL "UPDATE" query for the accounting STOP action in radius, so for example:
- The first matching BYE will fill a row field "completed" and set it to "1".
- At the same time the SQL query has a "WHERE completed = 0".
In this way, just the first BYE will trigger an UPDATE SQL query. Any other BYE will be discarded by MySQL server because doesn't honor the "WHERE" clausule and will no "re-update" the accounting row.
But, in this case, the last one should be the right one.
Cheers, Daniel
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
On 12/20/08 11:55, Iñaki Baz Castillo wrote:
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
I don't really get it ... would it select the first or last BYE for a call? Will it accept many BYEs for same call or will trigger failure?
You can configure the SQL "UPDATE" query for the accounting STOP action in radius, so for example:
- The first matching BYE will fill a row field "completed" and set it to
"1". - At the same time the SQL query has a "WHERE completed = 0".
In this way, just the first BYE will trigger an UPDATE SQL query. Any other BYE will be discarded by MySQL server because doesn't honor the "WHERE" clausule and will no "re-update" the accounting row.
But, in this case, the last one should be the right one.
Well, not sure of which case exactly you mean now. I think that the accounting proxy should ensure that a fraudulent BYE can't not be the first one in triggering the STOP action.
On 12/20/08 13:25, Iñaki Baz Castillo wrote:
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
On 12/20/08 11:55, Iñaki Baz Castillo wrote:
El Sábado, 20 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Yeah. With radius it should be easy, since the SQL query for SOP action will ensure that it wasn't a previous matching BYE.
I don't really get it ... would it select the first or last BYE for a call? Will it accept many BYEs for same call or will trigger failure?
You can configure the SQL "UPDATE" query for the accounting STOP action in radius, so for example:
- The first matching BYE will fill a row field "completed" and set it to
"1". - At the same time the SQL query has a "WHERE completed = 0".
In this way, just the first BYE will trigger an UPDATE SQL query. Any other BYE will be discarded by MySQL server because doesn't honor the "WHERE" clausule and will no "re-update" the accounting row.
But, in this case, the last one should be the right one.
Well, not sure of which case exactly you mean now. I think that the accounting proxy should ensure that a fraudulent BYE can't not be the first one in triggering the STOP action.
I see the proxy just as a reporting point, sending to accounting system all events within a session: - START (200ok for INVITE, confirmed - ACK) - UPDATEs (re-INVITE, other in-session requests) - STOP (good, bad BYEs)
Then it comes the billing application that implements the logic to deal with different cases. Easiest one is when you have one STOP event, but if you have more, then you have to check for reply code, cseq, etc...
The proxy is critical because of the real-time nature of the communication. Billing can sit and digest peacefully, report abnormally cases, etc. Many tend to load the proxy with functionalities that don't belong there, then start complaining is not doing the job right or fast enough ... in every system you have to get to a compromise, not only in VoIP.
Cheers, Daniel
El Domingo, 21 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Then it comes the billing application that implements the logic to deal with different cases. Easiest one is when you have one STOP event, but if you have more, then you have to check for reply code, cseq, etc...
Well, as I said I don't need dealing with it if I use radius ACC since only one BYE matching the dialog can trigger a SQL STOP action (other BYE's matching this dialog will trigger radius STOP action, but not SQL action due to "WHERE" clausules the SQL query).
So the only I need is the proxy ensures that the BYE is not fraudulent, for example, it's not a spoofed BYE from the user with RURI=same_user.
Anyway, it seems really complex and a post-accounting process should be needed as you say. I will try to avoid needing it doing the billing in a B2BUA.
Tahnks.
On 12/21/08 15:50, Iñaki Baz Castillo wrote:
El Domingo, 21 de Diciembre de 2008, Daniel-Constantin Mierla escribió:
Then it comes the billing application that implements the logic to deal with different cases. Easiest one is when you have one STOP event, but if you have more, then you have to check for reply code, cseq, etc...
Well, as I said I don't need dealing with it if I use radius ACC since only one BYE matching the dialog can trigger a SQL STOP action (other BYE's matching this dialog will trigger radius STOP action, but not SQL action due to "WHERE" clausules the SQL query).
So the only I need is the proxy ensures that the BYE is not fraudulent, for example, it's not a spoofed BYE from the user with RURI=same_user.
accounting only 200ok-ed BYEs will ensure that.
By the way, are you accounting all session updates, e.g., re-INVITE, or just first INVITE and the BYE. There are billing systems that use the re-INVITEs due to session timers to estimate the duration when BYE is missing.
Anyway, it seems really complex and a post-accounting process should be needed as you say. I will try to avoid needing it doing the billing in a B2BUA.
Don't you have a rating engine to compute the costs? Also, I assume you have a tool to aggregate the cdrs from your providers with what you get on proxy. Indeed, accounting/billing is quite complex, depending also on what type of charging you have (e.g., time of the day based charging).
Would be interesting to see what would be more efficient, a b2bua that may give better CDRs or a stand alone application that digest the accounting events. It is clear that a b2bua introduces delays, therefore reduces the processing capacity -- probably difference is not that big.
Cheers, Daniel
2008/12/22 Daniel-Constantin Mierla miconda@gmail.com:
Well, as I said I don't need dealing with it if I use radius ACC since only one BYE matching the dialog can trigger a SQL STOP action (other BYE's matching this dialog will trigger radius STOP action, but not SQL action due to "WHERE" clausules the SQL query).
So the only I need is the proxy ensures that the BYE is not fraudulent, for example, it's not a spoofed BYE from the user with RURI=same_user.
accounting only 200ok-ed BYEs will ensure that.
By the way, are you accounting all session updates, e.g., re-INVITE, or just first INVITE and the BYE. There are billing systems that use the re-INVITEs due to session timers to estimate the duration when BYE is missing.
Well, except in the case of BYE sent by the gateway (since the attacker could reply non-200 to the BYE and mantain the session open). But anyway, I imagine this exotica case:
- alice (attacker) speaking with the PSTN gateway.
- alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
The proxy could check the RURI to know that the destination in the gateway, so to account a BYE the gateway must reply 200 OK to the BYE. The first route is the proxy, so there is loose routing (as expected and required). But there is other Route pointing to alice again, so the BYE would be sent to alice who will reply 200 OK to this spoofed BYE. The proxy would trigger STOP action but the call session remains.
Anyway, it seems really complex and a post-accounting process should be needed as you say. I will try to avoid needing it doing the billing in a B2BUA.
Don't you have a rating engine to compute the costs? Also, I assume you have a tool to aggregate the cdrs from your providers with what you get on proxy. Indeed, accounting/billing is quite complex, depending also on what type of charging you have (e.g., time of the day based charging).
Well, now I'm designing it, not a real implementation now.
Would be interesting to see what would be more efficient, a b2bua that may give better CDRs or a stand alone application that digest the accounting events. It is clear that a b2bua introduces delays, therefore reduces the processing capacity -- probably difference is not that big.
I think (but not 100% sure) that a B2BUA could check all the requests in both legs to ensure that no spoofed accounting action is performed, so the accounting would be in realtime (without the need of an external application re-checking it). But this is just theory XD
Thanks a lot for your comments.
Iñaki Baz Castillo writes:
alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
in this particular case, you could call to_gw() and find out that request is going to gw and, if so, drop the request it is has more than one route header (the one for the proxy itself).
-- juha
2008/12/22 Juha Heinanen jh@tutpro.com:
Iñaki Baz Castillo writes:
alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
in this particular case, you could call to_gw() and find out that request is going to gw and, if so, drop the request it is has more than one route header (the one for the proxy itself).
Sure Juha, but don't you agree with me that finally there are too many exotic checks? Sincerely I can't expect that any user configuring a proxy for accounting purposes will take all this "features" in mind.
Iñaki Baz Castillo writes:
Sure Juha, but don't you agree with me that finally there are too many exotic checks?
i fully agree with that. that is why i have never even dreamed to do any monetary accounting of sip calls. what my proxy provides is for end user's "information only". trying to anything beyond that means re-inventing pstn and loosing the benefits of internet. the "solution" is called ims, and i don't want to be any part of it.
-- juha
2008/12/22 Juha Heinanen jh@tutpro.com:
Iñaki Baz Castillo writes:
Sure Juha, but don't you agree with me that finally there are too many exotic checks?
i fully agree with that. that is why i have never even dreamed to do any monetary accounting of sip calls. what my proxy provides is for end user's "information only". trying to anything beyond that means re-inventing pstn and loosing the benefits of internet. the "solution" is called ims, and i don't want to be any part of it.
100% agree :)
Juha Heinanen schrieb:
Iñaki Baz Castillo writes:
alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
in this particular case, you could call to_gw() and find out that request is going to gw and, if so, drop the request it is has more than one route header (the one for the proxy itself).
Not sure if this is enough - the attacker could omit the Route header pointing to the proxy. Maybe the check should use $dd which is set if another Route header is present.
regard klaus
2008/12/23 Klaus Darilion klaus.mailinglists@pernau.at:
Juha Heinanen schrieb:
Iñaki Baz Castillo writes:
- alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0
Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
in this particular case, you could call to_gw() and find out that request is going to gw and, if so, drop the request it is has more than one route header (the one for the proxy itself).
Not sure if this is enough - the attacker could omit the Route header pointing to the proxy. Maybe the check should use $dd which is set if another Route header is present.
Yes, I think so. Checking $dd would be the appropiate way to know if the request has other Route. So steps would be:
a) The proxy receives BYE from a gateway IP, so it must account the BYE in that moment (regardless of the BYE response).
b) The proxy receives BYE from a non gateway IP (so it could be an user). It must: - Check loose routing (as always). - Check if $dd is set. In that case drop the request since it shouldn't have more Route header and could be a spoofed BYE. - If $dd is not set, then check if the RURI host:port matches an IP:port of a gateway. If not, drop the request. - Forward the request to the gateway. - Upon receiving 200 OK from the gateway do the accounting (call end).
Do I miss somehting? Is it *completely* feasible? or is it vulnerable with a more exotic BYE?
Iñaki Baz Castillo writes:
Do I miss somehting?
transport between proxy and gw should be tcp if gw is not in private network with the proxy. otherwise ip based tests do not prove anything.
-- juha
Juha Heinanen schrieb:
Iñaki Baz Castillo writes:
Do I miss somehting?
transport between proxy and gw should be tcp if gw is not in private network with the proxy. otherwise ip based tests do not prove anything.
And if the GW is in the private network make sure to configure your router to block incoming IP packets with local source IP address (don't let spoofed packets into your network, Cisco reverse path filtering)
klaus
2008/12/23 Klaus Darilion klaus.mailinglists@pernau.at:
transport between proxy and gw should be tcp if gw is not in private network with the proxy. otherwise ip based tests do not prove anything.
And if the GW is in the private network make sure to configure your router to block incoming IP packets with local source IP address (don't let spoofed packets into your network, Cisco reverse path filtering)
good point!
there are way too many ways how routing logic can be confused to bypass admission control. poisoning user loc, having a DNS name or ENUM entry to point to a gateway (scripting fails to see it as PSTN target and may skip PSTN ACLs), etc. a good thing to do is to use onsend_route and check if someone is trying to use a gateway whilst a call is not being recognized as to a gateway.
-jiri
Klaus Darilion wrote:
Juha Heinanen schrieb:
Iñaki Baz Castillo writes:
alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
in this particular case, you could call to_gw() and find out that request is going to gw and, if so, drop the request it is has more than one route header (the one for the proxy itself).
Not sure if this is enough - the attacker could omit the Route header pointing to the proxy. Maybe the check should use $dd which is set if another Route header is present.
regard klaus
Users mailing list Users@lists.kamailio.org http://lists.kamailio.org/cgi-bin/mailman/listinfo/users
2009/1/7 Jiri Kuthan jiri@iptel.org:
there are way too many ways how routing logic can be confused to bypass admission control. poisoning user loc, having a DNS name or ENUM entry to point to a gateway (scripting fails to see it as PSTN target and may skip PSTN ACLs), etc. a good thing to do is to use onsend_route and check if someone is trying to use a gateway whilst a call is not being recognized as to a gateway.
True. I implemented it with OpenSer address blacklists (containing the gateways IP's). I just dissable this blacklist when a call goes to a PSTN (I decide it by examinating the RURI). In case a user is registered with a spoofed Contact like: Contact: sip:+12345678@FACKED_DOMAIN_POINTING_TO_GW then a call to this user will be rejected since the resolved destination IP would match the blacklist.
Regards.
On 01/07/2009 10:54 AM, Iñaki Baz Castillo wrote:
2009/1/7 Jiri Kuthan jiri@iptel.org:
there are way too many ways how routing logic can be confused to bypass admission control. poisoning user loc, having a DNS name or ENUM entry to point to a gateway (scripting fails to see it as PSTN target and may skip PSTN ACLs), etc. a good thing to do is to use onsend_route and check if someone is trying to use a gateway whilst a call is not being recognized as to a gateway.
True. I implemented it with OpenSer address blacklists (containing the gateways IP's). I just dissable this blacklist when a call goes to a PSTN (I decide it by examinating the RURI). In case a user is registered with a spoofed Contact like: Contact: sip:+12345678@FACKED_DOMAIN_POINTING_TO_GW then a call to this user will be rejected since the resolved destination IP would match the blacklist.
this is falling in the same race as reliability (how many 9es?!?!). Questions like how secure is the service and how accurate is the accounting are answered with same phrase: how much do you want to invest in?
Probably you will never think of all cases that can occur. Very important is to account everything goes on your platform and be able to recover when local accounting records does not match with what you get from your PSTN termination providers. Then you can correlate CDRs and bill properly the user.
Cheers, Daniel
El Lunes, 22 de Diciembre de 2008 14:33, Iñaki Baz Castillo escribió:
Well, except in the case of BYE sent by the gateway (since the attacker could reply non-200 to the BYE and mantain the session open). But anyway, I imagine this exotica case:
alice (attacker) speaking with the PSTN gateway.
alice sends this BYE:
BYE sip:PSTN_NUMBER@PSTN_GATEWAY SIP/2.0 Route: sip:PROXY_IP Route: sip:alice@ALICE_PHONE_IP
The proxy could check the RURI to know that the destination in the gateway, so to account a BYE the gateway must reply 200 OK to the BYE. The first route is the proxy, so there is loose routing (as expected and required). But there is other Route pointing to alice again, so the BYE would be sent to alice who will reply 200 OK to this spoofed BYE. The proxy would trigger STOP action but the call session remains.
In all the thread I wonder why you allow users to speak with your GW's ... in our systems users only may speak with our proxies, and our gateway only speak with our proxies. We know that this config overload the proxies, but powerfull machines are cheaper that aspirine truks ;-)
If you route all your traffic throught you proxies (SIP signaling, I mean) and you do your accounting based on your GW's information and not based on your proxies information, you will be safe.
Best regards -- Raúl Alexis Betancor Santana
2008/12/22 Raúl Alexis Betancor Santana rabs@dimension-virtual.com:
In all the thread I wonder why you allow users to speak with your GW's ... in our systems users only may speak with our proxies, and our gateway only speak with our proxies.
Hi Raul, when I say "alice speaks with gateway" I always mean "alice speaks with gateway *through* the proxy". :)
If you route all your traffic throught you proxies (SIP signaling, I mean) and you do your accounting based on your GW's information and not based on your proxies information, you will be safe.
Sure, the problem is that it requires be the owner of the gateways.
El Lunes, 22 de Diciembre de 2008 16:58, Iñaki Baz Castillo escribió:
2008/12/22 Raúl Alexis Betancor Santana rabs@dimension-virtual.com:
In all the thread I wonder why you allow users to speak with your GW's ... in our systems users only may speak with our proxies, and our gateway only speak with our proxies.
Hi Raul, when I say "alice speaks with gateway" I always mean "alice speaks with gateway *through* the proxy". :)
If you route all your traffic throught you proxies (SIP signaling, I mean) and you do your accounting based on your GW's information and not based on your proxies information, you will be safe.
Sure, the problem is that it requires be the owner of the gateways.
I know, you whant to have a "Man In The Middle" proxy, hidding to your customers what are the real "gateways", that you don't own. That's ok .. when I say "your own gateways", I mean ... "your own B2BUA's/PSTN Gateways" ..., it's obvious that I prefer to proxy also the RTP throught "our gateways", so we can have full control over RTP and no fraudulent use of our proxies are allowed (if we did not something wrong ...)
I don't like doing accounting on the proxy at all, I prefer to do it in the B2BUA/Gateways machines, realtime or quasi-realtime accounting, but not on the proxy.
El Lunes, 22 de Diciembre de 2008, Raúl Alexis Betancor Santana escribió:
I don't like doing accounting on the proxy at all, I prefer to do it in the B2BUA/Gateways machines, realtime or quasi-realtime accounting, but not on the proxy.
Sure. As I've trying to state in this thread, I consider accounting in a proxy very vulnerable.
my 2 cents:
1. nice attack ;-)
2. perform accounting only on a dialog statefull node
2.1 the gateway is the most accurate accounting source
2.2 if you need proxy based accounting use a media relay which you disable on BYE
regards klaus
Iñaki Baz Castillo wrote:
Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order
<-- 500 Req Out of Order
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
I think this is *VERY* dangerous and I hope I'm wrong.
Would help the dialog module here? does the dialog module check the CSeq of the BYE in some way and could it prevent Kamailio from generating the ACC STOP action? (I don't think so).
I've also asked in SIP-implementors and an idea could be generating the ACC STOP action when receiving the 200 OK for the BYE (and not when receiving the BYE itself). Of course this will be valid when the gateway is the recipient of the BYE (and we know the gateway is not an "attacker"), but this is not valid when the recipient of the BYE is an user since it could send no reply for the BYE.
The only solution I see is:
- Using the dialog module, Kamailio should check the CSeq value in the BYE.
- Kamailio should forward the BYE just in case the CSeq is higher
than the actual CSeq for this dialog direction. 2) Kamailio should generate the ACC STOP action just in case the CSeq is higher than the actual CSeq for this dialog direction.
Both 1) and 2) are needed since a gateway could accept a BYE with wrong CSeq. In this case the call is ended but the accounting STOP action doesn't exist (infinite call).
But I think this is too complex, isn't it?
Hello,
On 12/19/08 01:02, Klaus Darilion wrote:
my 2 cents:
nice attack ;-)
perform accounting only on a dialog statefull node
2.1 the gateway is the most accurate accounting source
2.2 if you need proxy based accounting use a media relay which you disable on BYE
I think that for some particular cases, a two-step accounting is a good solution. Like: - request fwd'ed - reply fwd'ed
I am thinking when one is willing to account MESSAGEs for example. Once forwarded, the service is delivered. If you restart the proxy, then 200OK won't match an active transaction.
The second step could be just a log message somewhere, when it happens a corner case like no active transaction, so additional tools can recover proper billing records (here special security checks have to be applied anyhow).
I agree with you, that best place for acc is the gateway. Some times the service involves more than audio calls, so more things need to be accounted, on the proxy.
Cheers, Daniel
regards klaus
Iñaki Baz Castillo wrote:
Hi, first of all I'm sorry for this cross-posting, but I think it could be interesting for any SIP proxy with accounting capabilities.
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order
<-- 500 Req Out of Order
The call hasn't finished, but Kamailio has ended the accounting for this call since it received a BYE. And this BYE will generate a correct ACC Stop action (since it matches From_tag, To_tag and Call-ID).
I think this is *VERY* dangerous and I hope I'm wrong.
Would help the dialog module here? does the dialog module check the CSeq of the BYE in some way and could it prevent Kamailio from generating the ACC STOP action? (I don't think so).
I've also asked in SIP-implementors and an idea could be generating the ACC STOP action when receiving the 200 OK for the BYE (and not when receiving the BYE itself). Of course this will be valid when the gateway is the recipient of the BYE (and we know the gateway is not an "attacker"), but this is not valid when the recipient of the BYE is an user since it could send no reply for the BYE.
The only solution I see is:
- Using the dialog module, Kamailio should check the CSeq value in the BYE.
- Kamailio should forward the BYE just in case the CSeq is higher
than the actual CSeq for this dialog direction. 2) Kamailio should generate the ACC STOP action just in case the CSeq is higher than the actual CSeq for this dialog direction.
Both 1) and 2) are needed since a gateway could accept a BYE with wrong CSeq. In this case the call is ended but the accounting STOP action doesn't exist (infinite call).
But I think this is too complex, isn't it?
Users mailing list Users@lists.kamailio.org http://lists.kamailio.org/cgi-bin/mailman/listinfo/users
El Jueves, 18 de Diciembre de 2008, Iñaki Baz Castillo escribió:
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order
<-- 500 Req Out of Order
There is a solution for this (not perfect):
- The proxy stops the accounting when receives a BYE from the gateway, regardless of the BYE reply from the client. This prevents from BYE negatively answered by clients. - The proxy stops the accounting when receives a BYE from the client and the 200 OK from the gateway. This prevents from the above case in which the client sends an out-of-date CSeq in the BYE.
But this is not enough, note the following case:
- The user is in a call with the gateway. - The user sends a BYE with "Route: proxy" and RURI pointing to *himself*. - The BYE arrives to the proxy which forwards it back to the user again. - The user (attacker in fact) replies a 200 OK but doesn't terminate the RTP session with the gateway. - The proxy receives the 200 OK (BYE) from a user, so terminates the accounting. - The gateway knows exactly *nothing* about it, the call continues (but from now it's free).
Annoying?
On 12/20/08 12:03, Iñaki Baz Castillo wrote:
El Jueves, 18 de Diciembre de 2008, Iñaki Baz Castillo escribió:
I'm thinking in the following flow in which the caller/attacker would get an unlimited call (but a limited CDR duration):
attacker Kamailio (Acc) gateway
INVITE (CSeq 12) ------> <-------- 407 Proxy Auth
INVITE (CSeq 13) ------> INVITE (CSeq 13) ------> <------------------- 200 Ok <------------------- 200 Ok << Acc START >> ACK (CSeq 13) -----------> ACK (CSeq 13) ----------->
<******************* RTP ************************>
# Fraudulent BYE !!! BYE (CSeq 10) -----------> << Acc STOP >> BYE (CSeq 10) -----------> <-- 500 Req Out of Order
<-- 500 Req Out of Order
There is a solution for this (not perfect):
- The proxy stops the accounting when receives a BYE from the gateway,
regardless of the BYE reply from the client. This prevents from BYE negatively answered by clients.
- The proxy stops the accounting when receives a BYE from the client and the
200 OK from the gateway. This prevents from the above case in which the client sends an out-of-date CSeq in the BYE.
But this is not enough, note the following case:
- The user is in a call with the gateway.
- The user sends a BYE with "Route: proxy" and RURI pointing to *himself*.
- The BYE arrives to the proxy which forwards it back to the user again.
- The user (attacker in fact) replies a 200 OK but doesn't terminate the RTP
session with the gateway.
- The proxy receives the 200 OK (BYE) from a user, so terminates the
accounting.
- The gateway knows exactly *nothing* about it, the call continues (but from
now it's free).
Annoying?
This is part of well know Route-based attacks. I did a demo for a German newspaper like 4-5 years ago with a modified KPhone.
Fortunately for you, kamailio gives you a lot of tools to enhance the security as you need. You can check the stack of Via headers, source ip, etc... against the destionation address.
Similar attacks can happen with poisoned DNS, where is hard to check the IP address.
I believe in this cases an important aspect is to be sure you can identify the attacker. It is hard to prevent all people can think of, but when detecting one case, being able to get the guilty is very important. Also, at that time, you can add the logic to prevent further exposure to same attack.
Cheers, Daniel
Daniel-Constantin Mierla writes:
I believe in this cases an important aspect is to be sure you can identify the attacker. It is hard to prevent all people can think of, but when detecting one case, being able to get the guilty is very important. Also, at that time, you can add the logic to prevent further exposure to same attack.
this sounds like the ever lasting story of fixing security holes in internet explorer. i don't think it is a vice path to take.
better to proxy all media if accounting cannot be done in the gateways. and then we have reinvented pstn ...
-- juha
On 12/20/08 17:19, Juha Heinanen wrote:
Daniel-Constantin Mierla writes:
I believe in this cases an important aspect is to be sure you can identify the attacker. It is hard to prevent all people can think of, but when detecting one case, being able to get the guilty is very important. Also, at that time, you can add the logic to prevent further exposure to same attack.
this sounds like the ever lasting story of fixing security holes in internet explorer.
:-)
i don't think it is a vice path to take.
better to proxy all media if accounting cannot be done in the gateways. and then we have reinvented pstn ...
you are right with media based session and calls to gateways, but sometime could be the case of accounting other types of sessions/sip messages. When the value is transmitted via signaling, that has to be stored somehow, b2bua is ultimate solution and the safest.
Cheers, Daniel
Daniel-Constantin Mierla writes:
When the value is transmitted via signaling, that has to be stored somehow, b2bua is ultimate solution and the safest.
i agree with that (which was also inaki's proposal). but even with b2bua, problem arises if b2bua crashes and becomes unavailable for a moment or after crash looses its state.
-- juha
On 12/21/08 10:09, Juha Heinanen wrote:
Daniel-Constantin Mierla writes:
When the value is transmitted via signaling, that has to be stored somehow, b2bua is ultimate solution and the safest.
i agree with that (which was also inaki's proposal). but even with b2bua, problem arises if b2bua crashes and becomes unavailable for a moment or after crash looses its state.
indeed. That's why I proposed multi-step accounting on proxy: - request in/out - reply in/out While may not solve all known/unknown cases, it offers extra information that can be used to recover damages.
Cheers, Daniel
Iñaki Baz Castillo writes:
- The gateway knows exactly *nothing* about it, the call continues (but from
now it's free).
Annoying?
it is only if you try to do accounting in the proxy. if you do accounting in the gateway, the call continues, but is not free.
lots of effort has gone to implement reliable accounting of sip calls in the proxy. i personally don't think that it is a good idea, because it greatly complicates proxy implementation and may force proxying of media even if it would not otherwise be needed.
-- juha
El Sábado, 20 de Diciembre de 2008, Juha Heinanen escribió:
Iñaki Baz Castillo writes:
- The gateway knows exactly *nothing* about it, the call continues (but
from now it's free).
Annoying?
it is only if you try to do accounting in the proxy. if you do accounting in the gateway, the call continues, but is not free.
lots of effort has gone to implement reliable accounting of sip calls in the proxy. i personally don't think that it is a good idea, because it greatly complicates proxy implementation and may force proxying of media even if it would not otherwise be needed.
What about doing the accounting in a B2BUA (just SIP signalling, no media)? At least a B2BUA is fully dialog stateful (it really knows about CSeq values and so).
Iñaki Baz Castillo writes:
What about doing the accounting in a B2BUA (just SIP signalling, no media)? At least a B2BUA is fully dialog stateful (it really knows about CSeq values and so).
that might work. using sems, for example, the b2bua could just be on the signalling path and let media flow directly.
-- juha