Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/SMSend-Anon-SMS-Sender/smsend.py
1291 views
1
import requests
2
from stem import Signal
3
from stem.control import Controller
4
import time
5
import subprocess
6
import os
7
8
class Colors:
9
RED = '\033[31m'
10
GREEN = '\033[32m'
11
YELLOW = '\033[33m'
12
BLUE = '\033[34m'
13
MAGENTA = '\033[35m'
14
CYAN = '\033[36m'
15
WHITE = '\033[37m'
16
RESET = '\033[0m'
17
18
19
def Intro():
20
print(f"""{Colors.GREEN}
21
⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀
22
⠀⠀⠀⠀⠀⠀⠀⢀⠙⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠀⠀⠀⠀⠀⠀⠀
23
⠀⠀⠀⠀⠀⠀⠀⠀⣷⣶⣤⣄⣈⣉⣉⣉⣉⣉⣉⣉⣁⣤⡄⠀⠀⠀⠀⠀⠀⠀
24
⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀
25
⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀
26
⠀⠀⠀⠀⠀⠀⢀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀
27
⠀⠀⢀⣠⣶⣾⡏⢀⡈⠛⠻⠿⢿⣿⣿⣿⣿⣿⠿⠿⠟⠛⢁⠀⢶⣤⣀⠀⠀⠀
28
⠀⢠⣿⣿⣿⣿⡇⠸⣿⣿⣶⣶⣤⣤⣤⣤⣤⣤⣤⣶⣶⣿⡿⠂⣸⣿⣿⣷⡄⠀
29
⠀⢸⣿⣿⣿⣿⣿⣦⣄⡉⠛⠛⠛⠿⠿⠿⠿⠛⠛⠛⢉⣁⣤⣾⣿⣿⣿⣿⡷⠀
30
⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀
31
⠀⠀⠀⠀⠈⠙⠛⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⠿⠿⠛⠛⠉⠁⠀⠀⠀⠀
32
⢀⡤⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠤⢤⡀
33
⣾⡁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣶⣤⣤⣶⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣷
34
⢿⣧⡀⠀⠀⠀⢀⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣀⡀⠀⠀⠀⢀⣼⡿
35
⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁
36
⠀⠀⠈⠙⠛⠛⠛⠛⠛⠛⠛⠉⠁⠀⠀⠀⠀⠈⠉⠛⠛⠛⠛⠛⠛⠛⠋⠁⠀⠀
37
{Colors.RESET}
38
- SMSend -
39
{Colors.BLUE} By Sytaxus and nu11secur1ty: debugging plus development / cmdSNR {Colors.RESET}
40
Instructions: This tool may {Colors.RED} limitations{Colors.RESET}.
41
- In regards to questions, open an issue in the GitHub repo
42
- Check the https://github.com/sytaxus/SMSend-Anon-SMS-Sender/, for full documentation if stuck.
43
- Check the https://github.com/nu11secur1ty/Kali-Linux/tree/master/SMSend-Anon-SMS-Sender, for plugins
44
""")
45
46
def cls_scrn():
47
if os.name == 'nt':
48
_ = os.system('cls')
49
else:
50
os.system('clear')
51
52
def connect_vpn_proton(config_path, username, password):
53
try:
54
with open('vpn_auth.txt', 'w') as auth_file:
55
auth_file.write(f"{username}\n{password}\n")
56
os.chmod('vpn_auth.txt', 0o600)
57
58
process = subprocess.Popen(
59
['sudo', 'openvpn', '--config', config_path, '--auth-user-pass', 'vpn_auth.txt', '--auth-nocache'],
60
stdout=subprocess.DEVNULL,
61
)
62
time.sleep(5)
63
return process
64
except Exception as e:
65
print(f"Failed to connect to VPN: {e}")
66
return None
67
68
def check_connectivity(ip='8.8.8.8'):
69
try:
70
subprocess.check_output(['ping', '-c', '4', ip])
71
return True
72
except subprocess.CalledProcessError:
73
print('No internet connection available..\n')
74
return False
75
76
77
def disconnect_vpn_proton():
78
subprocess.run(['sudo', 'pkill', 'openvpn'])
79
time.sleep(5)
80
81
82
83
def request_sms(phone, message):
84
try:
85
resp = requests.post('https://textbelt.com/text', {
86
'phone': phone,
87
'message': message,
88
'key': 'textbelt',
89
})
90
print(resp.json() if resp.status_code == 200 else f"HTTP Error {resp.status_code}: {resp.text}")
91
finally:
92
print('Finished.\n - SMSend. - nu11secur1ty.\n')
93
94
95
def multi_sms(vpn_directory, file_name_phone_num, message):
96
print("NOTE: EACH PHONE NUMBER WILL BE USING 1 VPN. Example: If you have 2 phone numbers in the file name and 1 .ovpn file in the vpn directory, then only ONE SMS will be sent.")
97
98
if not check_connectivity():
99
print("No internet connection available before VPN connection. Aborting operation.\n")
100
return
101
102
credentials_file = input('Enter the VPN credentials file name: ')
103
try:
104
with open(credentials_file, 'r') as file:
105
username = file.readline().strip()
106
password = file.readline().strip()
107
108
with open(file_name_phone_num, 'r') as file:
109
phone_numbers = [line.strip() for line in file if line.strip()]
110
111
print(f"Searching for VPN configs in: {vpn_directory}")
112
vpn_files = [os.path.join(vpn_directory, f) for f in os.listdir(vpn_directory) if f.lower().endswith('.ovpn')]
113
114
if not vpn_files:
115
print("No VPN configuration files found in the directory.\n")
116
return
117
118
print(f"Found {len(vpn_files)} VPN config file(s).")
119
120
if len(vpn_files) < len(phone_numbers):
121
print(f"Warning: Not enough VPN configs for the number of phone numbers. Only the first {len(vpn_files)} numbers will be sent.\n")
122
answ = input('Do you want to proceed with the available VPNs? (Y/n): ').lower()
123
if answ == 'n':
124
print("Operation aborted.\n")
125
return
126
phone_numbers = phone_numbers[:len(vpn_files)]
127
128
for phone, vpn in zip(phone_numbers, vpn_files):
129
print(f"Sending SMS to {phone} using VPN config {vpn}")
130
if connect_vpn_proton(vpn, username, password) is not None:
131
if check_connectivity():
132
request_sms(phone, message)
133
print('SMS sent....\n')
134
else:
135
print("Internet connection lost after VPN connection. Aborting SMS send.\n")
136
disconnect_vpn_proton()
137
else:
138
print(f"Failed to connect using {vpn}, skipping...\n")
139
140
except Exception as e:
141
print(f"An error occurred in multi_sms: {e}\n")
142
143
def Begin():
144
cls_scrn()
145
Intro()
146
try:
147
available_choices = input(f'{Colors.BLUE}SELECT BY NUMBER:{Colors.RESET}\n1. Send ONE SMS.\n2. Send MULTIPLE SMS. (VPNs config required.)\n\nChoose > ')
148
message = input('Your custom message (LINKS ARE NOT ALLOWED DUE TO API limitations.): ')
149
150
if available_choices == '1':
151
region = input('Enter phone region/prefix (For example +1 for US/Canada): ')
152
phone_no_prefix = input('Enter phone number (Not Prefix Included): ')
153
check = []
154
155
http_detected = 0
156
o = message.split()
157
for i in o:
158
if 'http' in i or '.com' in i:
159
http_detected += 1
160
161
for i in region:
162
check.append(i)
163
if len(check) > 3:
164
print('Country prefix invalid! (Cannot exceed 3 characters.)')
165
elif http_detected >= 1:
166
print('Links are not allowed due to free api limitations.')
167
else:
168
full_number = region + phone_no_prefix
169
request_sms(full_number,message)
170
elif available_choices == '2':
171
vpn_directory = input('Enter PATH to VPN config files directory: ')
172
file_name = input('Enter file name with phone numbers. (ONE NUMBER PER LINE INCLUDING PREFIX, EX: +15555555555): ')
173
multi_sms(vpn_directory,file_name,message)
174
175
except Exception as e:
176
print(f'Invalid. Error: {e}\n')
177
178
if __name__ == "__main__":
179
Begin()
180
181