VoIP fraud analysis
Currently, VoIP systems are very often used in business, they replace the standard telephony systems because they are cheaper, expandable and more flexible.
Following the growth of VoIP marker, the fraud market is also growing.
The main scenarios for fraud are the generation of a large number of calls to expensive destinations. The destination operator pays back part of the revenue to a hacker.
These operators exist in many countries of the world.
A separate direction is a case when an operator organizes a joint with large VoIP terminators directly, so most of the cost is sent to it and there are no restrictions on the channels.
Methodology
For research, i create honeypot what mimics vulnerable PBX.
For emulation, i use Kamailio nodes what send any calls to termination node and answers to OPTIONS and REGISTER.
For every INVITE I record from, to, UA, callId, IP and call time.
Termination node has Kamailio with Flask app for preprocessing calls and Asterisk for topology hiding when calls sent to PSTN.
All calls with a cost of more than 2 cents per minute were rejected with code 486.
Sensor node
All data has been written to Redis using this code:
$var(json) = '{"from": "' + $fU + '", "to": "' + $rU + '", "ip": "' + $si + '", "ua": "' + $ua +'", "ci": "' + $ci + '", "ts": "' + $TV(s) +'"}';
redis_cmd("srvN", "LPUSH %s %s", "INVITE2", "$var(json)", "r");
redis_free("r");After that call forwards to termination node for processing.
Termination node
All calls cleaned with this simple function.
def number_clean(number):
match_pat = re.compile(r'\d*00([^0]\d{9}\d+)', flags=re.IGNORECASE)
number = str(number)
results = match_pat.match(number)
if results == None:
return number[-12:]
return results.group(1)[-12:]After that if call costs less than $0.02 per minute it forwards to Asterisk.
[honeypot]
exten => _XXXX.,1,Verbose(Got call to ${EXTEN})
exten => _XXXX.,n,Set(TIMEOUT(ABSOLUTE)=10)
exten => _XXXX.,n, Set(GROUP()=OUTBOUND_GROUP)
exten => _XXXX.,n, GotoIf($[${GROUP_COUNT()} > 1]?hangup)
exten => _XXXX.,n,Dial(SIP/outbount_trunk/${EXTEN})
exten => _XXXX.,n(hangup),Hangup()Results
I use 4 sensor nodes located in NL, DE, SG и NYC.
For 18 days, 254805 INVITE were collected from 296 different IP’s. On average, 860 INVITE was received from IP.
Request sources
48% INVITE comes from single IP — 155.94.64.75.
Top 10 sources:

Most sources comes from hosting providers or from Palestine.

Used UA

Test numbers
For every IP i get first number. It turned out 209 numbers. Some of them were used more than once from different IP.

Countries distribution looks like:

Some calls 8.6% (22005) is used for scan local extensions (1–99999).
Conclusion
If you block known UA (sipcli and friendly-scanner), you can filter out about 45% of attempts.
It can be achieved using this simple code:
if($ua =~ "(friendly-scanner|sipvicious|sipcli|VaxSIPUserAgent|voxalot)") {
exit;
}And you can block all calls to nonstandart destinations like Palestine.
