StarTrinity.com

Measuring quality

False Answer Supervision (FAS) Fraud Generation and Detection in VoIP networks

Generation

The StarTrinity Softswitch could be used to generate the FAS fraud only for test purposes - to develop your anti-FAS system, and to add extra billed seconds for generated/dialer/CC/telemarketing (unwanted) VoIP traffic. We block softswitch licenses in case of FAS applied to live VoIP retail traffic (when end users pay small amounts for the fraud). Note that the FAS could be detected by the same software. The purpose of publishing the scipt is to help the fraud managers to fight against such type of fraud. We intentionally publish information about all kinds of the fraud (types 1-5) to make you be able to fight against it.

If you're suspecting the FAS fraud on your routes, we recommend you to go through the FAS types and check your CDRs/recordings to identify the FAS. Contact the route provider, make a complaint. Add the provider to public lists of fraudsters, describing the details

FAS type 1: billing of incoming VoIP traffic, without call leg B

Scenario:
  • play a ringback tone one time, do not charge the client
  • connect the call, start charging
  • play a ringback tone for 20 seconds, do charge the client
  • connect the call to itself, play back received audio
CallXML code:
<accept value="183" />
<playaudio value="rbt.wav" maxtime="3s" />
<accept value="200" />
<playaudio value="rbt.wav" maxtime="20s" repeat="infinite" />
<loopbackaudio />
another srcipt: for 10% of calls set ring time = 8 seconds, for 90% of calls set ring time = 40 seconds, then connect call and play an audio file in repeat: (note that you should upload files "Ring.wav" and "IVR.wav")
<callxml type="custom">
 <accept value="183" />
 <block probability="0.1">
  <playaudio value="Ring.wav" maxtime="8s" />
  <accept value="200" />
  <playaudio value="IVR.wav" maxtime="12s" repeat="infinite" />
  <exit />
 </block>
<!-- rest of calls (90%) come here: play ring and disconnect -->
 <playaudio value="Ring.wav" maxtime="40s" repeat="infinite" />
 <reject value="487" />
</callxml>

FAS type 2: start of billing before actual answer of call leg B

Scenario:
  • transfer call (create call leg B)
  • (for 10% of calls) wait for 3 seconds
  • (for 10% of calls) start billing even if call leg B is not connected
CallXML code:
<accept value="183" />
<block probability="0.1">
 <settimeout value="3s" >
  <accept value="200" />
 </settimeout>
</block>

<transfer terminators="routed" />

FAS type 3: extra billing after call leg B disconnection

Scenario:
  • transfer call (create call leg B)
  • wait for call leg B disconnection
  • (for 10% of calls, only at night) don't disconnect call leg A add extra 3 seconds
<accept value="183" />
<transfer terminators="routed" simulateFasAfterConnection="true" />
<block probability="0.1">
 <assign var="doFAS" value="false" />
 <checktime var="doFAS">
  <span daystart="01:00" daystop="06:00" value="true" /> 
 </checktime>
 <if test="$doFAS;"> <wait value="3s"/> </if>
</block>
simpler script: always add extra billing of max. 10 seconds, without schedule: note: you can configure Open RTP mode in originator details - setting 'media proxy mode' if you want to pass RTP directly between originator and terminator
<accept value="183" />
<transfer terminators="routed" simulateFasAfterConnection="true" />
<wait value="10s"/>
<exit/>
another script: limit connected duration (by 30 seconds) and play an IVR file after disconnecting call leg B, while keeping call leg A connected:
<accept value="183" />
<transfer terminators="routed" maxansweredtime="30s" >
<on event="maxansweredtime">
 <playaudio value="music.wav" />
 <exit />
</on>
</transfer>
<wait value="30s"/>
another script: limit connected duration (by 30 seconds), disconnect call leg B, while keeping call leg A connected, transfer call leg A to call leg C (provider C at IP 12.34.56.78, tech. prefix 777):
<accept value="183" />
<transfer terminators="routed" maxansweredtime="30s" >
<on event="maxansweredtime">
 <transfer value="sip:777$calledId;@12.34.56.78" callerId="$callerId;" />
</on>
</transfer>
<wait value="30s"/>

FAS type 4: simulate voicemail

Scenario:
  • for 10% of calls start billing and play a voicemail message
  • for 90% of calls do normal transfer
<block probability="0.1">
 <accept />
 <playaudio value="voicemail.wav" />
 <wait value="100m" />
 <exit/>
</block>

<accept value="183" />
<transfer terminators="routed" />
</block>

FAS type 5: play ringback tone and random audio file

  • Play ringback tone in early media
  • Answer call, play random audio file from specified path
  • Different ASR for various originator trunks
<performaaa />
<switch value="$originatorId;">
 <case equals="O1">
  <!-- here is script for originator 1 -->
  <block probability="0.60">
   <reject value="503" />
   <exit />
  </block>
  <accept value="183" />
  <playaudio value="RBT_LAT.wav" maxtime="6s" />
  <accept value="200" />
  <playaudio value="$randfile(C:\Program Files (x86)\StarTrinity\StarTrinity SoftSwitch\Sound files\*.wav);" />
 </case>
 <case equals="O2">
  <block probability="0.6">
   <reject value="503" />
   <exit />
  </block>
  <accept value="183" />
  <playaudio value="RBT_LAT.wav" maxtime="6s" />
  <accept value="200" />
  <playaudio value="$randfile(C:\Program Files (x86)\StarTrinity\StarTrinity SoftSwitch\Pakistan\*.wav);" />
 </case>
 <case equals="O3">
  <block probability="0.50">
   <reject value="503" />
   <exit />
  </block>
  <accept value="183" />
  <playaudio value="RBT_LAT.wav" maxtime="6s" />
  <accept value="200" />
  <playaudio value="$randfile(C:\Program Files (x86)\StarTrinity\StarTrinity SoftSwitch\Sound files 5555\*.wav);" />
 </case>
 <case equals="O4">
  <block probability="0.65">
   <reject value="503" />
   <exit />
  </block>
  <accept value="183" />
  <playaudio value="RBT_LAT.wav" maxtime="6s" />
  <accept value="200" />
  <playaudio value="$randfile(C:\Program Files (x86)\StarTrinity\StarTrinity SoftSwitch\Senegal recordings\*.wav);" />
 </case>
</switch>

FAQ

How to add a new originator with different tech. prefix, but same client IP, to connect call and play IVR audio file?
  • Upload IVR audio file (WAV, mono, 8kHz, 16bit) in softswitch menu - configuration - audio files. In this example ivr.wav
  • Add a new originator in softswitch menu - configuration - originators. It is possible to add 2 originators with different ID's, same IP, but different tech. prefix.
  • In originator details Enter client IP address and tech. prefix; set script type = "simplest IVR", IVR file name = ivr.wav
  • It is ready for test call

Detection

Method #1

The 1st method is to use our softswitch, to use audio signal processing features. Every type of FAS implementation needs detailed analysis and special configuration

Method #2

The 2nd method needs interconnection with suspective carriers and telco's in destination countries. Special contracts are needed. We suggest you to have 2 or more instances of SIP Tester, one to generate calls and second to receive calls. The test calls are passed through a network of VoIP carriers (wholesalers) to ensure integrity of VoIP routes. If some fraud exists in the network, the SIP Testers detect mismatch of billed duration. Additionally you should process generated CDRs to detect blending or loss of SIP calls: match every generated and received call, one by one.
CallXML scripts for call generator(s):
<callxml>
<!-- IP addresses:
  2.2.2.2 - call receiver instance of SIP Tester for morocco (country#1)
  3.3.3.3 - call receiver instance of SIP Tester for zimbabwe (country#2)
  4.4.4.4 - outgoing carrier for morocco
  5.5.5.5 - outgoing carrier for zimbabwe
 -->

<!-- read destination numbers from CSV files -->
 <readcsv value="D:\StarTrinity\CSV\Morocco Cell June 29 Dialer Ready.csv" var0="calledId_1" var1="callerId_1" repeat="infinite" />
 <readcsv value="D:\StarTrinity\CSV\Zim Econet Nov 18 Dialer Ready 4x.csv" var0="calledId_2" var1="callerId_2" repeat="infinite" />

<!-- make call to one of 2 destination carriers (for 2 countries) -->
 <call maxtime="35000ms" value="$rand_from_options;" codec="G729">
  <option value="sip:$calledId_1;@4.4.4.4?callerId=$callerId_1;" maxCallsPerDestinationResource="300" destinationResourceId="server1" />
  <option value="sip:$calledId_2;@5.5.5.5?callerId=$callerId_2;" maxCallsPerDestinationResource="600" destinationResourceId="server2" />
 </call>
 <on event="answer">
  <!-- when call is connected: -->

  <assign var="duration" value="$rand(670000);" /> <!-- predefine billed duration for this call -->

  <!-- check if call is really answered by call receiver instance of SIP Tester, send locally predefined billed duration -->
  <switch value="$destinationResourceId;">
   <case equals="server1">
    <sendhttprequest value="http://2.2.2.2:19019/API/MainViewModel/SetCallXmlVariables?calledId=$calledId;&peerDuration=$duration;" user="admin" password="todo_password" contentvar="r" />
    <if test="$r; == false">
     <log value="rejecting call: does not exist on peer = 2.2.2.2 (to $calledId;)" />
     <exit />
    </if>
   </case>
   <case equals="server2">
    <sendhttprequest value="http://3.3.3.3:19019/API/MainViewModel/SetCallXmlVariables?calledId=$calledId;&peerDuration=$duration;" user="admin" password="todo_password" contentvar="r" />
    <if test="$r; == false">
     <log value="rejecting call: does not exist on peer = 3.3.3.3 (to $calledId;)" />
     <exit />
    </if>
   </case>
  </switch>

  <assign var="t1" value="$timeMs();" />
  <!-- every 2 seconds: check if call is not over-billed -->
  <setinterval value="2s">
   <if test="$peerDuration;">
    <assign var="localActualDelay" mathvalue="$timeMs(); - $t1; - 1000" />
    <if test="$localActualDelay; &gt; $peerDuration;">
     <log value="detected duration mismatch! (from $callerId; to $calledId;) actual: $localActualDelay;ms, must be $peerDuration;ms" />
     <exit />
    </if>
   </if>
  </setinterval>

  <!-- leave the call connected for the predefined duration. play a random WAV file -->
  <playaudio value="$randfile(D:\StarTrinity\Wav\*.wav);" repeat="infinite" maxtime="$duration;ms" />
  <exit />
 </on>
</callxml>

CallXML scripts for call receiver(s):
<callxml>
<!-- IP addresses:
  1.1.1.1 - call generator instance of SIP Tester
  6.6.6.6 and 7.7.7.7 - carriers which send calls to this SIP Tester
 -->


 <if test="$callerIpAddress; = 6.6.6.6 or $callerIpAddress; = 7.7.7.7"> <!-- firewall logic: accept only from needed carriers -->
  <assign var="duration" value="$rand(670000);" /> <!-- predefine billed duration of call -->

  <!-- send request to call generator to check if this call was really sent there. also send planned duration -->
  <sendhttprequest value="http://1.1.1.1:19019/API/MainViewModel/SetCallXmlVariables?callerId=&calledId=$calledId;&peerDuration=$duration;" user="admin" password="password_todo" contentvar="r" />
  <if test="$r; == false">
   <log value="rejecting call: does not exist on call generator=1.1.1.1 (to $calledId;)" />
   <reject value="503" />
   <exit />
  </if>

  <accept value="183" />
  <playaudio value="rbt.wav" repeat="infinite" maxtime="$rand(15000);ms" /> <!-- simulate ringback tone, play rbt.wav -->
  <block probability="0.55">
   <reject value="486" /> <!--reject call with probability of 55%-->
   <exit />
  </block>
  <accept /> <!-- connect the call -->
  <assign var="t1" value="$timeMs();" />
  <setinterval value="2s">
   <if test="$peerDuration;">
    <!-- every 2 seconds check if current call is not over-billed. if over-billed (a sign of FAS - report it) -->
    <assign var="localActualDelay" mathvalue="$timeMs(); - $t1; - 1000" />
    <if test="$localActualDelay; &gt; $peerDuration;">
     <log value="detected duration mismatch! (from $callerId; to $calledId;) actual: $localActualDelay;ms, must be $peerDuration;ms" />
     <exit />
    </if>
   </if>
  </setinterval>
  <playaudio value="speech.wav" repeat="infinite" maxtime="$duration;ms" /> <!-- leave the call connected for the predefined duration -->
 </if>
 <exit />
</callxml>
Hope this will help you to fight against VoIP fraud
Copyright 2011-2024 StarTrinity.com | Blog | Contact lead developer via LinkedIn |