Home 0P3N Blog Catch the Phishy Domains – Python & Slack Integration
Ready to Start Your Career?
Create Free Account
P3t3rp4rk3r s profile image
By: P3t3rp4rk3r
March 25, 2018

Catch the Phishy Domains – Python & Slack Integration

By: P3t3rp4rk3r
March 25, 2018
P3t3rp4rk3r s profile image
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 
1
2
3
4
Linux VM (2GB-RAM/20GB-HDD)
Python - (Dependencies)
Slack API Access
Internet Access
Python Dependencies (pip install -r requirements.txt
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
domains.py 
  • 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'
]
catch_phish.py  
  • 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)
Script Execution: finaloutSlack Alerts: *Red color ones critical ones*slack_alerthttps://crazybulletctfwriteups.wordpress.com/2018/03/17/catch-the-phishy-domains-python-slack-integration/Thanks for reading.
Schedule Demo

Build your Cybersecurity or IT Career

Accelerate in your role, earn new certifications, and develop cutting-edge skills using the fastest growing catalog in the industry