Random IVR code

Tags: #<Tag:0x00007fafc544b890> #<Tag:0x00007fafc544b728>

(Mu) #21

the calls are coming from the outside … I did copy the dial plan from above and it works beautifully ( thank you again lgaetz ).
What I want now is to make the same kind of filter but with a simple Math question … what is … 2 plus 2 bla bla .

(Itzik) #22

Ouch down 5060

(Mu) #23

I need the calls to be coming from "outside " I don’t really understand what Port 5060 does and how shutting it down will help .

(Lorne Gaetz) #24
exten => s,n,Set(i=${RAND(0,7))
exten => s,n,Set(j=${RAND(0,7))
exten => s,n,set(goal=${MATH(${i}+${j},i)})

(Communication Technologies) #25

We are experiencing the same issue, but are taking a different, more reactive approach for what it is worth. When a call comes in:

  • Check it against a whitelist. On the list = Pass

  • Check it against a blacklist. On the list = Straight to a IVR challenge

  • Not on any list, pull the last Y seconds of the CDR

  • Has the prefix called us X times in the last Y seconds? If yes = IVR challenge

  • Has the DNID been called X times in the last Y seconds? If yes = IVR challenge

In this way we are hoping we can do a more elaborate challenge, while not inconveniencing every customer. Bonus is when the attack lets up, you can resume a normal operation automatically. Bad side is a few calls will always get though as the CDR has to build up to start flagging.

(Communication Technologies) #26

Have you looked at the logs to see if they are getting though the way you think (going to your challenge IVR and pressing the correct digit)? Maybe the approach is different and that how its getting though? If that were the case, you might be able to avoid the less friendly challenge. Food for thought.

(Lorne Gaetz) #27

I’ve been challenging all unknown inbound calls now for over a year. Very simple test, the caller only needs to key a single DTMF tone, doesn’t matter which one. I block probably 10-20 calls a week and have 2-3 cases total of an automated call bypassing this. I find it highly unlikely that automated calls are managing to bypass this random number captcha.

(Mu) #28

yes I have looked at the log files … and they are pressing exactly the right numbers. :frowning:

(Mu) #29

believe me… I am dealing with this problem for 2 Months now …
I started with one meniu IVR and at first it was oke … after about 10 minutes the phone startet wringing off the hook … added a second sub menu and it was oke for 10 minutes …
then i started actively managing the IVR and changing the meniu prompts and would get 10 min free maybe… but lately they would bypass my IVR changes as soon as I implement them … CRAZY … I can only assume voice recognition used …
last I tried your awesome random challenge and same story … first 10 min oke after that calls started coming … so I now at 5 random digits … and it#s better but not full proof . anyway i desperatly need some help with this and I thank the Freepbx community for everything ! really thank you guys !!


Ask them to dial the fourth from the end of their CallerID(number)

(Mu) #31

how would I do that ?


exten => Set(goal=${CallerID(number):-4:1})

(Mu) #33

Very interesting option … thank you very much .:+1:


Human engineering and AI together suggests that if Voice Recognition IS going on , don’t say words like “dial” or “enter” or “press”.

Here you could say “what is the last but three (‘preantepenultimate’’ :slight_smile: ) character in your number”

(Lorne Gaetz) #35

Make it too hard and only robots will get thru.


OK let’s use the robots.

Get a google speech-to-text account which is free for 240 lookups per month, then $0.004 per .
Install gcloud locally and ‘init’ it.
Install ‘jq’ to parse the results (the come in json)
Ask the caller to say their phone number and record it as number.wav (should be 16bit 8k)
This STT shell script takes less than 3 seconds to return.

gcloud ml speech recognize number.wav --language-code='en-US' |jq -r '.results[] | .alternatives[]| .transcript'

expect a response much like

One 323-555-1212
Areacode 323-555-1212

Then just a couple of lines of dialplan to FILTER and then match the last 10 digits of response to the last 10 digits of CallerID(number) , their robots will have to learn to speak to get through now.

So far just a WIP but all the bits work . .

(Mu) #37

I wish I was the guy who could implement all that just by your description but I’m afraid I lack the technical skill , however I do understand the logic of it and it’s very cool !


Though this thread was originally about filtering telemarketing spam/scam calls, you are dealing with a TDoS attack, which is very different. Please tell us a little about the attacker’s calls:

In what country is the number(s) being attacked?
What caller IDs are being sent? Are they spoofed?
For US and Canada, look up some of the caller IDs at https://apeiron.io/lrn . If you see e.g. mobile numbers, they are clearly spoofed. For other countries, you may find useful info at https://freecarrierlookup.com/ .

When the robot gets through to you, what do you hear? If you have a recording, please post a link.

It may be useful to have a whitelist of existing customers and vendors, which bypasses the IVR (or any other obstacles you might create). Import the last year or two of your CDRs into Excel, keep only calls that lasted for more than one minute, remove duplicates and use that for your initial whitelist.

Are you selling to consumers or to businesses? Possibly, an arrangement to call them back would work.

Or, maybe you could ask “who’s calling, please?” Your system wouldn’t actually recognize the speech, but if the robot always says the same thing, if the waveform matches you would drop the call.

Unless someone is targeting you specifically, it’s almost certain that they are using a commercial software package and they won’t bother tailoring it for your defenses; just find one vulnerability and you should be free.


Quick kinda working context

exten => s,1,Noop(This context uses Google STT to return a 10 digit NANP number, and dispatch s appropriate)
same => n,PlayBack(beep); replace with a file containing  what you want to say en/custom/yourwords
same => n,Record(/tmp/number.wav,1,10)
same => n,System(stt.sh "/tmp/number.wav")

; /usr/local/bin/stt.sh has "gcloud ml speech recognize $1 --language-code='en-US' |jq -r '.results[] | .alternatives[]| .transcript'>/tmp/number.txt" ;in it
; the asterisk user needs to be able to execute gcloud as the asterisk user.

same => n,Set(rawnumber=${SHELL(cat /tmp/number.txt)})
same => n,Set(number=${FILTER(0-9,${rawnumber}):-10})
same => n,GotoIf($["${number}" != "${CALLERID(num):-10}"]?gotcha)
same => n,Noop(Do whatever here, hopefully the bad guys got got, the next line just makes it a regular call )
same => n,goto(from-pstn,${EXTEN},1)
same => gotcha,Hangup()

It probably needs more than a little debugging :wink:

(So, its well after 4:30 here so how about “what’s the current time in the timezone of your area code?”)


So, Google cloud has a problem with O’s and 0’s as spoken, So adding a possible two factor improvement on @lgaetz original concept.

First they have to say a number between 11 and 99 (google gloud translate single digits as words), Then they have to dial the same number,

( google is pretty good with numbers up to a million but KISS)

exten => s,1,noop(Entering a context to provide 2FA of callers using Google Cloud Speech to text recognition)
same => n,Set(loop=0)
same => n,Set(prefix=${EPOCH})
same => n(loop),Playback(custom/screening)
same => n,Record(/tmp/${prefix}number.wav,2,3)
same => n,Set(voice=${SHELL(gcloud ml speech recognize /tmp/${prefix}number.wav --language-code='en-US'|sed -n -e  '/transcript/p'|sed  -e 's/[^0-9]*//g' -e 's/.*\([0-9]\{2\}$\)/\1/'|tr -d '\n')})
same => n,GotoIf($[ ${LEN(${voice})}  < 2 ]?invalid)
same => n,Read(keypad,custom/verify,2,,,2)
same => n,GotoIf($["${voice}" = "${keypad}"]?from-pstn,${FROM_DID},1)
same => n(invalid),PlayBack(custom/wronganswer)
same => n(break),Set(loop=$[${loop}+1])
same => n,GotoIf($["${loop}"="3"]?finish:loop)
same => n(finish),Playback(sorry-youre-having-problems)
same => n,Hangup()

You will need to setup a goggle cloud account, set up a Speech to text profile, install gcloud SDK on your system and then

su asterisk
gloud init

so the asterisk user can “do it”