[Freeswitch-users] Outbound call limit bypass prevention

Dmitry Sytchev kbdfck at gmail.com
Mon Mar 3 12:09:02 MSK 2014


Hi all!

<intro>
If you use FS or other softswitch with to provide services with limited
amounts of concurrent calls and have enabled REFER method for your SIP
users (you may disable it by *disable-transfer* in profiles, default
false), your setup may be vulnerable to call limit bypass attack.

For example, someone stoles credentials or bruteforces account password of
your SIP user and sends an amount of calls to premium numbers or
longdistance directions. These attempts should be at least limited with
customer call limit, but there is a method to bypass it.

When attacker sees the call limit is set on account, and call limit > 1, he
tries to bypass it to increase speed and amount of outbound calls. He makes
one outbound call, then makes second. At this moment there is four channels
- two inbound channels to FS, and two outbound channels from FS to PSTN or
SIP gw. FS sets call limit usage to 2.
Now attacker issuing transfer request by sending REFER to bridge two
outbound channels with each other. After successful transfer, two inbound
channels are destroyed and outbound channels are bridged together. After
that, FS decreases call limit, since it destroyed channels limit was set on.
</intro>

The problem is the method people often use to limit concurrent calls.
Something like that:

<action application="limit" data="hash OutboundLimit
${pbx_subscriber_customer_id} ${pbx_customer_call_limit} !CALL_REJECTED"/>
 <action application="bridge"
data="{ignore_early_media=false,hangup_after_bridge=false}sofia/gateway/gw/$1"/>

Now limit is set on inbound channel. When attacker bridges outbound
channels, their A-legs (inbound channels) get destroyed and FS decreases
limit due to channel destruction. So attacker have 2 outbound bridged
channels, and limit is still 0. Then the process repeats, allowing attacker
effectively bypass your call limits.

One of possible solutions is to move limits on B-legs after answer, while
keeping limits on A-legs too in order prevent exceeding limit by unanswered
calls:

We set limit on A-LEG, then on answer we decrease limit on A-LEG and "move"
it to B-leg by calling limit on outbound channel.

<action application="export" data="nolocal:execute_on_answer_1=set
api_result=${uuid_limit_release(${uuid} hash OutboundLimit
${pbx_subscriber_customer_id})}"/>
<action application="export" data="nolocal:execute_on_answer_2=limit hash
OutboundLimit ${pbx_subscriber_customer_id} ${pbx_customer_call_limit}
!CALL_REJECTED"/>
<action application="limit" data="hash OutboundLimit
${pbx_subscriber_customer_id} ${pbx_customer_call_limit} !CALL_REJECTED"/>
<action application="bridge"
data="{ignore_early_media=false,hangup_after_bridge=false}sofia/gateway/gw/$1"/>

Now limit is correctly evaluated for non-answered outbound calls, and
doesn't allow excessive calls.

Hope this helps somebody. Maybe you guys know more effective and correct
ways to prevent limit bypassing in this scenario?





-- 
Best regards,

Dmitry Sytchev,
IT Engineer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freeswitch.org/pipermail/freeswitch-users/attachments/20140303/de9d9b19/attachment.html 


Join us at ClueCon 2013 Aug 6-8, 2013
More information about the FreeSWITCH-users mailing list