-
Notifications
You must be signed in to change notification settings - Fork 7
/
searchsploit-rb
executable file
·372 lines (356 loc) · 14 KB
/
searchsploit-rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#!/usr/bin/env ruby
#
# Searchsploit Ruby Edition
# By: Hood3dRob1n
#
# Exploit-db now on Github:
# git clone https://github.com/offensive-security/exploit-database.git
#
# The original bash searchsploit script is too simple sometimes (and a little outdated)
# Plus, who doesn't like logging and a little color to mix things up ;p
#
######## Exploit-DB Files.csv Path ########
CSV='/home/clue/fun/exploit-db/files.csv' #
###########################################
###### STD GEMS ######
require 'optparse' #
require 'fileutils' #
#### NON-STD GEMS ####
require 'rubygems' #
require 'colorize' #
######################
# Catch System Interupts
trap("SIGINT") {
puts "\n\nWARNING".light_red + "!".white + " CTRL".light_red + "+".white + "C Detected".light_red + ",".white + " Shutting things down".light_red + "....\n\n".white
exit 666;
}
# 0x1337 Banner
def banner
puts
puts "Searchsploit-rb".light_red + ": An Exploit-DB Search Tool".white
end
# Clear
def cls
if RUBY_PLATFORM =~ /win32|win64|\.NET|windows|W0W64/i
system('cls')
else
system('clear')
end
end
# Update to latest and greatest
# Leverages the new Github format
# Much better than older HTTP downloads!
def git_update(dir=nil)
if dir.nil?
directory = "#{CSV.split("/")[0..-2].join("/")}/"
else
directory = dir
end
Dir.chdir(directory) do
system('git pull')
end
end
# Fetch fresh copy of exploit-db
# Git clones to local dir
# renames: exploit-db
def git_get(dir=nil)
if dir.nil?
directory = Dir.pwd
else
directory = dir
end
Dir.chdir(directory) do
system('git clone https://github.com/offensive-security/exploit-database.git exploit-db')
end
end
# Search based on initial full CSV results set against platform
# This initializes our array to perform further searchs
# We wind down narrowing results as we go
# Due to poor CSV consistency this is the best I could come up with
def search_platform(query)
platform_results=[]
IO.foreach(CSV) do |line|
line = line.unpack('C*').pack('U*') if !line.valid_encoding? # Thanks Stackoverflow :)
if line =~ /(\".+,.+\")/ # Deal with annoying commans within quotes as they shouldn't be used to split on (ahrg)
crappy_csv_line = $1
not_as_crappy_csv_line = crappy_csv_line.sub(",", "")
workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",")
else
workable_csv_line = line.split(",")
end
foo = workable_csv_line - workable_csv_line.slice(0,5)
foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1)
if query == 'nil'
platform_results << line
else
platform_results << line if "#{foobar.join(",")}" =~ /#{query}/i
end
end
return platform_results
end
# Search based on TYPE
# Returns an array with the results
def search_type(exploits_array, query)
search_results=[]
exploits_array.each do |line|
line = line.unpack('C*').pack('U*') if !line.valid_encoding?
if line =~ /(\".+,.+\")/
crappy_csv_line = $1
not_as_crappy_csv_line = crappy_csv_line.sub(",", "")
workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",")
else
workable_csv_line = line.split(",")
end
foo = workable_csv_line - workable_csv_line.slice(0,5)
foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1)
if query == 'nil'
search_results << line
else
if not workable_csv_line[-2].nil?
search_results << line if "#{workable_csv_line[-2].downcase}" =~ /#{query}/i
end
end
end
return search_results
end
# Search based on Author
# Returns an array with the results
def search_author(exploits_array, query)
search_results=[]
exploits_array.each do |line|
line = line.unpack('C*').pack('U*') if !line.valid_encoding?
if line =~ /(\".+,.+\")/
crappy_csv_line = $1
not_as_crappy_csv_line = crappy_csv_line.sub(",", "")
workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",")
else
workable_csv_line = line.split(",")
end
foo = workable_csv_line - workable_csv_line.slice(0,5)
foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1)
if query == 'nil'
search_results << line
else
if not workable_csv_line[4].nil?
search_results << line if "#{workable_csv_line[4].downcase}" =~ /#{query}/i
end
end
end
return search_results
end
# Search based on PORT
# Returns an array with the results
def search_port(exploits_array, query)
search_results=[]
exploits_array.each do |line|
line = line.unpack('C*').pack('U*') if !line.valid_encoding?
if line =~ /(\".+,.+\")/
crappy_csv_line = $1
not_as_crappy_csv_line = crappy_csv_line.sub(",", "")
workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",")
else
workable_csv_line = line.split(",")
end
foo = workable_csv_line - workable_csv_line.slice(0,5)
foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1)
if query == 'nil'
search_results << line
else
if not workable_csv_line[-1].nil?
search_results << line if "#{workable_csv_line[-1].downcase}" =~ /#{query}/i
end
end
end
return search_results
end
# Search based on SEARCH Term
# Returns an array with the results
def search_search(exploits_array, query)
search_results=[]
exploits_array.each do |line|
line = line.unpack('C*').pack('U*') if !line.valid_encoding?
if query == 'nil'
search_results << line
else
search_results << line if line =~ /#{query}/i
end
end
return search_results
end
# Parse remaining exploits in array
# Print out the search results for user
# log to file as well if requested
def display_results(remaining_exploits)
rezsize = remaining_exploits.size
puts "[".light_green + "*".white + "] ".light_green + "Saved #{rezsize} Result(s) to: #{@out}".white if @log
puts "[".light_green + "*".white + "] ".light_green + "Displaying Result(s):".white if @verbose and @log
puts "[".light_green + "*".white + "] ".light_green + "Found #{rezsize} Result(s):".white if @verbose and not @log
remaining_exploits.each do |line|
if line =~ /(\".+,.+\")/
crappy_csv_line = $1
not_as_crappy_csv_line = crappy_csv_line.sub(",", "")
workable_csv_line = line.sub!("#{crappy_csv_line}","#{not_as_crappy_csv_line}").split(",")
else
workable_csv_line = line.split(",")
end
foo = workable_csv_line - workable_csv_line.slice(0,5)
foobar = foo - workable_csv_line.slice(-1, 1) - workable_csv_line.slice(-2, 1)
if @log
f = File.open("#{@out}", 'a+')
f.puts "Description: #{workable_csv_line[2]}"
f.puts "Location: #{CSV.split("/")[0..-2].join("/")}/#{workable_csv_line[1]}"
f.puts "Exploit ID: #{workable_csv_line[0]}"
f.puts "Platform: #{foobar.join(",")}"
f.puts "Type: #{workable_csv_line[-2]}"
if not "#{workable_csv_line[-1].chomp}".to_i == 0
f.puts "Port: #{workable_csv_line[-1].chomp}"
end
f.puts "Author: #{workable_csv_line[4]}"
f.puts "Submit: #{workable_csv_line[3]}"
f.puts
f.close
end
if @verbose
puts "[".light_green + "*".white + "] ".light_green + "Description: ".light_red + "#{workable_csv_line[2]}".white
puts "[".light_green + "*".white + "] ".light_green + "Location: ".light_red + "#{CSV.split("/")[0..-2].join("/")}/#{workable_csv_line[1]}".white
puts "[".light_green + "*".white + "] ".light_green + "Exploit ID: ".light_red + "#{workable_csv_line [0]}".white
puts "[".light_green + "*".white + "] ".light_green + "Platform: ".light_red + "#{foobar.join(",")}".white
puts "[".light_green + "*".white + "] ".light_green + "Type: ".light_red + "#{workable_csv_line[-2]}".white
if not "#{workable_csv_line[-1].chomp}".to_i == 0
"[".light_green + "*".white + "] ".light_green + "Port: ".light_red + "#{workable_csv_line[-1].chomp}".white
end
puts "[".light_green + "*".white + "] ".light_green + "Author: ".light_red + "#{workable_csv_line[4]}".white
puts "[".light_green + "*".white + "] ".light_green + "Submit: ".light_red + "#{workable_csv_line[3]}\n".white
end
end
puts "[".light_blue + "*".white + "] ".light_blue + "Search Complete!".white
puts "[".light_blue + "*".white + "] ".light_blue + "Hope you found what you needed....".white
puts "[".light_blue + "*".white + "] ".light_blue + "Good Bye!".white
end
### MAIN ###
options = {}
optparse = OptionParser.new do |opts|
opts.banner = "Usage:".light_green + " #{$0} ".white + "[".light_green + "OPTIONS".white + "]".light_green
opts.separator ""
opts.separator "EX:".light_green + " #{$0} --update".white
opts.separator "EX:".light_green + " #{$0} -t webapps -s vBulletin".white
opts.separator "EX:".light_green + " #{$0} --search=\"Linux Kernel 2.6\"".white
opts.separator "EX:".light_green + " #{$0} -a \"JoinSe7en\" -s \"MyBB\"".white
opts.separator "EX:".light_green + " #{$0} -t remote -s \"SQL Injection\"".white
opts.separator "EX:".light_green + " #{$0} -p linux -t local -s UDEV -o search_results.txt".white
opts.separator ""
opts.separator "Options: ".light_green
opts.on('-u', '--update', "\n\tUpdate Exploit-DB Working Archive to Latest & Greatest".white) do |host|
options[:method] = 0
end
opts.on('-p', '--platform <PLATFORM>', "\n\tSystem Platform Type, options include:
sco, bsdi/x86, openbsd, lin/amd64, plan9, bsd/x86, openbsd/x86, hardware, bsd, unix, lin/x86-64, netbsd/x86, linux, solaris, ultrix, arm, php, solaris/sparc, osX, os-x/ppc, cfm, generator, freebsd/x86, bsd/ppc, minix, unixware, freebsd/x86-64, cgi, hp-ux, multiple, win64, tru64, jsp, novell, linux/mips, solaris/x86, aix, windows, linux/ppc, irix, QNX, lin/x86, win32, linux/sparc, freebsd, asp, sco/x86".white) do |platform|
options[:platform] = platform.downcase.chomp
options[:method] = 1
end
opts.on('-t', '--type <TYPE>', "\n\tType of Exploit, options include:\n\tDoS, Remote, Local, WebApps, Papers or Shellcode".white) do |type|
options[:type] = type.downcase.chomp
options[:method] = 1
end
opts.on('-a', '--author <NAME>', "\n\tRun Lookup based on Author Username".white) do |author|
options[:author] = author.downcase.chomp
options[:method] = 1
end
opts.on('-s', '--search <SEARCH_TERM>', "\n\tSearch Term to look for in Exploit-DB Working Archive".white) do |search|
options[:search] = search.downcase.chomp
options[:method] = 1
end
opts.on('-o', '--output <OUTPUT_FILE>', "\n\tOutput File to Write Search Results to".white) do |output|
@out = output.strip.chomp
options[:log] = true
end
opts.on('-q', '--quiet', "\n\tSilence Output to Terminal for Search Results (when logging output)".white) do |output|
options[:q] = true
end
opts.on('-h', '--help', "\n\tHelp Menu".white) do
banner
puts
puts opts
puts
exit 69;
end
end
begin
foo = ARGV[0] || ARGV[0] = "--help"
optparse.parse!
mandatory = [:method]
missing = mandatory.select{ |param| options[param].nil? }
if not missing.empty?
cls
banner
puts
puts "Missing options: ".light_red + " #{missing.join(', ')}".white
puts optparse
exit 666;
end
rescue OptionParser::InvalidOption, OptionParser::MissingArgument, OptionParser::AmbiguousOption
cls
banner
puts
puts $!.to_s.light_red
puts
puts optparse
puts
exit 666;
end
#Make we have search values or set wildcards
options[:platform] = '' if not options[:platform]
options[:type] = '' if not options[:type]
options[:author] = '' if not options[:author]
options[:port] = '' if not options[:port]
options[:search] = '' if not options[:search]
if options[:log]
@log=true
else
@log=false
end
if options[:q]
@verbose=false
else
@verbose=true
end
cls
banner
puts
if File.exists?(CSV) and File.directory?("#{CSV.split("/")[0..-2].join("/")}/platforms")
if options[:method].to_i == 0
# Update
puts "[".light_green + "*".white + "] ".light_green + "Found existing archive file: #{CSV}".white
puts "[".light_green + "*".white + "] ".light_green + "Running update to get latest and greatest....".white
git_update
else
puts "[".light_green + "*".white + "] ".light_green + "Found archive file: #{CSV}".white
plresults = search_platform(options[:platform]) unless options[:platform].nil?
tresults = search_type(plresults, options[:type]) unless options[:type].nil?
aresults = search_author(tresults, options[:author]) unless options[:author].nil?
presults = search_port(aresults, options[:port]) unless options[:port].nil?
results = search_search(presults, options[:search]) unless options[:search].nil?
display_results(results)
end
else
# Not finding fi.es.csv and ./platforms/
puts "[".light_red + "X".white + "] ".light_red + "Problem locating archive file: #{CSV}!".white unless File.exists?(CSV)
puts "[".light_red + "X".white + "] ".light_red + "Problem locating archives platforms dir: #{CSV.split("/")[0..-2].join("/")}/platforms!".white unless File.directory?("#{CSV.split("/")[0..-2].join("/")}/platforms")
puts "[".light_red + "X".white + "] ".light_red + "Can't run searches without it...".white
print "(".light_red + "Do You want to Git CLone it ".white + "(".light_yellow + "Y".white + "/".light_yellow + "N".white + ")".light_yellow + "?".white + ")> ".light_red
answer = gets.chomp
if answer.upcase == 'Y' or answer.upcase == 'YES'
puts "[".light_blue + "*".white + "] ".light_blue + "Trying to git clone the exploit-db repo...".white
if File.directory?("#{CSV.split("/")[0..-2].join("/")}/") and "#{CSV.split("/")[0..-2].join("/")}/" != '/'
git_get("#{CSV.split("/")[0..-2].join("/")}/")
else
git_get
end
puts "[".light_blue + "*".white + "] ".light_blue + "Hopefully things went well with git clone installation...".white
puts "[".light_blue + "*".white + "] ".light_blue + "Try editing source code to point to the new setup and run again...".white
else
puts "[".light_red + "X".white + "] ".light_red + "OK, try again when you get things figured out then.....".white
end
end
puts "\n\n"
#EOF