ruby_hashcat 0.1.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ path = File.dirname(__FILE__)
2
+ require "#{path}/hash"
@@ -0,0 +1,245 @@
1
+ path = File.dirname(__FILE__)
2
+ require "#{path}/tools"
3
+
4
+ ###########################################################################
5
+ # Author: Coleton Pierson #
6
+ # Company: Praetorian #
7
+ # Date: August 20, 2014 #
8
+ # Project: Ruby Hashcat #
9
+ # Description: Main parser class. Parses ocl stdout and pot file. #
10
+ ###########################################################################
11
+
12
+ module RubyHashcat
13
+ module Parse
14
+
15
+ ###########################################################################
16
+ # @method RubyHashcat::Parse.stdout(file) #
17
+ # @param file: [String] Path to oclHashcat stdout file #
18
+ # @description Parses the oclHashcat stdout file into hashes. #
19
+ # @return [Array][Hash] Array of Hashes with oclHashcat status. #
20
+ ###########################################################################
21
+ def self.stdout(file)
22
+ array = []
23
+ return array unless File.exists?(file)
24
+ placement = -1
25
+ string = []
26
+ File.open(file).each_line do |x|
27
+ string << x
28
+ end
29
+ string.each do |line|
30
+ if line.include?('Session.Name.')
31
+ placement += 1
32
+ array[placement] = {}
33
+ elsif placement < 0
34
+ next
35
+ elsif line.include?('Status.')
36
+ tmp = line.split(':')
37
+ array[placement][:status] = tmp[-1].chomp.strip
38
+ elsif line.include?('Rules.Type.')
39
+ tmp = line.split(':')
40
+ array[placement][:rules] = tmp[-1].chomp.strip
41
+ elsif line.include?('Input.Mode.')
42
+ tmp = line.split(':')
43
+ array[placement][:input] = tmp[-1].chomp.strip
44
+ elsif line.include?('Input.Base.')
45
+ # Label only used in combination attack
46
+ tmp = line.split(':')
47
+ array[placement][:input_base] = tmp[-1].chomp.strip
48
+ elsif line.include?('Input.Mod.')
49
+ # Label only used in combination attack
50
+ tmp = line.split(':')
51
+ array[placement][:input_mod] = tmp[-1].chomp.strip
52
+ elsif line.include?('Hash.Target.')
53
+ tmp = line.split(':')
54
+ array[placement][:target] = tmp[-1].chomp.strip
55
+ elsif line.include?('Hash.Type.')
56
+ tmp = line.split(':')
57
+ array[placement][:type] = tmp[-1].chomp.strip
58
+ elsif line.include?('Time.Started.')
59
+ tmp = line.split(':')
60
+ tmp.delete_at(0)
61
+ tmp = tmp.join(':')
62
+ array[placement][:started] = tmp.chomp.strip
63
+ elsif line.include?('Time.Estimated.')
64
+ tmp = line.split(':')
65
+ tmp.delete_at(0)
66
+ tmp = tmp.join(':')
67
+ array[placement][:estimated] = tmp.chomp.strip
68
+ elsif line.include?('Speed.GPU.')
69
+ # Must account for x amount of GPUs
70
+ tmp = line.split(':')
71
+ tmp[0].gsub!('Speed.GPU.', '')
72
+ tmp[0].gsub!('.', '')
73
+ tmp[0].gsub!('#', '')
74
+ num = tmp[0].to_i
75
+ if num == 1
76
+ array[placement][:speed] = []
77
+ end
78
+ array[placement][:speed][num-1] = tmp[-1].chomp.strip
79
+ elsif line.include?('Recovered.')
80
+ tmp = line.split(':')
81
+ array[placement][:recovered] = tmp[-1].chomp.strip
82
+ elsif line.include?('Progress.')
83
+ tmp = line.split(':')
84
+ array[placement][:progress] = tmp[-1].chomp.strip
85
+ elsif line.include?('Rejected.')
86
+ tmp = line.split(':')
87
+ array[placement][:rejected] = tmp[-1].chomp.strip
88
+ elsif line.include?('HWMon.GPU.')
89
+ # Must account for x amount of GPUs
90
+ tmp = line.split(':')
91
+ tmp[0].gsub!('HWMon.GPU.', '')
92
+ tmp[0].gsub!('.', '')
93
+ tmp[0].gsub!('#', '')
94
+ num = tmp[0].to_i
95
+ if num == 1
96
+ array[placement][:hwmon] = []
97
+ end
98
+ array[placement][:hwmon][num-1] = tmp[-1].chomp.strip
99
+ end
100
+ end
101
+ array
102
+ end
103
+
104
+
105
+ ###########################################################################
106
+ # @method RubyHashcat::Parse.status_automat(file) #
107
+ # @param file: [String] Path to oclHashcat stdout file #
108
+ # @description Parses the oclHashcat status-automat stdout format. #
109
+ # @return [Array][Hash] Array of Hashes with oclHashcat status. #
110
+ ###########################################################################
111
+ def self.status_automat(file)
112
+ array = []
113
+ return array unless File.exists?(file)
114
+ string = []
115
+ File.open(file).each_line do |x|
116
+ string << x
117
+ end
118
+ string.each do |line|
119
+ line = line.chomp
120
+ line = line.strip
121
+ line = line.gsub(' ', ' ')
122
+ unless line.include?('STATUS')
123
+ next
124
+ end
125
+ split = line.split(' ')
126
+ stat = {}
127
+ i = 0
128
+ if split[i] == 'STATUS'
129
+ stat[:status] = split[i+1].chomp.strip
130
+ i += 2
131
+ end
132
+ if split[i] == 'SPEED'
133
+ i += 1
134
+ speed = 0
135
+ si = 0
136
+ while split[i] != 'CURKU'
137
+ calc = split[i].to_f
138
+ duration = split[i+1].to_f
139
+ if calc == 0.0 and duration == 0.0
140
+ stat["speed_gpu_#{si+1}".to_sym] = 0
141
+ else
142
+ stat["speed_gpu_#{si+1}".to_sym] = (calc/duration).round
143
+ speed += (calc/duration).round
144
+ end
145
+ si += 1
146
+ i += 2
147
+ end
148
+ stat[:total_speed] = speed
149
+ end
150
+ if split[i] == 'CURKU'
151
+ stat[:checkpoint] = split[i+1]
152
+ i += 2
153
+ end
154
+ if split[i] == 'PROGRESS'
155
+ current_prog = split[i+1].to_f
156
+ total_prog = split[i+2].to_f
157
+ stat[:progress] = ((((current_prog + 0.0)/(total_prog + 0.0)) * 10000).round)/10000.0
158
+ i += 3
159
+ end
160
+ if split[i] == 'RECHASH'
161
+ rec_count = split[i+1].to_f.to_i
162
+ rec_total = split[i+2].to_f.to_i
163
+ stat[:rec_hash] = "#{rec_count}/#{rec_total}"
164
+ i += 3
165
+ end
166
+ if split[i] == 'RECSALT'
167
+ rec_count = split[i+1].to_f.to_i
168
+ rec_total = split[i+2].to_f.to_i
169
+ stat[:rec_salt] = "#{rec_count}/#{rec_total}"
170
+ i += 3
171
+ end
172
+ if split[i] == 'TEMP'
173
+ i += 1
174
+ si = 0
175
+ while i < split.count
176
+ stat["temp_gpu_#{si+1}".to_sym] = split[i].to_i
177
+ si += 1
178
+ i += 1
179
+ end
180
+ end
181
+ array << stat
182
+ end
183
+ array
184
+ end
185
+
186
+ ###########################################################################
187
+ # @method RubyHashcat::Parse.pot_file(file) #
188
+ # @param file: [String] Path to oclHashcat cracked passwords #
189
+ # @description Parses the cracked passwords into a hash. #
190
+ # @return [Array][Hash] Array of Hashes with cracked passwords. #
191
+ ###########################################################################
192
+ def self.pot_file(file)
193
+ arr = []
194
+ return arr unless File.exists?(file)
195
+ File.open(file).each_line do |x|
196
+ split = x.split(':')
197
+ plain = self.hex_to_bin(split[-1])
198
+ split.delete_at(-1)
199
+ hash = split.join(':')
200
+ arr << {:hash => hash, :plain => plain}
201
+ end
202
+ arr
203
+ end
204
+
205
+ ###########################################################################
206
+ # @method RubyHashcat::Parse.hash(hash) #
207
+ # @param hash: [Hash] Original Hash with strings as keys. #
208
+ # @description Parses a hash with strings as keys and converts them #
209
+ # to symbols. #
210
+ # @return [Hash] Hash with all keys as symbols. #
211
+ ###########################################################################
212
+ def self.hash(obj)
213
+ return obj.reduce({}) do |memo, (k, v)|
214
+ memo.tap { |m| m[k.to_sym] = hash(v) }
215
+ end if obj.is_a? Hash
216
+
217
+ return obj.reduce([]) do |memo, v|
218
+ memo << hash(v); memo
219
+ end if obj.is_a? Array
220
+
221
+ obj
222
+ end
223
+
224
+ ###########################################################################
225
+ # @method RubyHashcat::Parse.bin_to_hex(s) #
226
+ # @param s: [String] Normal String #
227
+ # @description Converts a string to hex #
228
+ # @return [String] Hexed String #
229
+ ###########################################################################
230
+ def self.bin_to_hex(s)
231
+ s.each_byte.map { |b| b.to_s(16) }.join
232
+ end
233
+
234
+ ###########################################################################
235
+ # @method RubyHashcat::Parse.hex_to_bin(s) #
236
+ # @param s: [String] Hexed String #
237
+ # @description Converts hex to a string #
238
+ # @return [String] Normal String #
239
+ ###########################################################################
240
+ def self.hex_to_bin(s)
241
+ s.scan(/../).map { |x| x.hex.chr }.join
242
+ end
243
+
244
+ end
245
+ end
@@ -1,16 +1,25 @@
1
1
  require 'rprogram/program'
2
2
 
3
+ ###########################################################################
4
+ # Author: Coleton Pierson #
5
+ # Company: Praetorian #
6
+ # Date: June 28, 2014 #
7
+ # Project: Ruby Hashcat #
8
+ # Description: Main program wrapper class. Holds the main method #
9
+ # for initializing a cli session. #
10
+ ###########################################################################
11
+
3
12
  module RubyHashcat
4
13
  class Program < RProgram::Program
5
14
 
6
15
  # Add a top-level method which finds and runs the program.
7
16
  def self.crack(options={}, &block)
8
- self.find.crack(options,&block)
17
+ self.find.crack(options, &block)
9
18
  end
10
19
 
11
20
  # Add a method which runs the program with hashcat_task
12
- def crack(options={},&block)
13
- run_task(HashcatTask.new(options,&block))
21
+ def crack(options={}, &block)
22
+ run_task(HashcatTask.new(options, &block))
14
23
  end
15
24
 
16
25
  end
@@ -0,0 +1,23 @@
1
+ module RubyHashcat
2
+ class API < Sinatra::Application
3
+ post '/clean.json' do
4
+ content_type :json
5
+
6
+ if settings.debug
7
+ pp params
8
+ end
9
+
10
+ begin
11
+ hc = RubyHashcat::Objects::Hash.new(params[:id].to_i, settings.ocl_location)
12
+ if hc.exists?
13
+ hc.clean
14
+ return {:status => 'success'}.to_json
15
+ else
16
+ return {:status => 'error', :message => 'Invalid ID.'}.to_json
17
+ end
18
+ rescue => e
19
+ return {:status => 'error'}.to_json
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,85 @@
1
+ module RubyHashcat
2
+ class API < Sinatra::Application
3
+ post '/crack.json' do
4
+ content_type :json
5
+
6
+ if settings.debug
7
+ pp params
8
+ end
9
+
10
+ path = File.dirname(__FILE__)
11
+
12
+ tmp = params.clone
13
+ params = RubyHashcat::Parse.hash(tmp)
14
+
15
+ # Validate required parameters
16
+ unless params[:id] and params[:type] and params[:attack] and params[:hash]
17
+ return {error: 'Invalid Parameters. Please check the documentation.'}.to_json
18
+ end
19
+
20
+ begin
21
+ hc = RubyHashcat::Objects::Hash.new(params[:id].to_i, settings.ocl_location)
22
+ if hc.exists? and not hc.running?
23
+ hc.clean
24
+ end
25
+ id = params[:id].to_i
26
+ attack = params[:attack].to_i
27
+ type = params[:type].to_i
28
+ hash = "#{path}/../tmp/#{id}.hash"
29
+
30
+ hc.attack = attack
31
+
32
+ case attack
33
+ when 1
34
+ raise RubyHashcat::Objects::Hash::InvalidCombinationAttack unless File.exists?(params[:word_list][:tempfile]) and File.exists?(params[:word_list_2][:tempfile])
35
+ word_list = "#{path}/../tmp/#{id}.dict"
36
+ word_list_2 = "#{path}/../tmp/#{id}.dict2"
37
+ tmp = []
38
+ tmp << word_list.clone
39
+ tmp << word_list_2.clone
40
+ File.rename(params[:word_list][:tempfile], word_list)
41
+ File.rename(params[:word_list_2][:tempfile], word_list_2)
42
+ word_list = tmp
43
+ else
44
+ if params[:word_list]
45
+ if params[:word_list][:tempfile]
46
+ if File.exists?(params[:word_list][:tempfile])
47
+ word_list = "#{path}/../tmp/#{id}.dict"
48
+ File.rename(params[:word_list][:tempfile], word_list)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ if params[:rule_sets]
55
+ hc.rules = params[:rule_sets]
56
+ end
57
+ if params[:username]
58
+ hc.username = true
59
+ end
60
+ if params[:charset]
61
+ hc.charset = params[:charset]
62
+ end
63
+
64
+ File.rename(params[:hash][:tempfile], hash)
65
+
66
+ hc.hash = hash
67
+
68
+ if word_list
69
+ hc.word_list = word_list
70
+ end
71
+
72
+ hc.type = type
73
+
74
+ hc.crack(true)
75
+
76
+ return {:status => 'success'}.to_json
77
+ rescue RubyHashcat::Objects::Hash::RubyHashcatError => e
78
+ return {:error => e.message}.to_json
79
+ rescue => e
80
+ return {:error => e.message}.to_json
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,7 @@
1
+ path = File.dirname(__FILE__)
2
+
3
+ require "#{path}/clean"
4
+ require "#{path}/crack"
5
+ require "#{path}/results"
6
+ require "#{path}/settings"
7
+ require "#{path}/status"
@@ -0,0 +1,25 @@
1
+ module RubyHashcat
2
+ class API < Sinatra::Application
3
+ get '/results.json' do
4
+ content_type :json
5
+
6
+ if settings.debug
7
+ pp params
8
+ end
9
+
10
+ begin
11
+ hc = RubyHashcat::Objects::Hash.new(params[:id].to_i, settings.ocl_location)
12
+ unless hc.exists?
13
+ return {:status => 'error', :message => 'Invalid ID.'}.to_json
14
+ end
15
+ if hc.running?
16
+ return {:status => 'running'}.to_json
17
+ else
18
+ return {:results => hc.results}.to_json
19
+ end
20
+ rescue => e
21
+ return {:status => 'error', :message => e.message}.to_json
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ module RubyHashcat
2
+ class API < Sinatra::Application
3
+ get '/location.json' do
4
+ content_type :json
5
+
6
+ if settings.debug
7
+ pp params
8
+ end
9
+
10
+ {:location => settings.ocl_location}.to_json
11
+ end
12
+
13
+ get '/rules.json' do
14
+ content_type :json
15
+
16
+ if settings.debug
17
+ pp params
18
+ end
19
+
20
+ list = Dir.entries("#{settings.ocl_location}/rules/")
21
+ list.delete('.')
22
+ list.delete('..')
23
+ {:rules => list}.to_json
24
+ end
25
+ end
26
+ end