phisher_phinder 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -4
- data/README.md +10 -9
- data/lib/phisher_phinder.rb +3 -0
- data/lib/phisher_phinder/command.rb +8 -1
- data/lib/phisher_phinder/contact_finder.rb +37 -0
- data/lib/phisher_phinder/display.rb +7 -1
- data/lib/phisher_phinder/extended_ip.rb +1 -1
- data/lib/phisher_phinder/tracing_report.rb +10 -2
- data/lib/phisher_phinder/version.rb +1 -1
- data/lib/phisher_phinder/whois_email_extractor.rb +19 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfb338171a5bca59a9682dfe8157475e7ac1a6283d9410a8367fdbe78fed0be1
|
4
|
+
data.tar.gz: db30dccf14c2184cd01f4cb27e4d0cc305fda0ddb0b58205a6e3a077893e1eae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 831b8c8a93dc8cf8105724960be8052c1aa47a16fb57336a683e9780b07ce89a72e2e081344826b5462582c1270ca3fcd8a359d8b5111f97c4925c37cd5c085e
|
7
|
+
data.tar.gz: c25e50d534e780eaeef883a8e6c4311c4c51176589ac80959adb880c0b9f190b5350dd752497f3b19eb8ede04c95bd527201cf18f5f96222890ba08893495dd9
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
phisher_phinder (0.
|
4
|
+
phisher_phinder (0.3.0)
|
5
5
|
dotenv (~> 2.7.5)
|
6
6
|
maxmind-geoip2 (~> 0.4.0)
|
7
7
|
nokogiri (~> 1.11.0)
|
@@ -61,10 +61,8 @@ GEM
|
|
61
61
|
http (~> 4.3)
|
62
62
|
maxmind-db (~> 1.1)
|
63
63
|
method_source (1.0.0)
|
64
|
-
mini_portile2 (2.5.0)
|
65
64
|
minitest (5.14.2)
|
66
|
-
nokogiri (1.11.0)
|
67
|
-
mini_portile2 (~> 2.5.0)
|
65
|
+
nokogiri (1.11.0-x86_64-linux)
|
68
66
|
racc (~> 1.4)
|
69
67
|
pry (0.13.1)
|
70
68
|
coderay (~> 1.1)
|
data/README.md
CHANGED
@@ -97,14 +97,14 @@ The output of PhisherPhinder will produce something similar to the below:
|
|
97
97
|
+-----------+---------------+------------------+
|
98
98
|
|
99
99
|
|
100
|
-
|
101
|
-
|
|
102
|
-
|
103
|
-
| Sender IP
|
104
|
-
|
105
|
-
| 10.0.0.1
|
106
|
-
| 10.0.0.2
|
107
|
-
|
100
|
+
+--------------+----------------------+-----------------------+--------------------------------+-----------------------+-----------------------+
|
101
|
+
| Trace |
|
102
|
+
+--------------+----------------------+-----------------------+--------------------------------+-----------------------+-----------------------+
|
103
|
+
| Sender IP | IP Contacts | Sender Host | Host Contacts | Advertised Sender | Recipient |
|
104
|
+
+--------------+----------------------+-----------------------+--------------------------------+-----------------------+-----------------------+
|
105
|
+
| 10.0.0.1 | abuse@hosttwo.zzz | host.test.zzz | support@test.zzz | dodgy.test.zzz | mx.google.com |
|
106
|
+
| 10.0.0.2 | abuse@hostone.zzz | | | dodgy.othertest.zzz | mail.hostthree.zzz |
|
107
|
+
+--------------+----------------------+-----------------------+--------------------------------+-----------------------+-----------------------+
|
108
108
|
|
109
109
|
```
|
110
110
|
|
@@ -116,7 +116,8 @@ be trusted.
|
|
116
116
|
|
117
117
|
The `Trace` secion shows a subset of the `Received` headers from the original (advertised, but not necessarily actual)
|
118
118
|
origin (the last entry in the table) to the last external server to process the email before the recipient's mail host
|
119
|
-
received the email.
|
119
|
+
received the email. The contacts are abuse contacts for the sender IP and the sender host as found in the results of a
|
120
|
+
WHOIS lookup. If this could not be resolved, these fields will be blank.
|
120
121
|
|
121
122
|
## Dependencies
|
122
123
|
1. [Maxmind GeoIP2 User Account](https://dev.maxmind.com/geoip/geoip2/web-services/) - pay as you go
|
data/lib/phisher_phinder.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require "phisher_phinder/version"
|
2
2
|
|
3
3
|
require 'maxmind/geoip2'
|
4
|
+
require 'whois-parser'
|
4
5
|
|
5
6
|
require_relative './phisher_phinder/command'
|
6
7
|
require_relative './phisher_phinder/display'
|
7
8
|
|
8
9
|
require_relative './phisher_phinder/body_hyperlink'
|
9
10
|
require_relative './phisher_phinder/cached_geoip_client'
|
11
|
+
require_relative './phisher_phinder/contact_finder'
|
12
|
+
require_relative './phisher_phinder/whois_email_extractor'
|
10
13
|
require_relative './phisher_phinder/null_lookup_client'
|
11
14
|
require_relative './phisher_phinder/null_response'
|
12
15
|
require_relative './phisher_phinder/geoip_ip_data'
|
@@ -13,7 +13,14 @@ module PhisherPhinder
|
|
13
13
|
end
|
14
14
|
ip_factory = PhisherPhinder::ExtendedIpFactory.new(geoip_client: lookup_client)
|
15
15
|
mail_parser = PhisherPhinder::MailParser::Parser.new(ip_factory, line_ending)
|
16
|
-
|
16
|
+
whois_client = Whois::Client.new
|
17
|
+
tracing_report = PhisherPhinder::TracingReport.new(
|
18
|
+
mail_parser.parse(contents),
|
19
|
+
PhisherPhinder::ContactFinder.new(
|
20
|
+
whois_client: whois_client,
|
21
|
+
extractor: PhisherPhinder::WhoisEmailExtractor.new
|
22
|
+
)
|
23
|
+
)
|
17
24
|
tracing_report.report
|
18
25
|
end
|
19
26
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PhisherPhinder
|
4
|
+
class ContactFinder
|
5
|
+
def initialize(whois_client:, extractor:)
|
6
|
+
@whois_client = whois_client
|
7
|
+
@extractor = extractor
|
8
|
+
end
|
9
|
+
|
10
|
+
def contacts_for(address)
|
11
|
+
whois_content = nil
|
12
|
+
begin
|
13
|
+
whois_content = case address
|
14
|
+
when ExtendedIp
|
15
|
+
@whois_client.lookup(address.ip_address.to_s).content
|
16
|
+
when String
|
17
|
+
hostname_parts = address.split('.')
|
18
|
+
whois_content = nil
|
19
|
+
until whois_content do
|
20
|
+
address = hostname_parts.join('.')
|
21
|
+
whois_record = @whois_client.lookup(address)
|
22
|
+
if whois_record.parser.available?
|
23
|
+
hostname_parts = hostname_parts[1..-1]
|
24
|
+
else
|
25
|
+
whois_content = whois_record.content
|
26
|
+
end
|
27
|
+
end
|
28
|
+
whois_content
|
29
|
+
end
|
30
|
+
rescue Whois::ServerNotFound
|
31
|
+
rescue Whois::AttributeNotImplemented
|
32
|
+
end
|
33
|
+
|
34
|
+
whois_content ? @extractor.abuse_contact_emails(whois_content) : []
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -32,14 +32,16 @@ module PhisherPhinder
|
|
32
32
|
data = input_data[:tracing].map do |entry|
|
33
33
|
[
|
34
34
|
entry[:sender][:ip],
|
35
|
+
display_email_addresses(entry[:sender_contact_details][:ip][:email]),
|
35
36
|
entry[:sender][:host],
|
37
|
+
display_email_addresses(entry[:sender_contact_details][:host][:email]),
|
36
38
|
entry[:advertised_sender] || entry[:helo],
|
37
39
|
entry[:recipient]
|
38
40
|
]
|
39
41
|
end
|
40
42
|
|
41
43
|
trace_table = Terminal::Table.new(
|
42
|
-
headings: ['Sender IP', 'Sender Host', 'Advertised Sender', 'Recipient'],
|
44
|
+
headings: ['Sender IP', 'IP Contacts', 'Sender Host', 'Host Contacts', 'Advertised Sender', 'Recipient'],
|
43
45
|
title: 'Trace',
|
44
46
|
rows: data
|
45
47
|
)
|
@@ -60,5 +62,9 @@ module PhisherPhinder
|
|
60
62
|
output << [description, input_data[:origin][type].join(', ')]
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
def display_email_addresses(email_addresses)
|
67
|
+
email_addresses.map { |address| address.gsub(/[,<>]/, '') }.join(', ')
|
68
|
+
end
|
63
69
|
end
|
64
70
|
end
|
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
module PhisherPhinder
|
4
4
|
class TracingReport
|
5
|
-
def initialize(mail)
|
5
|
+
def initialize(mail, contact_finder)
|
6
6
|
@mail = mail
|
7
|
+
@contact_finder = contact_finder
|
7
8
|
end
|
8
9
|
|
9
10
|
def report
|
@@ -34,7 +35,14 @@ module PhisherPhinder
|
|
34
35
|
|
35
36
|
def extract_tracing_headers(received_headers, latest_spf_entry)
|
36
37
|
start = received_headers[:received].find_index { |h| h[:sender][:ip] == ip_address(latest_spf_entry) }
|
37
|
-
received_headers[:received][start..-1]
|
38
|
+
received_headers[:received][start..-1].map do |h|
|
39
|
+
h.merge(
|
40
|
+
sender_contact_details: {
|
41
|
+
host: {email: @contact_finder.contacts_for(h[:sender][:host])},
|
42
|
+
ip: {email: @contact_finder.contacts_for(h[:sender][:ip])},
|
43
|
+
}
|
44
|
+
)
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def extract_origin_headers(headers)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PhisherPhinder
|
4
|
+
class WhoisEmailExtractor
|
5
|
+
def abuse_contact_emails(contents)
|
6
|
+
if contents =~ /OrgAbuseEmail/
|
7
|
+
contents.scan(/OrgAbuseEmail:\s+(\S+)/).flatten.uniq
|
8
|
+
elsif contents =~ /Abuse contact for .+? is '([^']+)'/
|
9
|
+
[$1]
|
10
|
+
elsif contents =~ /Registrar Abuse Contact Email:\s+([\S]+)/
|
11
|
+
[$1]
|
12
|
+
elsif contents =~ /(abuse@[\S]+)/
|
13
|
+
[$1]
|
14
|
+
else
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phisher_phinder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rory McKinley
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv
|
@@ -249,6 +249,7 @@ files:
|
|
249
249
|
- lib/phisher_phinder/body_hyperlink.rb
|
250
250
|
- lib/phisher_phinder/cached_geoip_client.rb
|
251
251
|
- lib/phisher_phinder/command.rb
|
252
|
+
- lib/phisher_phinder/contact_finder.rb
|
252
253
|
- lib/phisher_phinder/display.rb
|
253
254
|
- lib/phisher_phinder/expanded_data_processor.rb
|
254
255
|
- lib/phisher_phinder/extended_ip.rb
|
@@ -276,6 +277,7 @@ files:
|
|
276
277
|
- lib/phisher_phinder/simple_ip.rb
|
277
278
|
- lib/phisher_phinder/tracing_report.rb
|
278
279
|
- lib/phisher_phinder/version.rb
|
280
|
+
- lib/phisher_phinder/whois_email_extractor.rb
|
279
281
|
- phisher_phinder.gemspec
|
280
282
|
homepage: https://capefox.co
|
281
283
|
licenses:
|