├── LICENSE ├── README.md ├── checker.py ├── requirements.txt └── screencast.gif /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 bl4ckmamb4 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenRelayMagic 2 | ``` 3 | ╔═╗┌─┐┌─┐┌┐┌╦═╗┌─┐┬ ┌─┐┬ ┬╔╦╗┌─┐┌─┐┬┌─┐ 4 | ║ ║├─┘├┤ │││╠╦╝├┤ │ ├─┤└┬┘║║║├─┤│ ┬││ 5 | ╚═╝┴ └─┘┘└┘╩╚═└─┘┴─┘┴ ┴ ┴ ╩ ╩┴ ┴└─┘┴└─┘ 6 | ``` 7 | Tool to test for vulnerable open relays on SMTP servers 8 | 9 | ### Features 10 | * Check single target/ domain list 11 | * Port 587 and 465 Implemented 12 | * Multithreaded 13 | 14 | OpenRelayMagic 15 | -------------------------------------------------------------------------------- /checker.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json, requests 3 | import socket 4 | import smtplib 5 | import random, string 6 | import argparse 7 | from tqdm import * 8 | from multiprocessing import Pool 9 | from email.mime.text import MIMEText 10 | from email.mime.multipart import MIMEMultipart 11 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 12 | requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 13 | socket.setdefaulttimeout(15) 14 | 15 | def randomshit(): 16 | digits = "".join( [random.choice(string.digits) for i in range(5)] ) 17 | chars = "".join( [random.choice(string.ascii_letters) for i in range(5)] ) 18 | randomtext = (chars+digits) 19 | return randomtext 20 | 21 | def checker(hostname): 22 | socket.setdefaulttimeout(15) 23 | try: 24 | sender = 'newsletter@'+hostname 25 | receiver = 'dracarys@getnada.com' 26 | rando = randomshit() 27 | subject = ('Unique identify '+rando) 28 | messageHTML = '

Testing

Hi you got sometime for a beer m8!?!

' 29 | messagePlain = 'Mod this if you want to send a plain message' 30 | msg = MIMEMultipart('alternative') 31 | msg['From'] = sender 32 | msg['To'] = receiver 33 | msg['Subject'] = subject 34 | msg.attach(MIMEText(messageHTML, 'html')) 35 | if args.port == 465: 36 | port = 465 37 | server = smtplib.SMTP_SSL(hostname, port) 38 | else: 39 | port = 587 40 | server = smtplib.SMTP(hostname, port) 41 | server.helo() 42 | text = msg.as_string() 43 | server.sendmail(sender, receiver, text) 44 | server.quit() 45 | 46 | time.sleep(15) 47 | check_url = "https://getnada.com:443/api/v1/inboxes/dracarys@getnada.com" 48 | check_cookies = {"tarteaucitron": "!adsense=true!gajs=true", "__gads": "Test", "__utmt": "1"} 49 | check_headers = {"Connection": "close", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", "Accept": "*/*", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors", "Referer": "https://getnada.com/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9"} 50 | rr = requests.get(check_url, headers=check_headers, cookies=check_cookies, verify=False, timeout=30) 51 | json_data = json.loads(rr.text) 52 | msgs = json_data['msgs'] 53 | delete_key = '' 54 | for i in msgs: 55 | if rando in str(i): 56 | if args.output: 57 | formatted = ('Vulnerable: ',hostname,port) 58 | f=open(args.output,'a') 59 | f.write(str(formatted)+'\n') 60 | f.close() 61 | else: 62 | print ('Vulnerable Host:',hostname,'Port:',port) 63 | delete_key = (i['uid']) 64 | #time.sleep(2) 65 | delete_cookies = {"tarteaucitron": "!adsense=true!gajs=true", "__gads": "Test", "__utmt": "1"} 66 | delete_url = ("https://getnada.com:443/api/v1/messages/"+str(delete_key)) 67 | delete_headers = {"Connection": "close", "Origin": "https://getnada.com", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", "Accept": "*/*", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "same-origin", "Referer": "https://getnada.com/msg", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en-US,en;q=0.9"} 68 | requests.delete(delete_url, headers=delete_headers, cookies=delete_cookies, verify=False, timeout=30) 69 | else: 70 | None 71 | except: 72 | None 73 | 74 | if __name__ == '__main__': 75 | print (''' 76 | ╔═╗┌─┐┌─┐┌┐┌╦═╗┌─┐┬ ┌─┐┬ ┬╔╦╗┌─┐┌─┐┬┌─┐ 77 | ║ ║├─┘├┤ │││╠╦╝├┤ │ ├─┤└┬┘║║║├─┤│ ┬││ 78 | ╚═╝┴ └─┘┘└┘╩╚═└─┘┴─┘┴ ┴ ┴ ╩ ╩┴ ┴└─┘┴└─┘ 79 | -- keep em closed -- 80 | ''') 81 | parser = argparse.ArgumentParser() 82 | parser.add_argument("-l", "--list", help="Domain List") 83 | parser.add_argument("-t", "--target", help="Single Host") 84 | parser.add_argument("-p", "--port", help="Define 465/587", type=int) 85 | parser.add_argument("-o", "--output", help="Output of Results") 86 | parser.add_argument("-T", "--threads", help="No. of threads", default=10, type=int) 87 | args = parser.parse_args() 88 | if args.target: 89 | checker(args.target) 90 | elif args.list: 91 | lineList = [line.rstrip('\n') for line in open(args.list)] 92 | processcount = args.threads 93 | with Pool(processes=processcount) as p: 94 | if args.output: 95 | max_ = (len(lineList)) 96 | with tqdm(total=max_) as pbar: 97 | for i, _ in tqdm(enumerate(p.imap_unordered(checker, lineList))): 98 | pbar.update() 99 | print('\n') 100 | else: 101 | p.map(checker, lineList) 102 | print('\n') 103 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | tqdm 2 | argparse 3 | -------------------------------------------------------------------------------- /screencast.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bl4ckmamb4/OpenRelayMagic/324621daad92a9fe527086078fc379c66e6888e8/screencast.gif --------------------------------------------------------------------------------