├── README.md ├── requirements.txt └── source ├── command-based └── main.py └── menu-based ├── api.py └── main.py /README.md: -------------------------------------------------------------------------------- 1 | ## 📱 sms_spoofer ```(ONLY FOR EDUCATIONAL USAGE)``` 2 | 3 | this utility allows you to send SMS to any phone number from any name with any content (for example send notification about changed password via SMS) 4 | ([example #1](https://i.imgur.com/SOmATqN.jpg), [example #2](https://i.imgur.com/Ll26s2U.jpg)) 5 | 6 | ![alt-text](https://i.imgur.com/2JNGiIi.png) 7 | 8 | ## installation 9 |
windows 10 | 11 | ``` 12 | 1) download python 3.10+ 13 | 2) download and unpack sms_spoofer.zip 14 | 15 | open terminal in unpacked folder and execute following commands 16 | 3) pip install -r requirements.txt 17 | 4) python source/menu-based/main.py 18 | ``` 19 | 20 |
21 | 22 |
linux 23 | 24 | ``` 25 | $ sudo apt-get install python3 git 26 | $ git clone https://github.com/Defaultik/sms_spoofer 27 | $ cd sms_spoofer 28 | $ pip3 install -r requirements.txt 29 | $ python3 source/menu-based/main.py 30 | ``` 31 | 32 |
33 | 34 |
macos 35 | 36 | ``` 37 | $ brew install python3 git 38 | $ git clone https://github.com/Defaultik/sms_spoofer 39 | $ cd sms_spoofer 40 | $ pip3 install -r requirements.txt 41 | $ python3 source/menu-based/main.py 42 | ``` 43 | 44 |
45 | 46 | ## f.a.q 47 | **(?) is this free?** 48 | unfortunately this program is just utility that works on API of big sms gateway, and this gateway takes money from every sms that you send 49 | 50 | **(?) does it support any other languages besides English?** 51 | yes, it is supports unicode so program works in English, Russian, Chinese and other languages 52 | 53 | **(?) can I get a ban?** 54 | yes, your account can get a ban from Vonage if you violate their [terms of use](https://www.vonage.com/legal/communications-apis/terms-of-use/) 55 | 56 | **(?) can I use it on unix-like systems?** 57 | yes you can, the utility is not demanding on the system, and the functions are adapted to another systems 58 | 59 | 60 | ## 61 | **i'll glad to get a star from you ❤️** 62 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | annotated-types==0.7.0 2 | certifi==2025.1.31 3 | cffi==1.17.1 4 | charset-normalizer==3.4.1 5 | cryptography==44.0.1 6 | idna==3.10 7 | pycparser==2.22 8 | pydantic==2.10.6 9 | pydantic_core==2.27.2 10 | PyJWT==2.10.1 11 | requests==2.32.3 12 | typing_extensions==4.12.2 13 | urllib3==2.3.0 14 | vonage==4.4.0 15 | vonage-account==1.1.1 16 | vonage-application==2.0.1 17 | vonage-http-client==1.5.1 18 | vonage-jwt==1.1.5 19 | vonage-messages==1.4.0 20 | vonage-network-auth==1.0.2 21 | vonage-network-number-verification==1.0.2 22 | vonage-network-sim-swap==1.1.2 23 | vonage-number-insight==1.0.6 24 | vonage-numbers==1.0.4 25 | vonage-sms==1.1.5 26 | vonage-subaccounts==1.0.4 27 | vonage-users==1.2.1 28 | vonage-utils==1.1.4 29 | vonage-verify==2.1.0 30 | vonage-verify-legacy==1.0.1 31 | vonage-video==1.2.0 32 | vonage-voice==1.3.0 33 | -------------------------------------------------------------------------------- /source/command-based/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import configparser 3 | import argparse 4 | from getpass import getpass 5 | 6 | from vonage import Vonage, Auth 7 | from vonage_sms import SmsMessage, SmsResponse 8 | 9 | 10 | def main(): 11 | global config 12 | 13 | parser = argparse.ArgumentParser(prog="SMS Spoofer", description="Fake the sender name and message content") 14 | parser.add_argument("-n", "--number", required=True, help="victim's phone number") 15 | parser.add_argument("-s", "--sender", required=True, help="sender name") 16 | parser.add_argument("-t", "--text", required=True, help="message content") 17 | args = parser.parse_args() 18 | 19 | config = configparser.ConfigParser() 20 | if not os.path.exists("config.ini"): 21 | api_key = input("[!] Enter your Vonage API key: ") 22 | api_secret = getpass("[!] Enter your Vonage API Secret: ") 23 | 24 | config.add_section("api_credentials") 25 | 26 | config.set("api_credentials", "api_key", api_key) 27 | config.set("api_credentials", "api_secret", api_secret) 28 | 29 | with open("config.ini", "w") as config_file: 30 | config.write(config_file) 31 | 32 | config.read("config.ini") 33 | 34 | send_sms(args.number, args.sender, args.text) 35 | 36 | 37 | def send_sms(number, sender, text): 38 | auth = Auth( 39 | api_key=config["api_credentials"]["api_key"], 40 | api_secret=config["api_credentials"]["api_secret"] 41 | ) 42 | 43 | client = Vonage(auth=auth) 44 | 45 | message = SmsMessage(to=number, from_=sender, text=text, type="unicode") 46 | response: SmsResponse = client.sms.send(message) 47 | 48 | return response 49 | 50 | 51 | if __name__ == "__main__": 52 | main() -------------------------------------------------------------------------------- /source/menu-based/api.py: -------------------------------------------------------------------------------- 1 | import os 2 | import configparser 3 | 4 | from vonage import Vonage, Auth 5 | from vonage_sms import SmsMessage, SmsResponse 6 | from vonage_account import Balance 7 | 8 | 9 | def send_sms(number, sender, text): 10 | config = configparser.ConfigParser() 11 | config.read(os.path.join("data", "config.ini")) 12 | 13 | # Transmits user data to send sms 14 | auth = Auth( 15 | api_key=config["api_credentials"]["api_key"], 16 | api_secret=config["api_credentials"]["api_secret"] 17 | ) 18 | 19 | client = Vonage(auth=auth) 20 | 21 | message = SmsMessage(to=number, from_=sender, text=text, type="unicode") 22 | response: SmsResponse = client.sms.send(message) 23 | 24 | return response 25 | 26 | 27 | def get_balance(): 28 | config = configparser.ConfigParser() 29 | config.read(os.path.join("data", "config.ini")) 30 | 31 | auth = Auth( 32 | api_key=config["api_credentials"]["api_key"], 33 | api_secret=config["api_credentials"]["api_secret"] 34 | ) 35 | 36 | client = Vonage(auth=auth) 37 | 38 | balance: Balance = client.account.get_balance() 39 | 40 | return (f'{balance.value:0.2f} EUR') -------------------------------------------------------------------------------- /source/menu-based/main.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | import os 3 | import csv 4 | 5 | from api import send_sms, get_balance 6 | 7 | 8 | BANNER = r""" 9 | ___ __ __ ___ ___ ___ ___ ___ ___ ___ ___ 10 | / __| \/ / __| / __| _ \/ _ \ / _ \| __| __| _ \ 11 | \__ \ |\/| \__ \ \__ \ _/ (_) | (_) | _|| _|| / 12 | |___/_| |_|___/ |___/_| \___/ \___/|_| |___|_|_\ 13 | """ 14 | 15 | 16 | def print_options(*args): 17 | # Print a list of options 18 | for i, name in enumerate(args): 19 | print(f"[{i + 1}]", name) 20 | 21 | 22 | def init(): 23 | # Checks if we have all needed files in directory, and if not - creates them; 24 | # Starts program cycle 25 | global config 26 | 27 | config = configparser.ConfigParser() 28 | 29 | if not os.path.exists("data"): 30 | os.makedirs("data") 31 | 32 | contacts_path = os.path.join("data", "contacts.csv") 33 | config_path = os.path.join("data", "config.ini") 34 | 35 | if not os.path.exists(contacts_path): 36 | with open(contacts_path, "w", newline="") as contacts_file: 37 | writer = csv.DictWriter(contacts_file, fieldnames=("name", "phone_number")) 38 | writer.writeheader() 39 | 40 | if not os.path.exists(config_path): 41 | api_key = input("Enter your Vonage API key: ") 42 | api_secret = input("Enter your Vonage API Secret: ") 43 | 44 | config.add_section("api_credentials") 45 | config.set("api_credentials", "api_key", api_key) 46 | config.set("api_credentials", "api_secret", api_secret) 47 | 48 | with open(config_path, "w") as config_file: 49 | config.write(config_file) 50 | 51 | config.read(config_path) 52 | 53 | main() 54 | 55 | 56 | def main(): 57 | display_menu() 58 | print(f"Thank you for using!\nfrom https://github.com/Defaultik with <3") 59 | 60 | 61 | def display_menu(): 62 | # Main Menu Display 63 | while True: 64 | print("=" * 56) 65 | print(BANNER) 66 | print(f"{" " * 10}Your remaining balance is {get_balance()}") 67 | print("=" * 56) 68 | 69 | print_options("Single", "Multiple", "Contacts", "API Credentials", "Exit") 70 | selected_option = input("Enter number of the task: ") 71 | print("=" * 56) 72 | match selected_option: 73 | case "1": 74 | dial_number() 75 | case "2": 76 | dial_numbers() 77 | case "3": 78 | open_contacts() 79 | case "4": 80 | change_api_credentials() 81 | case "5": 82 | break 83 | case _: 84 | print("ERROR: Invalid option, try again") 85 | 86 | 87 | def dial_number(): 88 | # Send SMS to a single number menu 89 | number = input("Victim number: ").replace("+", "").replace("-", "").replace(" ", "") # removing pluses and spaces for VonageAPI that accepts only integer number 90 | sender = input("Sender name: ") 91 | text = input("Text: ") 92 | 93 | send_sms(number, sender, text) 94 | print("\nMessage sent successfully!") 95 | 96 | 97 | def dial_numbers(): 98 | # Send SMS to multiple numbers menu 99 | print("How many victims?") 100 | print_options("All of contacts", "Manual", "Back") 101 | selected_option = input("Enter number of the task: ") 102 | print("=" * 56) 103 | 104 | numbers = [] 105 | match selected_option: 106 | case "1": 107 | with open(os.path.join("data", "contacts.csv"), "r") as contacts_file: 108 | reader = csv.DictReader(contacts_file) 109 | for row in list(reader): 110 | numbers.append(row["phone_number"]) 111 | case "2": 112 | count = int(input("How many numbers do you want to bulk: ")) 113 | for i in range(count): 114 | number = input(f"Victim number #{i + 1}: ").replace("+", "").replace("-", "").replace(" ", "") 115 | numbers.append(number) 116 | case "3": 117 | return 118 | case _: 119 | print("ERROR: Invalid option") 120 | return 121 | 122 | print() 123 | sender = input("Sender name: ") 124 | text = input("Text: ") 125 | 126 | for number in numbers: 127 | send_sms(number, sender, text) 128 | 129 | 130 | def open_contacts(): 131 | # Contact management (new contacts creation, send to contact sms) 132 | with open(os.path.join("data", "contacts.csv"), "r") as contacts_file: 133 | reader = csv.DictReader(contacts_file) 134 | for i, row in enumerate(reader): 135 | print(f"[{i + 1}]", row["name"]) 136 | 137 | print("\n[*] Create a new contact") 138 | print("[X] Back") 139 | 140 | task = input("\nEnter number of the task: ") 141 | print("=" * 56) 142 | match task: 143 | case "*": 144 | new_contact() 145 | case "x" | "X": 146 | return 147 | case _: 148 | try: 149 | select_num = int(task) - 1 150 | with open(os.path.join("data", "contacts.csv"), "r") as contacts_file: 151 | reader = csv.DictReader(contacts_file) 152 | rows = list(reader) 153 | 154 | number = rows[select_num]["phone_number"] 155 | print() 156 | sender = input("Sender name: ") 157 | text = input("Text: ") 158 | 159 | send_sms(number, sender, text) 160 | except (ValueError, IndexError): 161 | print("ERROR: Invalid option") 162 | return 163 | 164 | 165 | def new_contact(): 166 | # New contacts creation menu 167 | contact_name = input("\nContact name: ") 168 | contact_number = input("Contact number: ").replace("+", "").replace("-", "").replace(" ", "") # removing pluses and spaces for VonageAPI which accepts only integer number 169 | 170 | with open(os.path.join("data", "contacts.csv"), "a", newline = "") as contacts_file: 171 | writer = csv.DictWriter(contacts_file, fieldnames=("name", "phone_number")) 172 | writer.writerow({"name": contact_name, "phone_number": contact_number}) 173 | 174 | 175 | def change_api_credentials(): 176 | # Change API credentials menu 177 | sure = input("Are you sure you want to change API Credentials (Y/N): ") 178 | if (sure.lower() == "y"): # did in in .lower() cuz we need to check any 'y' (small and large) 179 | api_key = input("\nEnter your new Vonage API key: ") 180 | api_secret = input("Enter your new Vonage API Secret: ") 181 | 182 | config.set("api_credentials", "api_key", api_key) 183 | config.set("api_credentials", "api_secret", api_secret) 184 | 185 | with open("config.ini", "w") as config_file: 186 | config.write(config_file) 187 | 188 | config.read("config.ini") 189 | 190 | 191 | if __name__ == "__main__": 192 | init() --------------------------------------------------------------------------------