Victim caller script

Questions about programming languages and debugging
Post Reply
User avatar
ayu
Staff
Staff
Posts: 8094
Joined: 27 Aug 2005, 16:00
16
Contact:

Victim caller script

Post by ayu »

Been hunting a lot of phone scammers recently.
Every time I find a new group of scammers I also always find a long list of numbers for their victims, usually older people they've managed to have success in scamming. Hard to deal with so many numbers so I've made a script that will call them.

Not finished yet but works pretty well so far.

Code: Select all

import os
import time

from dotenv import load_dotenv

from flask import Flask
from twilio.rest import Client
from threading import Thread

from callbacks import handle_callbacks

from conn import create_table
from conn import get_next_call
from conn import update_in_call

from common import printGood
from common import printBad
from common import printNeutral

victimTableSql = '''CREATE TABLE IF NOT EXISTS victims (
    id integer PRIMARY KEY AUTOINCREMENT,
    phone text,
    attempts integer NOT NULL,
    stop_calling integer NOT NULL,
    in_call integer NOT NULL,
    created_date text NOT NULL,
    last_call text NOT NULL,
    dial_code integer NOT NULL
);'''

current_code = 1

def main():
    t1 = Thread(target=handle_calls)
    t2 = Thread(target=handle_callbacks)

    t1.start()
    t2.start()

    t1.join()
    t2.join()

def handle_calls():
    load_dotenv()

    account_sid = os.getenv('TWILIO_SID')
    auth_token = os.getenv('TWILIO_TOKEN')
    client = Client(account_sid, auth_token)

    create_table(victimTableSql)

    while True:
        next_call = get_next_call(current_code)

        if next_call and next_call[4] != 1:
            call_to = next_call[1]
            in_call = next_call[4]
            dial_code = next_call[7]

            if dial_code == current_code:
                if dial_code == 1:
                    call_from = os.getenv('TWILIO_US_NUM')
                elif dial_code == 61:
                    # Need to buy an AU number!
                    call_from = os.getenv('TWILIO_US_NUM')
                else:
                    printBad("No number for this country, skipping")
                    continue

                printGood("Calling: " + next_call[1])
                update_in_call(next_call[1], 1)
                call = client.calls.create(
                                url=os.getenv('TWILIO_NGROK') + '/important?language=en-US',
                                to=next_call[1],
                                from_=call_from,
                                status_callback=os.getenv('TWILIO_NGROK') + '/status',
                                status_callback_method= 'POST',
                                record=True,
                                recording_channels='dual',
                                recording_status_callback=os.getenv('TWILIO_NGROK') + '/recordingStatus'
                            )

                printGood("Call SID: " + call.sid)
                time.sleep(60)
            else:
                printBad("Not current dial code, skipping")

if __name__ == "__main__":
    main()

Code: Select all

from flask import Flask, request
from twilio.twiml.voice_response import VoiceResponse, Gather

from conn import update_stop_calling
from conn import update_attempts

from common import printGood
from common import printBad
from common import printNeutral

calledDict = {}
app = Flask(__name__)

@app.route("/answer", methods=['GET', 'POST'])
def answer_call():
    resp = VoiceResponse()
    resp.say("", voice='alice', language='de-DE')

    return str(resp)

@app.route("/important", methods=['GET', 'POST'])
def important_call():
    resp = VoiceResponse()
    language = request.values['language']

    gather = Gather(num_digits=1, action='/stop_calling?language=' + language)

    if language == 'de-DE':
        message = ''
    else:
        message = 'Please listen carefully. We are calling from an anti scammer association. You are receiving this call because we suspect you have been targeted by scammers recently. If someone has called you regarding a charge or suspicious activity on your credit card or account, it is most likely a scam. Please do not give out any information concerning your credit or debit card over the phone. If anyone calls you and wants you to buy gift cards for them, hang up. If someone tries to convince you to give them access to your computer remotely, hang up. If you are uncertain what to do in these situations, please call your local authorities for assistance. If you understand this message, press 1 and we will not call you again.'

    gather.say(message, voice='alice', language=language)
    resp.append(gather)

    try:
        calledDict[request.values['Called']] += 1
        printGood("Message number " + str(calledDict[request.values['Called']]) + " for " + request.values['Called'])
    except:
        calledDict[request.values['Called']] = 0
        printGood("Message number 0 for " + request.values['Called'])

    if calledDict[request.values['Called']] < 2:
        resp.redirect('/important?language=' + language)

    return str(resp)

@app.route("/stop_calling", methods=['GET', 'POST'])
def stop_calling():
    resp = VoiceResponse()
    language = request.values['language']

    if language == 'de-DE':
        message = ''
    else:
        message = 'Thank you. We will not call you again.'

    if 'Digits' in request.values:
        choice = request.values['Digits']

        if choice == '1':
            printGood(request.values['Called'] + " pressed 1, removing from list")
            resp.say(message, voice='alice', language=language)

            update_stop_calling(request.values['Called'])
            return str(resp)

    return str(resp)

@app.route("/status", methods=['GET', 'POST'])
def status():

    printGood("Call status called, updating record")
    #print(request.values)
    update_attempts(request.values['Called'])
    if request and request.values['CallStatus'] == 'completed':
        pass

    return "ok"

@app.route("/recordingStatus", methods=['GET', 'POST'])
def recording_status():

    #printGood("Recording status called")
    #print(request.values)

    return "ok"

def handle_callbacks():
    app.run(debug=False)
"The best place to hide a tree, is in a forest"

User avatar
maboroshi
Dr. Mab
Dr. Mab
Posts: 1621
Joined: 28 Aug 2005, 16:00
16

Re: Victim caller script

Post by maboroshi »

Nice programming Ayu! :-)

There are to many elderly being scammed through online and phone services. I hope you have an effect in fishing out these criminals.

*cheers mabo

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11616
Joined: 06 Apr 2005, 16:00
16
Location: The zone.
Contact:

Re: Victim caller script

Post by bad_brain »

how is the actual call made? I'm a little confused because I can't seem to find any carrier connection or something... :-k

and yeah, as mab said,,,, :D =D>
my mum also got weird international calls from a "survey institute" repeatedly (mab might remember), I ended up having incoming international calls being blocked by the provider (seriously, I have their best and most pricey internet package but you can't even block single numbers on router level :roll: ).
Image

User avatar
maboroshi
Dr. Mab
Dr. Mab
Posts: 1621
Joined: 28 Aug 2005, 16:00
16

Re: Victim caller script

Post by maboroshi »

Hey bad_brain, the call code is likely to do with the twilio api in ayu's script.

https://www.twilio.com/

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11616
Joined: 06 Apr 2005, 16:00
16
Location: The zone.
Contact:

Re: Victim caller script

Post by bad_brain »

maboroshi wrote:
23 Dec 2021, 14:12
Hey bad_brain, the call code is likely to do with the twilio api in ayu's script.

https://www.twilio.com/
thanks buddy! bookmarked it, they have some interesting services and prices... :-k
Image

User avatar
ayu
Staff
Staff
Posts: 8094
Joined: 27 Aug 2005, 16:00
16
Contact:

Re: Victim caller script

Post by ayu »

Yup it's using Twilio! :D

Been experimenting a lot with their API recently.
Finished some work yesterday that automatically steals victim phone lists from the scammers.
Over 9000 (always wanted to say that) numbers in the database currently, and counting.

Gonna take a while for the script to call all of those though.
"The best place to hide a tree, is in a forest"

Post Reply