squatcop 0.1.0.dev

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []