squatcop 0.1.0.dev

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 875c451126a8c25e0cddec24ed0a13841e5401a2
4
+ data.tar.gz: 14c2547e41ced0e43b8cd7710332487812eeea87
5
+ SHA512:
6
+ metadata.gz: f2b7aad9855878c61e1544900e5d8d4e8213b641814a75ff43e4439fa622649f5395c9d0d298fffc319b787b96ef3b1838dbe77f74abafc35ddac5eb9c32d9c0
7
+ data.tar.gz: bcd773a061007a9e7e1ceac71f3b8d5cf3f3f30443238bdb0128bcaf6c6055b27b504363322035066d7b64eda5a508480e7875fa05ec6001068b272872e09c13
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2017, Michelle Pellon <mpellon@conroeisd.net>
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,4 @@
1
+ # squatcop
2
+
3
+ SquatCop finds similar-looking domains that your adversaries can use to attack
4
+ you via typo-squatting, phishing attacks, fraud and corporate espionage.
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ require 'squatcop/version'
4
+ require 'squatcop/fuzzer'
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ module SquatCop
4
+ #
5
+ module Constants
6
+ VOWELS = ['a', 'e', 'i', 'o', 'u']
7
+ end # module Constants
8
+ end # module SquatCop
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ # Standard library dependencies.
4
+ require 'set'
5
+
6
+ # Third-party dependencies.
7
+ require 'connection_pool'
8
+ require 'parallel'
9
+ require 'public_suffix'
10
+ require 'whois'
11
+ require 'whois-parser'
12
+
13
+ # Internal dependencies.
14
+ require 'squatcop/constants'
15
+ require 'squatcop/result'
16
+
17
+ module SquatCop
18
+ class InvalidDomainError < StandardError
19
+ end # class InvalidDomainError
20
+
21
+ #
22
+ class Fuzzer
23
+
24
+ attr_reader :domain
25
+
26
+ attr_reader :tld
27
+
28
+ attr_reader :nthreads
29
+
30
+ attr_reader :pqueue
31
+
32
+ private
33
+
34
+ def initialize(_domain, _nthread = 1)
35
+ raise InvalidDomainError unless PublicSuffix.valid?(_domain)
36
+ @domain = PublicSuffix.parse(_domain).sld
37
+ @tld = PublicSuffix.parse(_domain).tld
38
+ @nthreads = _nthread
39
+ @pqueue = Set.new
40
+ end # def initialize
41
+
42
+ def run
43
+ addition
44
+ vowel_swap
45
+ fill_whois
46
+ pp_json_results
47
+ end # def run
48
+
49
+ def fill_whois
50
+ # Rate limit whois server lookups.
51
+ $whois = ConnectionPool.new(size: @nthreads) {
52
+ Whois::Client.new
53
+ }
54
+
55
+ Parallel.each(@pqueue, in_threads: @nthreads) do |record|
56
+ $whois.with do |conn|
57
+ begin
58
+ whois_result = conn.lookup(record.fqdn)
59
+ parsed = whois_result.parser
60
+ record.registered = true if parsed.registered?
61
+ rescue Exception => e
62
+ puts "Error on whois lookup - #{record.fqdn} - #{e}"
63
+ end
64
+ end
65
+ end
66
+ end # def fill_whois
67
+
68
+ def pp_json_results
69
+ @pqueue.each do |record|
70
+ puts record.to_json
71
+ end
72
+ end # def pp_json_results
73
+
74
+ def vowel_swap
75
+ Parallel.each((0..@domain.length - 1), in_threads: @nthreads) do |i|
76
+ SquatCop::Constants::VOWELS.each do |vowel|
77
+ if SquatCop::Constants::VOWELS.include?(@domain[i])
78
+ @pqueue.add(Result.new((@domain[0..i-1] + vowel + @domain[i+1..@domain.length - 1]) + ".#{@tld}", 'vowel-swap'))
79
+ end
80
+ end
81
+ end
82
+ end # def vowel_swap
83
+
84
+ def addition
85
+ Parallel.each((97..122), in_threads: @nthreads) do |i|
86
+ @pqueue.add(Result.new(@domain + i.chr + ".#{@tld}", 'addition'))
87
+ end
88
+ end # def addition
89
+
90
+ public(:initialize, :run)
91
+ end # class Fuzzer
92
+ end # module SquatCop
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require 'json'
4
+
5
+ module SquatCop
6
+ #
7
+ class Result
8
+
9
+ attr_accessor :fqdn
10
+
11
+ attr_reader :method
12
+
13
+ attr_accessor :registered
14
+
15
+ private
16
+
17
+ def initialize(fqdn, method)
18
+ @fqdn = fqdn
19
+ @method = method
20
+ @registered = false
21
+ end # def initialize
22
+
23
+ def to_json
24
+ {
25
+ :fqdn => @fqdn,
26
+ :method => @method,
27
+ :registered => @registered
28
+ }.to_json
29
+ end # def to_json
30
+
31
+ public(:initialize, :fqdn, :registered, :to_json)
32
+ end # class Result
33
+ end # module SquatCop
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module SquatCop
4
+ # This module holds the SquatCop version information.
5
+ module Version
6
+ STRING = '0.1.0.dev'.freeze
7
+
8
+ module_function
9
+
10
+ def version(debug = false)
11
+ if debug
12
+ format(STRING, RUBY_ENGINE, RUBY_VERSION, RUBY_PLATFORM)
13
+ else
14
+ STRING
15
+ end
16
+ end # def version
17
+ end # module Version
18
+ end # module SquatCop
metadata ADDED
@@ -0,0 +1,251 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: squatcop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.dev
5
+ platform: ruby
6
+ authors:
7
+ - Michelle Pellon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.4.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.4.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: connection_pool
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.2'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.2.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.2'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.2.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: paint
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.0.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 2.0.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: parallel
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.10'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.10.0
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.10'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.10.0
93
+ - !ruby/object:Gem::Dependency
94
+ name: public_suffix
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '2.0'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 2.0.5
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '2.0'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 2.0.5
113
+ - !ruby/object:Gem::Dependency
114
+ name: whois
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '4.0'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 4.0.1
123
+ type: :runtime
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '4.0'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 4.0.1
133
+ - !ruby/object:Gem::Dependency
134
+ name: whois-parser
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '1.0'
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 1.0.0
143
+ type: :runtime
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '1.0'
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 1.0.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '12.0'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 12.0.0
163
+ type: :development
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '12.0'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 12.0.0
173
+ - !ruby/object:Gem::Dependency
174
+ name: rspec
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '3.5'
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: 3.5.0
183
+ type: :development
184
+ prerelease: false
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: '3.5'
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: 3.5.0
193
+ - !ruby/object:Gem::Dependency
194
+ name: rubocop
195
+ requirement: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - "~>"
198
+ - !ruby/object:Gem::Version
199
+ version: '0.46'
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: 0.46.0
203
+ type: :development
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: '0.46'
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: 0.46.0
213
+ description: A typo-squatting and phishing domain detector.
214
+ email:
215
+ - opensource@michaelpellon.com
216
+ executables: []
217
+ extensions: []
218
+ extra_rdoc_files: []
219
+ files:
220
+ - LICENSE
221
+ - README.md
222
+ - lib/squatcop.rb
223
+ - lib/squatcop/constants.rb
224
+ - lib/squatcop/fuzzer.rb
225
+ - lib/squatcop/result.rb
226
+ - lib/squatcop/version.rb
227
+ homepage: https://github.com/michellepellon/squatmap
228
+ licenses:
229
+ - ISC
230
+ metadata: {}
231
+ post_install_message:
232
+ rdoc_options: []
233
+ require_paths:
234
+ - lib
235
+ required_ruby_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: 2.0.0
240
+ required_rubygems_version: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - ">"
243
+ - !ruby/object:Gem::Version
244
+ version: 1.3.1
245
+ requirements: []
246
+ rubyforge_project:
247
+ rubygems_version: 2.5.1
248
+ signing_key:
249
+ specification_version: 4
250
+ summary: A typo-squatting and phishing domain detector.
251
+ test_files: []