moby.rb 1.0.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 +7 -0
- data/CHANGES.txt +32 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +172 -0
- data/Rakefile +22 -0
- data/bin/moby +67 -0
- data/lib/File/self.collect.rb +10 -0
- data/lib/Moby/Backends/MechanizeBackend.rb +157 -0
- data/lib/Moby/Backends/SeleniumBackend.rb +236 -0
- data/lib/Moby/Configuration.rb +113 -0
- data/lib/Moby/RandomInputGenerator.rb +49 -0
- data/lib/Moby/VERSION.rb +6 -0
- data/lib/Moby.rb +179 -0
- data/lib/Selenium/WebDriver/Driver/Attempt/attempt.rb +18 -0
- data/lib/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb +13 -0
- data/lib/Thoran/File/SelfCollect/self.collect.rb +22 -0
- data/lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt.rb +53 -0
- data/lib/Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb +39 -0
- data/moby.gemspec +51 -0
- data/test/Moby/VERSION_test.rb +23 -0
- data/test/moby_test.rb +295 -0
- data/test/test_helper.rb +36 -0
- metadata +153 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb
|
|
2
|
+
# Thoran::Selenium::WebDriver::SearchContext::ElementPresentQ.element_present?
|
|
3
|
+
|
|
4
|
+
# 20200418
|
|
5
|
+
# 0.0.0
|
|
6
|
+
|
|
7
|
+
# Examples:
|
|
8
|
+
# 1. driver.element_present?(:xpath, '//a[@id="submit"]')
|
|
9
|
+
# 2. driver.element_present?(:id, @logout_button_id)
|
|
10
|
+
|
|
11
|
+
# Changes:
|
|
12
|
+
# 1. + Thoran namespace.
|
|
13
|
+
|
|
14
|
+
module Thoran
|
|
15
|
+
module Selenium
|
|
16
|
+
module WebDriver
|
|
17
|
+
module SearchContext
|
|
18
|
+
module ElementPresentQ
|
|
19
|
+
|
|
20
|
+
def element_present?(selector_type, selector)
|
|
21
|
+
bridge.find_element_by(selector_type, selector)
|
|
22
|
+
true
|
|
23
|
+
rescue ::Selenium::WebDriver::Error::NoSuchElementError
|
|
24
|
+
false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Selenium
|
|
34
|
+
module WebDriver
|
|
35
|
+
class Driver
|
|
36
|
+
include Thoran::Selenium::WebDriver::SearchContext::ElementPresentQ
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/moby.gemspec
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# moby.gemspec
|
|
2
|
+
|
|
3
|
+
require_relative './lib/Moby/VERSION'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'moby.rb'
|
|
7
|
+
|
|
8
|
+
spec.version = Moby::VERSION
|
|
9
|
+
spec.date = '2026-01-08'
|
|
10
|
+
|
|
11
|
+
spec.summary = "Moby is a credentials poisoning tool which floods phishing forms with fake credentials."
|
|
12
|
+
spec.description = "Sometimes when they go fishing, they get a whale and it sinks their boat. Moby is a counter-phishing tool that floods phishing websites with fake login credentials, making harvested data useless."
|
|
13
|
+
|
|
14
|
+
spec.author = 'thoran'
|
|
15
|
+
spec.email = 'code@thoran.com'
|
|
16
|
+
spec.homepage = 'https://github.com/thoran/moby'
|
|
17
|
+
spec.license = 'MIT'
|
|
18
|
+
|
|
19
|
+
spec.required_ruby_version = ">= 2.5.0"
|
|
20
|
+
|
|
21
|
+
spec.add_dependency('mechanize', '~> 2')
|
|
22
|
+
spec.add_dependency('switches.rb', '~> 0')
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency('minitest')
|
|
25
|
+
spec.add_development_dependency('minitest-spec-context')
|
|
26
|
+
spec.add_development_dependency('rake')
|
|
27
|
+
spec.add_development_dependency('webmock')
|
|
28
|
+
|
|
29
|
+
spec.files = Dir[
|
|
30
|
+
'bin/*',
|
|
31
|
+
'lib/**/*.rb',
|
|
32
|
+
'test/**/*.rb',
|
|
33
|
+
'CHANGES.txt',
|
|
34
|
+
'Gemfile',
|
|
35
|
+
'LICENSE.txt',
|
|
36
|
+
'moby.gemspec',
|
|
37
|
+
'Rakefile',
|
|
38
|
+
'README.md',
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
spec.bindir = 'bin'
|
|
42
|
+
spec.executables = ['moby']
|
|
43
|
+
spec.require_paths = ['lib']
|
|
44
|
+
|
|
45
|
+
spec.metadata = {
|
|
46
|
+
"bug_tracker_uri" => "https://github.com/thoran/moby/issues",
|
|
47
|
+
"changelog_uri" => "https://github.com/thoran/moby/blob/main/CHANGES.txt",
|
|
48
|
+
"source_code_uri" => "https://github.com/thoran/moby",
|
|
49
|
+
"documentation_uri" => "https://github.com/thoran/moby/blob/main/README.md"
|
|
50
|
+
}
|
|
51
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# test/Moby/VERSION_test.rb
|
|
2
|
+
|
|
3
|
+
require_relative '../test_helper'
|
|
4
|
+
|
|
5
|
+
describe Moby do
|
|
6
|
+
describe "VERSION" do
|
|
7
|
+
it "has VERSION constant" do
|
|
8
|
+
_(defined?(Moby::VERSION)).wont_be_nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "version is a string" do
|
|
12
|
+
_(Moby::VERSION).must_be_kind_of(String)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "version follows semver pattern" do
|
|
16
|
+
_(Moby::VERSION).must_match(/\d+\.\d+\.\d+/)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "version is 1.0.0" do
|
|
20
|
+
_(Moby::VERSION).must_equal('1.0.0')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/test/moby_test.rb
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# test/moby_test.rb
|
|
2
|
+
|
|
3
|
+
require_relative './test_helper'
|
|
4
|
+
|
|
5
|
+
describe Moby do
|
|
6
|
+
let(:url){'https://phishing.example.com/login'}
|
|
7
|
+
let(:moby){Moby.new(url: url)}
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
WebMock.disable_net_connect!
|
|
11
|
+
|
|
12
|
+
# Stub the login page
|
|
13
|
+
stub_request(:get, url)
|
|
14
|
+
.to_return(
|
|
15
|
+
status: 200,
|
|
16
|
+
body: TestFixtures::SIMPLE_LOGIN_FORM,
|
|
17
|
+
headers: {'Content-Type' => 'text/html'}
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Stub form submission
|
|
21
|
+
stub_request(:post, 'https://phishing.example.com/login')
|
|
22
|
+
.to_return(status: 200, body: 'Success')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after do
|
|
26
|
+
WebMock.reset!
|
|
27
|
+
WebMock.allow_net_connect!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe "initialization" do
|
|
31
|
+
it "accepts url parameter" do
|
|
32
|
+
_(moby.url).must_equal(url)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "sets default form_number to 0" do
|
|
36
|
+
_(moby.form_number).must_equal(0)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "sets default username_field_name to 'username'" do
|
|
40
|
+
_(moby.username_field_name).must_equal('username')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "sets default password_field_name to 'password'" do
|
|
44
|
+
_(moby.password_field_name).must_equal('password')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "sets default username_field_number to 0" do
|
|
48
|
+
_(moby.username_field_number).must_equal(0)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "sets default password_field_number to 1" do
|
|
52
|
+
_(moby.password_field_number).must_equal(1)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "accepts form_name parameter" do
|
|
56
|
+
m = Moby.new(url: url, form_name: 'login')
|
|
57
|
+
|
|
58
|
+
_(m.form_name).must_equal('login')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "accepts username_hostname parameter" do
|
|
62
|
+
m = Moby.new(url: url, username_hostname: 'example.com')
|
|
63
|
+
|
|
64
|
+
_(m.username_hostname).must_equal('example.com')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "accepts username_is_email_address parameter" do
|
|
68
|
+
m = Moby.new(url: url, username_is_email_address: true)
|
|
69
|
+
|
|
70
|
+
_(m.username_is_email_address).must_equal(true)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "mechanize setup" do
|
|
75
|
+
it "creates Mechanize instance lazily" do
|
|
76
|
+
mech = moby.instance_variable_get(:@mechanize)
|
|
77
|
+
|
|
78
|
+
_(mech).must_be_nil
|
|
79
|
+
|
|
80
|
+
moby.send(:mechanize)
|
|
81
|
+
mech = moby.instance_variable_get(:@mechanize)
|
|
82
|
+
|
|
83
|
+
_(mech).must_be_instance_of(Mechanize)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "reuses same mechanize instance" do
|
|
87
|
+
mech1 = moby.send(:mechanize)
|
|
88
|
+
mech2 = moby.send(:mechanize)
|
|
89
|
+
|
|
90
|
+
_(mech1).must_be_same_as(mech2)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe "page loading" do
|
|
95
|
+
it "loads the target URL" do
|
|
96
|
+
page = moby.send(:page)
|
|
97
|
+
|
|
98
|
+
_(page).must_be_instance_of(Mechanize::Page)
|
|
99
|
+
assert_requested(:get, url, times: 1)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "reuses loaded page" do
|
|
103
|
+
page1 = moby.send(:page)
|
|
104
|
+
page2 = moby.send(:page)
|
|
105
|
+
|
|
106
|
+
_(page1).must_be_same_as(page2)
|
|
107
|
+
assert_requested(:get, url, times: 1)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "handles meta refresh redirects" do
|
|
111
|
+
redirect_body = '<html><head><meta http-equiv="Refresh" content="0; url=https://phishing.example.com/real-login"></head></html>'
|
|
112
|
+
|
|
113
|
+
stub_request(:get, url)
|
|
114
|
+
.to_return(status: 200, body: redirect_body, headers: {'Content-Type' => 'text/html'})
|
|
115
|
+
|
|
116
|
+
stub_request(:get, 'https://phishing.example.com/real-login')
|
|
117
|
+
.to_return(status: 200, body: TestFixtures::SIMPLE_LOGIN_FORM, headers: {'Content-Type' => 'text/html'})
|
|
118
|
+
|
|
119
|
+
m = Moby.new(url: url)
|
|
120
|
+
page = m.send(:page)
|
|
121
|
+
|
|
122
|
+
assert_requested(:get, url, times: 1)
|
|
123
|
+
assert_requested(:get, 'https://phishing.example.com/real-login', times: 1)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "form finding" do
|
|
128
|
+
describe "finding by name" do
|
|
129
|
+
let(:moby) do
|
|
130
|
+
Moby.new(url: url, form_name: 'login')
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "finds form by name when form_name is set" do
|
|
134
|
+
moby.send(:page)
|
|
135
|
+
form = moby.send(:form)
|
|
136
|
+
|
|
137
|
+
_(form).must_be_instance_of(Mechanize::Form)
|
|
138
|
+
_(form.name).must_equal('login')
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe "finding by number" do
|
|
143
|
+
let(:moby) do
|
|
144
|
+
Moby.new(url: 'https://multi.example.com/page', form_number: 1)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "finds form by number when form_number is set" do
|
|
148
|
+
stub_request(:get, 'https://multi.example.com/page')
|
|
149
|
+
.to_return(
|
|
150
|
+
status: 200,
|
|
151
|
+
body: TestFixtures::MULTIPLE_FORMS,
|
|
152
|
+
headers: {'Content-Type' => 'text/html'}
|
|
153
|
+
)
|
|
154
|
+
moby.send(:page)
|
|
155
|
+
form = moby.send(:form)
|
|
156
|
+
|
|
157
|
+
_(form).must_be_instance_of(Mechanize::Form)
|
|
158
|
+
_(form.node['id']).must_equal('login_form')
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "deafult form" do
|
|
163
|
+
it "defaults to first form" do
|
|
164
|
+
moby.send(:page)
|
|
165
|
+
form = moby.send(:form)
|
|
166
|
+
|
|
167
|
+
_(form).must_be_instance_of(Mechanize::Form)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe "field finding" do
|
|
173
|
+
describe "finding by name" do
|
|
174
|
+
let(:moby) do
|
|
175
|
+
Moby.new(url: url, form_name: 'login', username_field_name: 'username', password_field_name: 'password')
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "finds username field by name" do
|
|
179
|
+
moby.send(:page)
|
|
180
|
+
moby.send(:form)
|
|
181
|
+
field = moby.send(:username_field)
|
|
182
|
+
|
|
183
|
+
_(field.name).must_equal('username')
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it "finds password field by name" do
|
|
187
|
+
moby.send(:page)
|
|
188
|
+
moby.send(:form)
|
|
189
|
+
field = moby.send(:password_field)
|
|
190
|
+
|
|
191
|
+
_(field.name).must_equal('password')
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe "finding by number" do
|
|
196
|
+
let(:moby) do
|
|
197
|
+
Moby.new(url: url, username_field_number: 0, password_field_number: 1)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "finds username field by number" do
|
|
201
|
+
moby.send(:page)
|
|
202
|
+
moby.send(:form)
|
|
203
|
+
field = moby.send(:username_field)
|
|
204
|
+
|
|
205
|
+
_(field).wont_be_nil
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it "finds password field by number" do
|
|
209
|
+
moby.send(:page)
|
|
210
|
+
moby.send(:form)
|
|
211
|
+
field = moby.send(:password_field)
|
|
212
|
+
|
|
213
|
+
_(field).wont_be_nil
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
describe "#username" do
|
|
219
|
+
it "generates random username" do
|
|
220
|
+
username = moby.send(:username)
|
|
221
|
+
|
|
222
|
+
_(username).must_be_kind_of(String)
|
|
223
|
+
_(username.length).must_be(:>, 0)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "generates email address when username_is_email_address is true" do
|
|
227
|
+
m = Moby.new(url: url, username_is_email_address: true)
|
|
228
|
+
username = m.send(:username)
|
|
229
|
+
|
|
230
|
+
_(username).must_match(/@/)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it "generates email with custom hostname" do
|
|
234
|
+
m = Moby.new(url: url, username_hostname: 'example.com')
|
|
235
|
+
username = m.send(:username)
|
|
236
|
+
|
|
237
|
+
_(username).must_match(/@example\.com$/)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
it "generates different usernames" do
|
|
242
|
+
usernames = 10.times.map{moby.send(:username)}
|
|
243
|
+
|
|
244
|
+
_(usernames.uniq.length).must_be(:>, 1)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
describe "#password" do
|
|
249
|
+
it "generates random password" do
|
|
250
|
+
password = moby.send(:password)
|
|
251
|
+
|
|
252
|
+
_(password).must_be_kind_of(String)
|
|
253
|
+
_(password.length).must_be(:>, 0)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe "#user_agent" do
|
|
258
|
+
it "returns random user agent when not set" do
|
|
259
|
+
agent = moby.send(:user_agent)
|
|
260
|
+
|
|
261
|
+
_(agent).must_be_kind_of(String)
|
|
262
|
+
_(agent).wont_equal('Mechanize')
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "returns set user agent when provided" do
|
|
266
|
+
m = Moby.new(url: url, user_agent: 'CustomAgent')
|
|
267
|
+
|
|
268
|
+
_(m.send(:user_agent)).must_equal('CustomAgent')
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it "generates different random agents" do
|
|
272
|
+
agents = 10.times.map{Moby.new(url: url).send(:user_agent)}
|
|
273
|
+
|
|
274
|
+
_(agents.uniq.length).must_be(:>, 1)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
describe "#username_is_email_address?" do
|
|
279
|
+
it "returns true when username_is_email_address is set" do
|
|
280
|
+
m = Moby.new(url: url, username_is_email_address: true)
|
|
281
|
+
|
|
282
|
+
_(m.send(:username_is_email_address?)).must_equal(true)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "returns true when username_hostname is set" do
|
|
286
|
+
m = Moby.new(url: url, username_hostname: 'example.com')
|
|
287
|
+
|
|
288
|
+
_(m.send(:username_is_email_address?)).wont_be_nil
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "returns false by default" do
|
|
292
|
+
_(moby.send(:username_field_name)).must_equal('username')
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# test/test_helper.rb
|
|
2
|
+
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require 'minitest-spec-context'
|
|
5
|
+
require 'webmock/minitest'
|
|
6
|
+
|
|
7
|
+
require_relative '../lib/moby'
|
|
8
|
+
|
|
9
|
+
module TestFixtures
|
|
10
|
+
SIMPLE_LOGIN_FORM = <<~HTML
|
|
11
|
+
<html>
|
|
12
|
+
<body>
|
|
13
|
+
<form name="login" action="/login" method="post">
|
|
14
|
+
<input type="text" name="username" />
|
|
15
|
+
<input type="password" name="password" />
|
|
16
|
+
<input type="submit" value="Login" />
|
|
17
|
+
</form>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
20
|
+
HTML
|
|
21
|
+
|
|
22
|
+
MULTIPLE_FORMS = <<~HTML
|
|
23
|
+
<html>
|
|
24
|
+
<body>
|
|
25
|
+
<form name="search">
|
|
26
|
+
<input type="text" name="q" />
|
|
27
|
+
</form>
|
|
28
|
+
<form id="login_form">
|
|
29
|
+
<input type="email" name="username" id="user_email" />
|
|
30
|
+
<input type="password" name="password" id="user_password" />
|
|
31
|
+
<button type="submit">Submit</button>
|
|
32
|
+
</form>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
35
|
+
HTML
|
|
36
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: moby.rb
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- thoran
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-01-08 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: mechanize
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: switches.rb
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: minitest
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: minitest-spec-context
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rake
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: webmock
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
description: Sometimes when they go fishing, they get a whale and it sinks their boat.
|
|
97
|
+
Moby is a counter-phishing tool that floods phishing websites with fake login credentials,
|
|
98
|
+
making harvested data useless.
|
|
99
|
+
email: code@thoran.com
|
|
100
|
+
executables:
|
|
101
|
+
- moby
|
|
102
|
+
extensions: []
|
|
103
|
+
extra_rdoc_files: []
|
|
104
|
+
files:
|
|
105
|
+
- CHANGES.txt
|
|
106
|
+
- Gemfile
|
|
107
|
+
- LICENSE.txt
|
|
108
|
+
- README.md
|
|
109
|
+
- Rakefile
|
|
110
|
+
- bin/moby
|
|
111
|
+
- lib/File/self.collect.rb
|
|
112
|
+
- lib/Moby.rb
|
|
113
|
+
- lib/Moby/Backends/MechanizeBackend.rb
|
|
114
|
+
- lib/Moby/Backends/SeleniumBackend.rb
|
|
115
|
+
- lib/Moby/Configuration.rb
|
|
116
|
+
- lib/Moby/RandomInputGenerator.rb
|
|
117
|
+
- lib/Moby/VERSION.rb
|
|
118
|
+
- lib/Selenium/WebDriver/Driver/Attempt/attempt.rb
|
|
119
|
+
- lib/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb
|
|
120
|
+
- lib/Thoran/File/SelfCollect/self.collect.rb
|
|
121
|
+
- lib/Thoran/Selenium/WebDriver/Driver/Attempt/attempt.rb
|
|
122
|
+
- lib/Thoran/Selenium/WebDriver/SearchContext/ElementPresentQ/element_presentQ.rb
|
|
123
|
+
- moby.gemspec
|
|
124
|
+
- test/Moby/VERSION_test.rb
|
|
125
|
+
- test/moby_test.rb
|
|
126
|
+
- test/test_helper.rb
|
|
127
|
+
homepage: https://github.com/thoran/moby
|
|
128
|
+
licenses:
|
|
129
|
+
- MIT
|
|
130
|
+
metadata:
|
|
131
|
+
bug_tracker_uri: https://github.com/thoran/moby/issues
|
|
132
|
+
changelog_uri: https://github.com/thoran/moby/blob/main/CHANGES.txt
|
|
133
|
+
source_code_uri: https://github.com/thoran/moby
|
|
134
|
+
documentation_uri: https://github.com/thoran/moby/blob/main/README.md
|
|
135
|
+
rdoc_options: []
|
|
136
|
+
require_paths:
|
|
137
|
+
- lib
|
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
|
+
requirements:
|
|
140
|
+
- - ">="
|
|
141
|
+
- !ruby/object:Gem::Version
|
|
142
|
+
version: 2.5.0
|
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
|
+
requirements:
|
|
145
|
+
- - ">="
|
|
146
|
+
- !ruby/object:Gem::Version
|
|
147
|
+
version: '0'
|
|
148
|
+
requirements: []
|
|
149
|
+
rubygems_version: 4.0.3
|
|
150
|
+
specification_version: 4
|
|
151
|
+
summary: Moby is a credentials poisoning tool which floods phishing forms with fake
|
|
152
|
+
credentials.
|
|
153
|
+
test_files: []
|