Ready to Start Your Career?

By: P3t3rp4rk3r
March 25, 2018
Catch the Phishy Domains – Python & Slack Integration

By: P3t3rp4rk3r
March 25, 2018
Hey Guys, Today I just wanna discuss about catch the phishing domains before it was targeted to your organization.In Cybersecurity Defenders prospective, Everyone wants to detect something malicious /weird before it exploited. So, I have seen/worked lot of pentesting engagements on different organizations. 70% cases are Red Teamers successfully exploits client machine through phishing only. In lot of companies /organizations/ enterprises are not concern about phishing threats on their employees.Bad guys/hackers are very smart. If they target specific organization, they will create phishing campaigns before sending phishing emails on specific organization employees. These Phishy websites looks legit website with SSL certs.As a part of Security Defense, If we monitor the SSL Certs of all of domains using CTL (Certificate Transparency Log) / CertStream. We can able to detect phishy websites related to your organization in very less time. If you want to implement this in your organization, I will give brief idea on how can we deploy and monitor & integrate with slack.Installation & Configuration ProcedureBasic Requirements
Python Dependencies (pip install -r requirements.txt)
domains.py
catch_phish.py
Script Execution:
Slack Alerts: *Red color ones critical ones*
https://crazybulletctfwriteups.wordpress.com/2018/03/17/catch-the-phishy-domains-python-slack-integration/Thanks for reading.
1 2 3 4 | Linux VM (2GB-RAM /20GB-HDD ) Python - (Dependencies) Slack API Access Internet Access |
1 2 3 4 5 6 7 | termcolor = = 1.1 . 0 certstream = = 1.8 entropy = = 0.10 tqdm = = 4.19 . 4 tld = = 0.7 . 9 python_Levenshtein = = 0.12 . 0 slackclient |
- Create a folder “phishdomain_slack”
- create domains.py & catch_phish.py
- modify the keywords.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | keywords = { #Corporate/Organization/Enterprise_Domains 'paypal' : 80 , #ex: google 'facebook' : 80 , #ex: yahoo } #Top_20_top_level_domains // If you want add more tlds = [ '.ga' , '.gq' , '.ml' , '.cf' , '.tk' , '.xyz' , '.pw' , '.cc' , '.club' , '.work' , '.top' , '.support' , '.bank' , '.info' , '.study' , '.party' , '.click' , '.country' , '.stream' , '.gdn' , '.mom' , '.xin' , '.kim' , '.men' , '.loan' , '.download' , '.racing' , '.online' , '.center' , '.ren' , '.gb' , '.win' , '.review' , '.vip' , '.party' , '.tech' , '.science' , '.business' ] |
- Put same keywords in list ‘l’.
- Create slack workspace with email.
- Create a new app and generate oauth key.
- Configure channel id & username
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #!/usr/bin/env python import re import certstream import tqdm import entropy from tld import get_tld from Levenshtein import distance from termcolor import colored, cprint from domains import keywords, tlds from slackclient import SlackClient log_suspicious = 'phishing_enterprise_domains.log' pbar = tqdm.tqdm(desc = 'certificate_update' , unit = 'cert' ) l = [ 'paypal' , 'facebook' ] #same keywords def score_domain(domain): score = 0 for t in tlds: if domain.endswith(t): score + = 20 # Remove initial '*.' for wildcard certificates bug if domain.startswith( '*.' ): domain = domain[ 2 :] # Removing TLD to catch inner TLD in subdomain try : res = get_tld(domain, as_object = True , fail_silently = True , fix_protocol = True ) domain = '.' .join([res.subdomain, res.domain]) except : pass words_in_domain = re.split( \"\\W+\" , domain) # Remove initial '*.' for wildcard certificates bug if domain.startswith( '*.' ): domain = domain[ 2 :] # ie. detect fake .com if words_in_domain[ 0 ] in [ 'com' , 'net' , 'org' ]: score + = 10 # Testing keywords for word in keywords.keys(): if word in domain: score + = keywords[word] # Higer entropy is kind of suspicious score + = int ( round (entropy.shannon_entropy(domain) * 50 )) # Testing Levenshtein distance for strong keywords (>= 70 points) (ie. paypol) for key in [k for (k,s) in keywords.items() if s > = 70 ]: # Removing too generic keywords (ie. mail.domain.com) for word in [w for w in words_in_domain if w not in [ 'email' , 'mail' , 'cloud' ]]: if distance( str (word), str (key)) = = 1 : score + = 70 # Lots of '-' if 'xn--' not in domain and domain.count( '-' ) > = 4 : score + = domain.count( '-' ) * 3 # Deeply nested subdomains if domain.count( '.' ) > = 3 : score + = domain.count( '.' ) * 3 return score \"\"\" Slack Integration for Alerting \"\"\" def slack_message(msg): token = 'xoxp-326xxxxxxx-xxxxxxx-xxxxxxxxxx-xxxxxxxxxxxxx' sc = SlackClient(token) sc.api_call( 'chat.postMessage' , channel = 'Cxxxxxxxx' , text = msg, username = 'santhoshxxxxx' , icon_emoji = ':robot_face:' ) def callback(message, context): \"\"\"Callback handler for certstream events.\"\"\" if message[ 'message_type' ] = = \"heartbeat\" : return if message[ 'message_type' ] = = \"certificate_update\" : all_domains = message[ 'data' ][ 'leaf_cert' ][ 'all_domains' ] for domain in all_domains: pbar.update( 1 ) score = score_domain(domain.lower()) # If issued from a free CA = more suspicious if \"Let's Encrypt\" in message['data '][' chain '][0][' subject '][' aggregated']: score + = 10 if score > = 100 : tqdm.tqdm.write( \"[!] Suspicious: \" \"{} (score={})\" . format (colored(domain, 'red' , attrs = [ 'underline' , 'bold' ]), score)) elif score > = 90 : tqdm.tqdm.write( \"[!] Suspicious: \" \"{} (score={})\" . format (colored(domain, 'red' , attrs = [ 'underline' ]), score)) elif score > = 80 : tqdm.tqdm.write( \"[!] Likely : \" \"{} (score={})\" . format (colored(domain, 'yellow' , attrs = [ 'underline' ]), score)) elif score > = 65 : tqdm.tqdm.write( \"[+] Potential : \" \"{} (score={})\" . format (colored(domain, attrs = [ 'underline' ]), score)) if score > = 75 : if any (x in domain for x in l): slack_message(domain) else : print \"[+] No alert.\" with open (log_suspicious, 'a' ) as f: f.write( \"{}\\" . format (domain)) certstream.listen_for_events(callback) |

