├── scripts ├── __init__.py ├── monitor.py ├── call.py ├── HLR.py ├── user_interact.py ├── ussd.py └── sms_smpp.py ├── doc └── img │ ├── help.png │ └── RougeBTS.png ├── configs ├── osmo-sip-connector.cfg ├── extensions.conf ├── sip.conf ├── osmo-trx.cfg ├── osmo-bts.cfg ├── osmo-ggsn.cfg ├── osmo-pcu.cfg ├── osmo-sgsn.cfg ├── openbsc.cfg └── openbsc_egprs.cfg ├── services ├── osmo-sip-connector.service ├── osmo-trx-lms.service ├── osmo-nitb.service ├── osmo-ggsn.service ├── osmo-nitb_sip.service ├── osmo-sgsn.service ├── osmo-bts-trx.service └── osmo-pcu.service ├── install_services.sh ├── config.json ├── interact.py ├── auxiliary ├── ussd_broadcast.py ├── sms_spam.py └── sms_broadcast.py ├── README.md └── main.py /scripts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/img/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godfuzz3r/osmo-nitb-scripts/HEAD/doc/img/help.png -------------------------------------------------------------------------------- /doc/img/RougeBTS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godfuzz3r/osmo-nitb-scripts/HEAD/doc/img/RougeBTS.png -------------------------------------------------------------------------------- /configs/osmo-sip-connector.cfg: -------------------------------------------------------------------------------- 1 | app 2 | mncc 3 | socket-path /tmp/msc_mncc 4 | sip 5 | local 127.0.0.1 5069 6 | remote 127.0.0.1 5060 7 | 8 | -------------------------------------------------------------------------------- /configs/extensions.conf: -------------------------------------------------------------------------------- 1 | [gsmsubscriber] 2 | exten=>_XXX,1,Dial(SIP/GSM/${EXTEN}) 3 | exten=>_XXX,n,Playback(vm-nobodyavail) 4 | exten=>_XXX,n,HangUp 5 | -------------------------------------------------------------------------------- /configs/sip.conf: -------------------------------------------------------------------------------- 1 | [GSM] 2 | type=friend 3 | host=127.0.0.1 4 | dtmfmode=rfc2833 5 | canreinvite=no 6 | disallow=all 7 | allow=gsm 8 | context=gsmsubscriber 9 | port=5069 10 | -------------------------------------------------------------------------------- /services/osmo-sip-connector.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Osmo SIP Connector 3 | 4 | [Service] 5 | Type=simple 6 | Restart=always 7 | ExecStart=/usr/bin/osmo-sip-connector -c /etc/osmocom/osmo-sip-connector.cfg 8 | RestartSec=2 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /services/osmo-trx-lms.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Osmocom SDR BTS L1 Transceiver (LimeSuite backend) 3 | 4 | [Service] 5 | Type=simple 6 | Restart=always 7 | ExecStart=/usr/bin/osmo-trx-lms -C /etc/osmocom/osmo-trx-lms.cfg 8 | RestartSec=2 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /services/osmo-nitb.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=OpenBSC Network In the Box (NITB) 3 | 4 | [Service] 5 | Type=simple 6 | Restart=always 7 | ExecStart=/usr/bin/osmo-nitb -s -C -c /etc/osmocom/osmo-nitb.cfg -l /var/lib/osmocom/hlr.sqlite3 8 | RestartSec=2 9 | 10 | [Install] 11 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /services/osmo-ggsn.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=OsmoGGSN 3 | After=networking.service 4 | 5 | [Service] 6 | Type=simple 7 | Restart=always 8 | ExecStart=/usr/bin/osmo-ggsn -c /etc/osmocom/osmo-ggsn.cfg 9 | RestartSec=2 10 | RestartPreventExitStatus=1 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /services/osmo-nitb_sip.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=OpenBSC Network In the Box (NITB) 3 | 4 | [Service] 5 | Type=simple 6 | Restart=always 7 | ExecStart=/usr/bin/osmo-nitb -s -C -c /etc/osmocom/osmo-nitb.cfg -l /var/lib/osmocom/hlr.sqlite3 -M /tmp/msc_mncc 8 | RestartSec=2 9 | 10 | [Install] 11 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /services/osmo-sgsn.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Osmocom SGSN (Serving GPRS Support Node) 3 | Wants=osmo-hlr.service 4 | After=osmo-hlr.service 5 | After=osmo-hnbgw.service 6 | 7 | [Service] 8 | Type=simple 9 | Restart=always 10 | ExecStart=/usr/bin/osmo-sgsn -c /etc/osmocom/osmo-sgsn.cfg 11 | RestartSec=2 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /services/osmo-bts-trx.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Osmocom osmo-bts for osmo-trx 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts-trx.cfg 7 | Restart=always 8 | RestartSec=2 9 | 10 | # Let it process messages quickly enough 11 | CPUSchedulingPolicy=rr 12 | CPUSchedulingPriority=1 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /services/osmo-pcu.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Osmocom osmo-pcu 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/bin/osmo-pcu -c /etc/osmocom/osmo-pcu.cfg 7 | Restart=always 8 | RestartSec=2 9 | RestartPreventExitStatus=1 10 | 11 | # The msg queues must be read fast enough 12 | CPUSchedulingPolicy=rr 13 | CPUSchedulingPriority=1 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /configs/osmo-trx.cfg: -------------------------------------------------------------------------------- 1 | log stderr 2 | logging filter all 1 3 | logging color 1 4 | logging print category 1 5 | logging timestamp 1 6 | logging print file basename 7 | logging level set-all info 8 | ! 9 | line vty 10 | no login 11 | ! 12 | trx 13 | bind-ip 127.0.0.1 14 | remote-ip 127.0.0.1 15 | base-port 5700 16 | egprs disable 17 | tx-sps 4 18 | rx-sps 4 19 | rt-prio 18 20 | chan 0 21 | tx-path BAND1 22 | rx-path LNAW 23 | 24 | -------------------------------------------------------------------------------- /install_services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cp services/osmo-nitb.service /lib/systemd/system 3 | cp services/osmo-bts-trx.service /lib/systemd/system 4 | cp services/osmo-trx-lms.service /lib/systemd/system 5 | cp services/osmo-pcu.service /lib/systemd/system 6 | cp services/osmo-sgsn.service /lib/systemd/system 7 | cp services/osmo-ggsn.service /lib/systemd/system 8 | cp services/osmo-sip-connector.service /lib/systemd/system 9 | 10 | systemctl daemon-reload -------------------------------------------------------------------------------- /configs/osmo-bts.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! OsmoBTS configuration example 3 | !! 4 | ! 5 | ! 6 | line vty 7 | no login 8 | ! 9 | phy 0 10 | instance 0 11 | osmotrx rx-gain 30 12 | osmotrx tx-attenuation 30 13 | osmotrx ip local 127.0.0.1 14 | osmotrx ip remote 127.0.0.1 15 | no osmotrx timing-advance-loop 16 | bts 0 17 | oml remote-ip 127.0.0.1 18 | ipa unit-id 1801 0 19 | gsmtap-sapi pdtch 20 | gsmtap-sapi ccch 21 | band 900 22 | trx 0 23 | phy 0 instance 0 24 | -------------------------------------------------------------------------------- /configs/osmo-ggsn.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! OpenGGSN (0.94.1-adac) configuration saved from vty 3 | !! 4 | ! 5 | ! 6 | stats interval 5 7 | ! 8 | line vty 9 | no login 10 | ! 11 | ggsn ggsn0 12 | gtp state-dir /tmp 13 | gtp bind-ip 127.0.0.6 14 | apn internet 15 | gtpu-mode tun 16 | tun-device tun4 17 | type-support v4 18 | ip prefix dynamic 176.16.1.1/24 19 | ip dns 0 192.168.0.105 20 | ip dns 1 8.8.8.8 21 | ip ifconfig 176.16.1.1/24 22 | no shutdown 23 | default-apn internet 24 | no shutdown ggsn 25 | 26 | 27 | -------------------------------------------------------------------------------- /configs/osmo-pcu.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! Osmo-PCU (0.4.0.83-5b22) configuration saved from vty 3 | !! 4 | ! 5 | ! 6 | stats interval 5 7 | ! 8 | line vty 9 | no login 10 | ! 11 | pcu 12 | flow-control-interval 10 13 | cs 2 14 | cs max 4 15 | cs threshold 10 33 16 | cs downgrade-threshold 200 17 | cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12 18 | mcs link-quality-ranges mcs1 6 mcs2 5 8 mcs3 7 13 mcs4 12 15 mcs5 14 17 mcs6 16 18 mcs7 17 20 mcs8 19 24 mcs9 23 19 | mcs max 9 20 | window-size 64 0 21 | queue idle-ack-delay 10 22 | queue codel 23 | alloc-algorithm dynamic 24 | alpha 0 25 | gamma 0 26 | dl-tbf-idle-time 2000 27 | -------------------------------------------------------------------------------- /configs/osmo-sgsn.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! Osmocom SGSN configuration 3 | ! 4 | ! 5 | line vty 6 | no login 7 | ! 8 | sgsn 9 | gtp local-ip 127.0.0.1 10 | ggsn 0 remote-ip 127.0.0.6 11 | ggsn 0 gtp-version 1 12 | ! auth-policy closed 13 | ! accept-all, closed, acl-only, remote 14 | auth-policy accept-all 15 | ns 16 | timer tns-block 3 17 | timer tns-block-retries 3 18 | timer tns-reset 3 19 | timer tns-reset-retries 3 20 | timer tns-test 30 21 | timer tns-alive 3 22 | timer tns-alive-retries 10 23 | encapsulation udp local-ip 127.0.0.1 24 | encapsulation udp local-port 23000 25 | encapsulation framerelay-gre enabled 0 26 | ! 27 | bssgp 28 | ! 29 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts":{ 3 | "sms":{ 4 | "enabled": true, 5 | "sender_extension": "John Connor", 6 | "message":[ 7 | "If you are reading this, then you are resistance" 8 | ] 9 | }, 10 | "ussd":{ 11 | "enabled": false, 12 | "ussd_type": 1, 13 | "message":[ 14 | "Welcome to our l33t hax0r network.", 15 | "If you are reading this, then you are true L33T 1337 H4xXx0r" 16 | ] 17 | }, 18 | "call":{ 19 | "enabled": false, 20 | "caller_extension": 666, 21 | "voice-file": "tt-monkeys" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scripts/monitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | def update_monitor(users): 5 | data = "ID\t\tcreated\t\tIMSI\t\t\tTMSI\t\tnumber\n\n" 6 | data += "-" * 80 7 | data += "\n\n" 8 | 9 | for sub in users: 10 | try: 11 | user_data = "{0:1}\t{1:2}\t{2:<15}\t\t{3:<10}\t{4}".format( 12 | sub[0], 13 | sub[1], 14 | sub[3], 15 | sub[7], 16 | sub[5] 17 | ) 18 | data += user_data 19 | 20 | except Exception as e: 21 | print(e) 22 | print(sub) 23 | 24 | data += "\n" 25 | 26 | print('\x1bc') 27 | print("\x1b[{};{}H".format(0, 0)) 28 | print("\x1b[2J") 29 | print(data) 30 | -------------------------------------------------------------------------------- /scripts/call.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | 5 | def call(caller_extension, extension, voice_file): 6 | if not caller_extension: 7 | caller_extension = "" 8 | call_data = """Channel: SIP/GSM/{} 9 | MaxRetries: 10 10 | RetryTime: 10 11 | WaitTime: 30 12 | CallerID: {} 13 | Application: Playback 14 | Data: {}""".format(extension, caller_extension, voice_file) 15 | 16 | call_file = "{}.call".format(extension) 17 | with open(call_file, "w") as f: 18 | f.write(call_data) 19 | f.close() 20 | 21 | os.system("chown asterisk:asterisk {}".format(call_file)) 22 | os.system("mv {} /var/spool/asterisk/outgoing/".format(call_file)) 23 | 24 | 25 | if __name__ == "__main__": 26 | if len(sys.argv) != 4: 27 | print("usage: ./call.py [extention_from] [extention_to] [voice_file]") 28 | sys.exit(1) 29 | 30 | call(sys.argv[1], sys.argv[2], sys.argv[3]) 31 | -------------------------------------------------------------------------------- /scripts/HLR.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sqlite3 3 | 4 | 5 | class Database: 6 | def __init__(self, hlr_loc): 7 | self.db = sqlite3.connect(hlr_loc) 8 | self.db_cursor = self.db.cursor() 9 | 10 | #self.subscribers = [] 11 | self.IMSIs = [] 12 | 13 | 14 | def get_new_users(self): 15 | for user in self.db_cursor.execute("SELECT * FROM Subscriber"): 16 | if user[3] not in self.IMSIs and user[3] != None and user[3] != 999999999999999: 17 | self.IMSIs.append(user[3]) 18 | #self.subscribers.append(user) 19 | yield user 20 | 21 | 22 | def get_subscribers(self): 23 | subscribers = [] 24 | 25 | for user in self.db_cursor.execute("SELECT * FROM Subscriber"): 26 | if user[3] != None and user[3] != 999999999999999: 27 | subscribers.append(user) 28 | 29 | return subscribers 30 | -------------------------------------------------------------------------------- /scripts/user_interact.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import json 3 | import random 4 | from scripts import sms_smpp, ussd, call 5 | import sys 6 | 7 | def interact(config, extension): 8 | print("executing script...") 9 | 10 | with open(config, encoding="utf-8") as data: 11 | config = json.load(data)["scripts"] 12 | 13 | if config["sms"]["enabled"]: 14 | sender_extension = config["sms"]["sender_extension"] 15 | message = random.choice(config["sms"]["message"]) 16 | 17 | sms_smpp.send_message(sender_extension, str(extension), message) 18 | 19 | if config["ussd"]["enabled"]: 20 | ussd_type = int(config["ussd"]["ussd_type"]) 21 | message = random.choice(config["ussd"]["message"]) 22 | 23 | ussd.send(extension, ussd_type, message) 24 | 25 | if config["call"]["enabled"]: 26 | caller_extension = config["call"]["caller_extension"] 27 | voice_file = config["call"]["voice-file"] 28 | 29 | call.call(caller_extension, extension, voice_file) 30 | 31 | if __name__ == "__main__": 32 | if len(sys.argv) != 2: 33 | print("usage: python3 user_interact.py [extension]") 34 | exit(1) 35 | 36 | interact(int(sys.argv[1])) 37 | -------------------------------------------------------------------------------- /interact.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from scripts import HLR, user_interact, monitor 3 | import argparse 4 | 5 | help_message = """ 6 | Script for interaction with users 7 | 8 | """ 9 | 10 | if __name__ == "__main__": 11 | parser = argparse.ArgumentParser(description=help_message) 12 | parser.add_argument("-c", "--config", default="config.json", 13 | help="Config file for auto user interaction. (Default=config.json)") 14 | 15 | parser.add_argument("-D", "--hlr", default="/var/lib/osmocom/hlr.sqlite3", 16 | help="Config file for auto user interaction. (Default=/var/lib/osmocom/hlr.sqlite3)") 17 | 18 | parser.add_argument("-e", "--extension", default="all", 19 | help="Phone number. (Default=all)") 20 | 21 | 22 | args = parser.parse_args() 23 | if args.extension == "all": 24 | try: 25 | db = HLR.Database(args.hlr) 26 | for user in db.get_subscribers(): 27 | extension = user[5] 28 | user_interact.interact(args.config, extension) 29 | monitor.update_monitor(db.subscribers) 30 | 31 | except Exception as e: 32 | print("[-] {}".format(e)) 33 | exit(1) 34 | else: 35 | user_interact.interact(args.config, args.extension) 36 | -------------------------------------------------------------------------------- /scripts/ussd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import telnetlib 3 | import sqlite3 4 | import sys 5 | import time 6 | 7 | imsi = 999999999999999 8 | 9 | def check_subscriber(imsi, conn): 10 | conn.write("show subscriber imsi {}\n".format(imsi).encode()) 11 | res = conn.read_until(b"OpenBSC> ") 12 | 13 | if b"No subscriber found for imsi" in res: 14 | conn.write("subscriber create imsi {}\n".format(imsi).encode()) 15 | conn.read_until(b"OpenBSC> ") 16 | 17 | def send(extension, type, message): 18 | conn = telnetlib.Telnet("127.0.0.1", 4242) 19 | conn.read_until(b"OpenBSC> ") 20 | 21 | check_subscriber(imsi, conn) 22 | 23 | conn.write("subscriber extension {} silent-sms sender imsi {} send .SILENT\n".format(extension, imsi).encode()) 24 | res = conn.read_until(b"OpenBSC> ") 25 | if b"%" in res: 26 | print(res) 27 | return False 28 | 29 | time.sleep(3) 30 | conn.write("subscriber extension {} ussd-notify {} {}\n".format(extension, type, message).encode()) 31 | res = conn.read_until(b"OpenBSC> ") 32 | 33 | 34 | if __name__ == "__main__": 35 | if len(sys.argv) != 4: 36 | print("usage: ./sms.py [extension] [ussd-type] [\"message\"]") 37 | sys.exit(1) 38 | 39 | extension = sys.argv[1] 40 | ussd_type = sys.argv[2] 41 | message = sys.argv[3] 42 | send(extension, ussd_type, message) -------------------------------------------------------------------------------- /auxiliary/ussd_broadcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import telnetlib 3 | import sqlite3 4 | import sys 5 | import time 6 | 7 | imsi = 999999999999999 8 | HLR_DATABASE = "configs/hlr.sqlite3" 9 | 10 | def check_subscriber(imsi): 11 | conn.write(b"show subscriber imsi %d\n" % imsi) 12 | res = conn.read_until(b"OpenBSC> ") 13 | 14 | if b"No subscriber found for imsi" in res: 15 | conn.write(b"subscriber create imsi %d\n" % imsi) 16 | conn.read_until(b"OpenBSC> ") 17 | 18 | def get_users(): 19 | # returns user id list generator 20 | 21 | db = sqlite3.connect(HLR_DATABASE) 22 | c = db.cursor() 23 | c.execute("SELECT * FROM Subscriber") 24 | 25 | for subscriber in c.fetchall(): 26 | yield subscriber[0] 27 | 28 | def ussd_broadcast(type, message): 29 | users = list(get_users()) 30 | 31 | for id in users: 32 | conn.write(b"subscriber id %d silent-sms sender imsi %d send .SILENT\n" % (id, imsi)) 33 | res = conn.read_until(b"OpenBSC> ") 34 | if b"%" in res: 35 | print(res) 36 | exit(1) 37 | 38 | time.sleep(3) 39 | for id in users: 40 | conn.write(b"subscriber id %d ussd-notify %s %s\n" % (id, type, message)) 41 | res = conn.read_until(b"OpenBSC> ") 42 | 43 | if __name__ == "__main__": 44 | try: 45 | type = int(sys.argv[1]) 46 | message = " ".join(sys.argv[2:]) 47 | except: 48 | print("usage: ./sms_broadcast.py [ussd-type ( 0|1|2 )] message") 49 | exit(1) 50 | 51 | conn = telnetlib.Telnet("127.0.0.1", 4242) 52 | conn.read_until(b"OpenBSC> ") 53 | 54 | check_subscriber(imsi) 55 | ussd_broadcast(type, message) 56 | -------------------------------------------------------------------------------- /auxiliary/sms_spam.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import telnetlib 3 | import sys 4 | import random 5 | import time 6 | 7 | imsi = 999999999999999 8 | 9 | def check_extension(extension): 10 | conn.write(b"show subscriber extension %s\n" % extension) 11 | res = conn.read_until(b"OpenBSC> ") 12 | 13 | if b"No subscriber found for extension" in res: 14 | print("Phone with extension %s not found ;(" % extension) 15 | exit(1) 16 | 17 | def check_spam_subscriber(): 18 | conn.write(b"show subscriber imsi %d\n" % imsi) 19 | res = conn.read_until(b"OpenBSC> ") 20 | 21 | if b"No subscriber found for imsi" in res: 22 | conn.write(b"subscriber create imsi %d\n" % imsi) 23 | print(conn.read_until(b"OpenBSC> ")) 24 | 25 | def send(extension, spam_number, message): 26 | print("Sending sms from %d..." % spam_number) 27 | 28 | conn.write(b"enable\n") 29 | conn.read_until(b"OpenBSC# ") 30 | conn.write(b"subscriber imsi %d extension %d\n" % (imsi, spam_number)) 31 | conn.read_until(b"OpenBSC# ") 32 | conn.write(b"disable\n") 33 | conn.read_until(b"OpenBSC> ") 34 | 35 | conn.write(b"subscriber extension %s sms sender extension %d send %s\n" % (extension, spam_number, message)) 36 | res = conn.read_until(b"OpenBSC> ") 37 | 38 | if b"%" in res: 39 | print(res) 40 | exit(1) 41 | 42 | if __name__ == "__main__": 43 | try: 44 | extension = sys.argv[1] 45 | repeats = int(sys.argv[2]) 46 | message = " ".join(sys.argv[3:]) 47 | except: 48 | print("usage: ./sms_broadcast.py extension [num of repeats] message") 49 | exit(1) 50 | 51 | conn = telnetlib.Telnet("127.0.0.1", 4242) 52 | conn.read_until(b"OpenBSC> ") 53 | 54 | check_extension(extension) 55 | check_spam_subscriber() 56 | 57 | for _ in range(repeats): 58 | spam_number = random.randint(1000,9999) 59 | send(extension, spam_number, message) 60 | time.sleep(2) 61 | -------------------------------------------------------------------------------- /scripts/sms_smpp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- encoding: UTF-8 -*- 3 | import logging 4 | import sys 5 | 6 | import smpplib.gsm 7 | import smpplib.client 8 | import smpplib.consts 9 | 10 | logging.basicConfig(level = logging.DEBUG, 11 | format = "%(levelname)s %(filename)s:%(lineno)d %(message)s") 12 | 13 | def send_message(source, dest, string): 14 | client = smpplib.client.Client('127.0.0.1', 2775) 15 | 16 | # Print when obtain message_id 17 | client.set_message_sent_handler( 18 | lambda pdu: sys.stdout.write('sent {} {}\n'.format(pdu.sequence, pdu.message_id))) 19 | client.set_message_received_handler( 20 | lambda pdu: sys.stdout.write('delivered {}\n'.format(pdu.receipted_message_id))) 21 | 22 | client.connect() 23 | client.bind_transceiver(system_id='OSMO-SMPP', password='1234') 24 | 25 | parts, encoding_flag, msg_type_flag = smpplib.gsm.make_parts(string) 26 | #part = b"".join(parts) 27 | 28 | try: 29 | string.encode("ascii") 30 | coding = encoding_flag 31 | except: 32 | coding = smpplib.consts.SMPP_ENCODING_ISO10646 33 | 34 | logging.info('Sending SMS "%s" to %s' % (string, dest)) 35 | for part in parts: 36 | pdu = client.send_message( 37 | msg_type=smpplib.consts.SMPP_MSGTYPE_USERACK, 38 | source_addr_ton=smpplib.consts.SMPP_TON_ALNUM, 39 | source_addr_npi=smpplib.consts.SMPP_NPI_ISDN, 40 | source_addr=source, 41 | dest_addr_ton=smpplib.consts.SMPP_TON_INTL, 42 | dest_addr_npi=smpplib.consts.SMPP_NPI_ISDN, 43 | destination_addr=dest, 44 | short_message=part, 45 | data_coding=coding, 46 | esm_class=msg_type_flag, 47 | #esm_class=smpplib.consts.SMPP_MSGMODE_FORWARD, 48 | registered_delivery=True, 49 | ) 50 | #print(pdu.generate()) 51 | logging.debug(pdu.sequence) 52 | 53 | 54 | if __name__ == "__main__": 55 | if len(sys.argv) != 4: 56 | print("usage: ./sms.py [from] [to] [\"message\"]") 57 | sys.exit(1) 58 | 59 | source = sys.argv[1] 60 | dest = sys.argv[2] 61 | message = sys.argv[3] 62 | 63 | send_message(source, dest, message) -------------------------------------------------------------------------------- /auxiliary/sms_broadcast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import telnetlib 3 | import sqlite3 4 | import sys 5 | 6 | imsi = 999999999999999 7 | HLR_DATABASE = "configs/hlr.sqlite3" 8 | 9 | def check_extension(extension): 10 | conn.write(b"show subscriber extension %s\n" % extension) 11 | res = conn.read_until(b"OpenBSC> ") 12 | 13 | if b"No subscriber found for extension" in res: 14 | create_subscriber(extension) 15 | 16 | def create_subscriber(extension): 17 | print("No user with excension %s found. Creating new..." % extension) 18 | print("Extension: %s, IMSI: %d" % (extension, imsi)) 19 | 20 | conn.write(b"show subscriber imsi %d\n" % imsi) 21 | res = conn.read_until(b"OpenBSC> ") 22 | 23 | if b"No subscriber found for imsi" in res: 24 | conn.write(b"subscriber create imsi %d\n" % imsi) 25 | conn.read_until(b"OpenBSC> ") 26 | 27 | conn.write(b"enable\n") 28 | conn.read_until(b"OpenBSC# ") 29 | conn.write(b"subscriber imsi %d extension %s\n" % (imsi, extension)) 30 | conn.read_until(b"OpenBSC# ") 31 | conn.write(b"disable\n") 32 | conn.read_until(b"OpenBSC> ") 33 | 34 | def get_users(): 35 | # returns user id list generator 36 | 37 | db = sqlite3.connect(HLR_DATABASE) 38 | c = db.cursor() 39 | c.execute("SELECT * FROM Subscriber") 40 | 41 | for subscriber in c.fetchall(): 42 | yield subscriber[0] 43 | 44 | def send_sms(id, extension, message): 45 | conn.write(b"subscriber id %d sms sender extension %s send %s\n" % (id, extension, message)) 46 | res = conn.read_until(b"OpenBSC> ") 47 | if b"%" in res: 48 | print(res) 49 | exit(1) 50 | 51 | if __name__ == "__main__": 52 | try: 53 | extension = sys.argv[1] 54 | message = " ".join(sys.argv[2:]) 55 | except: 56 | print("usage: ./sms_broadcast.py extension message") 57 | exit(1) 58 | 59 | conn = telnetlib.Telnet("127.0.0.1", 4242) 60 | conn.read_until(b"OpenBSC> ") 61 | 62 | check_extension(extension) 63 | 64 | for id in get_users(): 65 | send_sms(id, extension, message) 66 | -------------------------------------------------------------------------------- /configs/openbsc.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! OpenBSC configuration saved from vty 3 | ! ! 4 | password foo 5 | ! 6 | line vty 7 | no login 8 | ! 9 | e1_input 10 | e1_line 0 driver ipa 11 | network 12 | network country code 313 13 | mobile network code 37 14 | short name H4ck1ng_N3Tw0rk 15 | long name H4ck1ng_N3Tw0rk 16 | auth policy accept-all 17 | location updating reject cause 13 18 | encryption a5 0 19 | neci 1 20 | rrlp mode none 21 | mm info 1 22 | handover 0 23 | handover window rxlev averaging 10 24 | handover window rxqual averaging 1 25 | handover window rxlev neighbor averaging 10 26 | handover power budget interval 6 27 | handover power budget hysteresis 3 28 | handover maximum distance 9999 29 | subscriber-keep-in-ram 0 30 | bts 0 31 | type sysmobts 32 | band GSM900 33 | cell_identity 0 34 | location_area_code 1 35 | training_sequence_code 7 36 | base_station_id_code 63 37 | ms max power 15 38 | rxlev access min 0 39 | periodic location update 1000 40 | cell reselection hysteresis 14 41 | cell reselection offset 120 42 | temporary offset 0 43 | penalty time 20 44 | channel allocator ascending 45 | rach tx integer 9 46 | rach max transmission 7 47 | ip.access unit_id 1801 0 48 | oml ip.access stream_id 255 line 0 49 | gprs mode none 50 | trx 0 51 | rf_locked 0 52 | arfcn 100 53 | nominal power 34 54 | max_power_red 20 55 | rsl e1 tei 0 56 | timeslot 0 57 | phys_chan_config CCCH+SDCCH4 58 | hopping enabled 0 59 | timeslot 1 60 | phys_chan_config SDCCH8 61 | hopping enabled 0 62 | timeslot 2 63 | phys_chan_config TCH/F 64 | hopping enabled 0 65 | timeslot 3 66 | phys_chan_config TCH/F 67 | hopping enabled 0 68 | timeslot 4 69 | phys_chan_config TCH/F 70 | hopping enabled 0 71 | timeslot 5 72 | phys_chan_config TCH/F 73 | hopping enabled 0 74 | timeslot 6 75 | phys_chan_config TCH/F 76 | hopping enabled 0 77 | timeslot 7 78 | phys_chan_config TCH/F 79 | hopping enabled 0 80 | nitb 81 | assign-tmsi 82 | subscriber-create-on-demand random 100 199 83 | smpp 84 | local-tcp-port 2775 85 | system-id OSMO-SMPP 86 | smpp-first 87 | policy accept-all 88 | esme OSMPP 89 | password 1234 90 | default-route 91 | osmocom-extensions 92 | 93 | -------------------------------------------------------------------------------- /configs/openbsc_egprs.cfg: -------------------------------------------------------------------------------- 1 | ! 2 | ! OpenBSC configuration saved from vty 3 | ! ! 4 | password foo 5 | ! 6 | line vty 7 | no login 8 | ! 9 | e1_input 10 | e1_line 0 driver ipa 11 | e1_line 0 port 0 12 | no e1_line 0 keepalive 13 | network 14 | network country code 313 15 | mobile network code 37 16 | short name H4ck1ng_N3Tw0rk 17 | long name H4ck1ng_N3Tw0rk 18 | auth policy accept-all 19 | authorized-regexp .* 20 | location updating reject cause 13 21 | encryption a5 0 22 | neci 1 23 | rrlp mode none 24 | mm info 1 25 | handover 0 26 | handover window rxlev averaging 10 27 | handover window rxqual averaging 1 28 | handover window rxlev neighbor averaging 10 29 | handover power budget interval 6 30 | handover power budget hysteresis 3 31 | handover maximum distance 9999 32 | subscriber-keep-in-ram 0 33 | bts 0 34 | type sysmobts 35 | band GSM900 36 | cell_identity 0 37 | location_area_code 1 38 | training_sequence_code 7 39 | base_station_id_code 63 40 | codec-support fr efr amr 41 | ms max power 15 42 | rxlev access min 0 43 | periodic location update 1000 44 | cell reselection hysteresis 14 45 | cell reselection offset 120 46 | temporary offset 0 47 | penalty time 20 48 | radio-link-timeout 32 49 | channel allocator ascending 50 | rach tx integer 9 51 | rach max transmission 7 52 | channel-descrption attach 1 53 | channel-descrption bs-pa-mfrms 5 54 | channel-descrption bs-ag-blks-res 1 55 | ip.access unit_id 1801 0 56 | oml ip.access stream_id 255 line 0 57 | gprs mode egprs 58 | gprs routing area 1 59 | gprs cell bvci 1234 60 | gprs nsei 1234 61 | gprs nsvc 0 nsvci 1234 62 | gprs nsvc 0 local udp port 23001 63 | gprs nsvc 0 remote udp port 23000 64 | gprs nsvc 0 remote ip 127.0.0.1 65 | no force-combined-si 66 | trx 0 67 | rf_locked 0 68 | arfcn 100 69 | nominal power 34 70 | max_power_red 20 71 | rsl e1 tei 0 72 | timeslot 0 73 | phys_chan_config CCCH+SDCCH4 74 | hopping enabled 0 75 | timeslot 1 76 | phys_chan_config SDCCH8 77 | hopping enabled 0 78 | timeslot 2 79 | phys_chan_config TCH/F 80 | hopping enabled 0 81 | timeslot 3 82 | phys_chan_config TCH/F 83 | hopping enabled 0 84 | timeslot 4 85 | phys_chan_config TCH/F 86 | hopping enabled 0 87 | timeslot 5 88 | phys_chan_config TCH/F 89 | hopping enabled 0 90 | timeslot 6 91 | phys_chan_config PDCH 92 | hopping enabled 0 93 | timeslot 7 94 | phys_chan_config PDCH 95 | hopping enabled 0 96 | nitb 97 | assign-tmsi 98 | subscriber-create-on-demand random 100 199 99 | smpp 100 | local-tcp-port 2775 101 | system-id OSMO-SMPP 102 | smpp-first 103 | policy accept-all 104 | esme OSMPP 105 | password 1234 106 | default-route 107 | osmocom-extensions -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![](https://raw.githubusercontent.com/DrLafa/osmo-nitb-scripts/master/doc/img/help.png) 3 | 4 | ### RougeBTS 5 | 6 | This project is created for easy deployment of Osmocom GSM stack and convenient interaction with users 7 | 8 | - E(GPRS) support 9 | - Asterisk support 10 | - monitoring online subscribers 11 | - automatic interaction with new users, like sms, ussd or call 12 | - manual interaction with individual users 13 | - USSD-broadcast 14 | - SMS-broadcast 15 | - SMS-spam ;) 16 | 17 | 18 | ![](https://raw.githubusercontent.com/DrLafa/osmo-nitb-scripts/master/doc/img/RougeBTS.png) 19 | 20 | All software was tested on [LimeSDR-Mini + Orange Pi Zero](https://codeby.net/threads/miniatjurnaja-sotovaja-stancija-na-baze-limesdr-mini-i-orange-pi-zero.66747/) with Armbian Bionic. Also with Debian 10 21 | 22 | ### Installation 23 | Installing LimeSuite 24 | ``` 25 | apt install git g++ cmake libsqlite3-dev libi2c-dev libusb-1.0-0-dev 26 | git clone https://github.com/myriadrf/LimeSuite.git 27 | cd LimeSuite 28 | mkdir builddir && cd builddir 29 | cmake ../ 30 | make -j4 31 | sudo make install 32 | sudo ldconfig 33 | cd ../udev-rules/ 34 | sudo sh LimeSuite/udev-rules/install.sh 35 | cd ~/ 36 | ``` 37 | Adding the Osmocom repository 38 | ``` 39 | sudo su 40 | wget http://download.opensuse.org/repositories/network:/osmocom:/latest/Debian_10//Release.key 41 | apt-key add Release.key 42 | rm Release.key 43 | echo "deb http://download.opensuse.org/repositories/network:/osmocom:/latest/Debian_10/ ./" > /etc/apt/sources.list.d/osmocom-latest.list 44 | apt update 45 | exit 46 | ``` 47 | Installing 48 | ``` 49 | sudo apt install osmocom-nitb osmo-trx-lms osmo-bts-trx osmo-ggsn osmo-sgsn osmo-pcu osmo-sip-connector libsofia-sip-ua-glib-dev asterisk sqlite3 libsmpp1 telnet python3-pip 50 | sudo pip3 install smpplib 51 | ``` 52 | It is necessary to install Osmocom stack from apt, because it configure Systemd services. If you compile osmocom from sources, you need to install Systemd services by yourself with script `install_services.sh` 53 | ``` 54 | sudo ./install_services.sh 55 | ``` 56 | Stopping launched services after installation 57 | ``` 58 | sudo su 59 | systemctl stop osmocom-nitb 60 | systemctl stop osmo-nitb 61 | systemctl stop osmo-trx-lms 62 | systemctl stop osmo-bts-trx 63 | systemctl stop osmo-ggsn 64 | systemctl stop osmo-sgsn 65 | systemctl stop osmo-pcu 66 | systemctl stop osmo-sip-connector 67 | systemctl stop asterisk 68 | exit 69 | ``` 70 | Disabling service autostart 71 | ``` 72 | sudo su 73 | systemctl disable osmocom-nitb 74 | systemctl disable osmo-nitb 75 | systemctl disable osmo-trx-lms 76 | systemctl disable osmo-bts-trx 77 | systemctl disable osmo-ggsn 78 | systemctl disable osmo-sgsn 79 | systemctl disable osmo-pcu 80 | systemctl disable osmo-sip-connector 81 | systemctl disable asterisk 82 | ``` 83 | Cloning 84 | ``` 85 | git clone https://github.com/DrLafa/osmo-nitb-scripts 86 | ``` 87 | 88 | ### Configure 89 | All osmocom config files stored in `config/` folder and updating everytime when you start `main.py`. You can change it by youself. 90 | 91 | ### config.json 92 | For easy setup of user-interactivity you can use config.json 93 | - config.json example 94 | ``` 95 | { 96 | "scripts":{ 97 | "sms":{ 98 | "enabled": false, 99 | "sender_extension": "John Connor", 100 | "message":[ 101 | "If you are reading this, then you are resistance" 102 | ] 103 | }, 104 | "ussd":{ 105 | "enabled": false, 106 | "ussd_type": 1, 107 | "message":[ 108 | "Welcome to our l33t hax0r network.", 109 | "If you are reading this, then you are true L33T 1337 H4xXx0r" 110 | ] 111 | }, 112 | "call":{ 113 | "enabled": true, 114 | "caller_extension": 666, 115 | "voice-file": "tt-monkeys" 116 | } 117 | } 118 | } 119 | ``` 120 | #### sms 121 | Send sms to new users. When user connect to network, script choose 1 random message from ```message``` section and sending it from extension ```sender_extension``` 122 | 123 | #### ussd 124 | Send ussd to new users. Script choose 1 random message from ```message``` section adn sending it to user 125 | 126 | #### call 127 | Make a call to new user. This function works only with Asterisk support. voice-file is 16-bit 8 kHz wav file. If ```caller_extension``` is ```false```, then the user sees that the phone is not defined. 128 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import subprocess 4 | import time 5 | import datetime 6 | import signal 7 | from scripts import HLR, user_interact, monitor 8 | import argparse 9 | 10 | def signal_handler(sig, frame): 11 | print('\x1bc') 12 | stop_services(log=True) 13 | if os.path.exists("/var/lib/osmocom/hlr.sqlite3"): 14 | os.remove("/var/lib/osmocom/hlr.sqlite3") 15 | 16 | #print("\x1b[2J") 17 | print("Exiting...") 18 | time.sleep(2) 19 | exit(0) 20 | 21 | 22 | def check_root(): 23 | if not os.geteuid() == 0: 24 | print("Run as root!") 25 | return False 26 | else: 27 | return True 28 | 29 | 30 | def sdr_check(): 31 | print("[*] Checking for SDR device..") 32 | p = subprocess.Popen(['LimeUtil', '--find'], stdout=subprocess.PIPE) 33 | output, err = p.communicate() 34 | rc = p.returncode 35 | 36 | if b"LimeSDR" in output: 37 | print("[+] Found device: " + output.decode()) 38 | else: 39 | print("[-] Not devices found, exiting...") 40 | exit(1) 41 | 42 | 43 | #configure osmocom, systemctl and asterisk 44 | def configure(gprs, sip, interface, config_path="/etc/osmocom"): 45 | # stopping osmocom services, if they a running 46 | stop_services() 47 | 48 | if not os.path.exists(config_path): 49 | os.makedirs(config_path) 50 | 51 | app_dir = os.path.dirname(os.path.realpath(__file__)) 52 | 53 | if gprs: 54 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/openbsc_egprs.cfg", config_path+"/osmo-nitb.cfg"), shell=True) 55 | subprocess.call("su -c \"echo \'1\' > /proc/sys/net/ipv4/ip_forward\"", shell=True) 56 | subprocess.call("iptables -A POSTROUTING -s 176.16.1.1/24 -t nat -o {} -j MASQUERADE".format(interface), shell=True) 57 | else: 58 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/openbsc.cfg", config_path+"/osmo-nitb.cfg"), shell=True) 59 | 60 | 61 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-pcu.cfg", config_path+"/osmo-pcu.cfg"), shell=True) 62 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-sgsn.cfg", config_path+"/osmo-sgsn.cfg"), shell=True) 63 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-ggsn.cfg", config_path+"/osmo-ggsn.cfg"), shell=True) 64 | 65 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-bts.cfg", config_path+"/osmo-bts-trx.cfg"), shell=True) 66 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-trx.cfg", config_path+"/osmo-trx-lms.cfg"), shell=True) 67 | 68 | if sip: 69 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/osmo-sip-connector.cfg", config_path+"/osmo-sip-connector.cfg"), shell=True) 70 | subprocess.call("cp -f {0} {1}".format(app_dir+"/services/osmo-nitb_sip.service", "/lib/systemd/system/osmo-nitb.service"), shell=True) 71 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/extensions.conf", "/etc/asterisk/extensions.conf"), shell=True) 72 | subprocess.call("cp -f {0} {1}".format(app_dir+"/configs/sip.conf", "/etc/asterisk/sip.conf"), shell=True) 73 | else: 74 | subprocess.call("cp -f {0} {1}".format(app_dir+"/services/osmo-nitb.service", "/lib/systemd/system/osmo-nitb.service"), shell=True) 75 | 76 | subprocess.call("sysctl -w kernel.sched_rt_runtime_us=-1", shell=True) 77 | subprocess.call("systemctl daemon-reload", shell=True) 78 | 79 | 80 | def run(gprs, sip): 81 | services = ["osmo-nitb.service", "osmo-trx-lms.service", "osmo-bts-trx.service"] 82 | if gprs: 83 | services += ["osmo-pcu.service", "osmo-ggsn.service", "osmo-sgsn.service"] 84 | if sip: 85 | services += ["osmo-sip-connector", "asterisk"] 86 | 87 | for service in services: 88 | print("[+] starting {0} ...".format(service)) 89 | subprocess.call("systemctl start {0}".format(service), shell=True) 90 | 91 | check_errors(service=service) 92 | 93 | 94 | def stop_services(log=False): 95 | services = ["osmocom-nitb.service", 96 | "osmo-nitb.service", 97 | "osmo-trx-lms.service", 98 | "osmo-bts-trx.service", 99 | "osmo-pcu.service", 100 | "osmo-ggsn.service", 101 | "osmo-sgsn.service", 102 | "osmo-sip-connector", 103 | "asterisk"] 104 | 105 | for service in services: 106 | p = subprocess.Popen(["systemctl", "status", service], stdout=subprocess.PIPE) 107 | output, err = p.communicate() 108 | 109 | if b"Active: active" in output or b"activating (auto-restart)" in output: 110 | if log: 111 | print("[*] Stopping {0} ...".format(service)) 112 | 113 | subprocess.call(["systemctl", "stop", service]) 114 | 115 | 116 | def check_errors(gprs=False, sip=False, service=False): 117 | if not service: 118 | services = ["osmo-nitb.service", "osmo-trx-lms.service", "osmo-bts-trx.service"] 119 | if gprs: 120 | services += ["osmo-pcu.service", "osmo-ggsn.service", "osmo-sgsn.service"] 121 | if sip: 122 | services += ["osmo-sip-connector"] 123 | else: 124 | services = [service] 125 | 126 | date = datetime.datetime.now() 127 | 128 | for service in services: 129 | #s = subprocess.Popen(["journalctl", "-b", "-S", 130 | # "{0}:{1}:{2}".format(date.hour, date.minute, date.second), 131 | # "-u", service], stdout=subprocess.PIPE).communicate()[0] 132 | 133 | #print(s.decode()) 134 | #if b"Failed with result 'exit-code'" in s: 135 | status = subprocess.Popen(["systemctl", "status", service], stdout=subprocess.PIPE).communicate()[0] 136 | if not b"active (running)" in status: 137 | print( "Somethigs wrong with {0}, see journalctl -b -S {1} -u {0}".format( 138 | service, 139 | "{0}:{1}:{2}".format(date.hour, date.minute, date.second)) 140 | ) 141 | stop_services() 142 | exit(1) 143 | 144 | 145 | help_message = """ 146 | Script for automaticaly preparing and deploying Osmocom GSM stack. 147 | 148 | """ 149 | 150 | if __name__ == "__main__" and check_root(): 151 | parser = argparse.ArgumentParser(description=help_message) 152 | 153 | parser.add_argument("-u", "--interact", 154 | action="store_true", dest="user_interaction", default=False, 155 | help="Enable automaticaly interaction with all new users.") 156 | 157 | parser.add_argument("-c", default="config.json", dest="config", 158 | help="Config file for auto user interaction. (Default=config.json)") 159 | 160 | parser.add_argument("--gprs", action="store_true", default=False, 161 | help="Enable E(GPRS) support. (Default=False)") 162 | 163 | parser.add_argument("-i", default="wlan0", dest="interface", 164 | help="Interface to routing E(GPRS). (Default=wlan0)") 165 | 166 | parser.add_argument("--sip", action="store_true", default=False, 167 | help="Enable sip (Asterisk) support. (Default=False)") 168 | 169 | args = parser.parse_args() 170 | 171 | hlr_path = "/var/lib/osmocom/hlr.sqlite3" 172 | user_interaction = args.user_interaction 173 | config = args.config 174 | gprs = args.gprs 175 | interface = args.interface 176 | sip = args.sip 177 | 178 | signal.signal(signal.SIGINT, signal_handler) 179 | 180 | sdr_check() 181 | configure(gprs, sip, interface) 182 | 183 | run(gprs, sip) 184 | check_errors() 185 | db = HLR.Database(hlr_path) 186 | print("[+] Done") 187 | time.sleep(3) 188 | 189 | while 1: 190 | if user_interaction: 191 | for user in db.get_new_users(): 192 | extension = user[5] 193 | time.sleep(3) 194 | user_interact.interact(config, extension) 195 | 196 | monitor.update_monitor(db.get_subscribers()) 197 | check_errors() 198 | time.sleep(1) 199 | --------------------------------------------------------------------------------