|
| 1 | +require 'sqlmap/sqlmap_session' |
| 2 | +require 'sqlmap/sqlmap_manager' |
| 3 | +require 'json' |
| 4 | + |
| 5 | +module Msf |
| 6 | + class Plugin::Sqlmap < Msf::Plugin |
| 7 | + class SqlmapCommandDispatcher |
| 8 | + include Msf::Ui::Console::CommandDispatcher |
| 9 | + |
| 10 | + def name |
| 11 | + "Sqlmap" |
| 12 | + end |
| 13 | + |
| 14 | + def commands |
| 15 | + { |
| 16 | + 'sqlmap_new_task' => 'It\'s a task!', |
| 17 | + 'sqlmap_connect' => 'sqlmap_connect <host> [<port>]', |
| 18 | + 'sqlmap_list_tasks' => 'List the knows tasks. Not stored in a DB, so lives as long as the console does', |
| 19 | + 'sqlmap_get_option' => 'Get an option for a task', |
| 20 | + 'sqlmap_set_option' => 'Set an option for a task', |
| 21 | + 'sqlmap_start_task' => 'Start the task', |
| 22 | + 'sqlmap_get_status' => 'Get the status of a task', |
| 23 | + 'sqlmap_get_log' => 'Get the running log of a task', |
| 24 | + 'sqlmap_get_data' => 'Get the resulting data of the task', |
| 25 | + 'sqlmap_save_data' => 'Save the resulting data as web_vulns' |
| 26 | + } |
| 27 | + end |
| 28 | + |
| 29 | + def cmd_sqlmap_connect(*args) |
| 30 | + if args.length == 0 |
| 31 | + print_error('Need a host, and optionally a port') |
| 32 | + return |
| 33 | + end |
| 34 | + |
| 35 | + host = args[0] |
| 36 | + port = args.length == 2 ? args[1] : nil |
| 37 | + |
| 38 | + if !port |
| 39 | + @manager = Sqlmap::Manager.new(Sqlmap::Session.new(host)) |
| 40 | + else |
| 41 | + @manager = Sqlmap::Manager.new(Sqlmap::Session.new(host, port)) |
| 42 | + end |
| 43 | + |
| 44 | + print_good('Set connection settings for host ' + host + (port ? ' on port ' + port : '')) |
| 45 | + end |
| 46 | + |
| 47 | + def cmd_sqlmap_set_option(*args) |
| 48 | + unless args.length == 3 |
| 49 | + print_error('Usage:') |
| 50 | + print_error('\tsqlmap_set_option <taskid> <option_name> <option_value>') |
| 51 | + return |
| 52 | + end |
| 53 | + |
| 54 | + unless @manager |
| 55 | + print_error('Please run sqlmap_connect <host> first.') |
| 56 | + return |
| 57 | + end |
| 58 | + |
| 59 | + val = args[2] |
| 60 | + if args[2] =~ /^\d+$/ |
| 61 | + val = val.to_i |
| 62 | + end |
| 63 | + |
| 64 | + res = @manager.set_option(@hid_tasks[args[0]], args[1], val) |
| 65 | + print_status('Success: ' + res['success'].to_s) |
| 66 | + end |
| 67 | + |
| 68 | + def cmd_sqlmap_start_task(*args) |
| 69 | + if args.length == 0 |
| 70 | + print_error('Usage:') |
| 71 | + print_error('\tsqlmap_start_task <taskid> [<url>]') |
| 72 | + return |
| 73 | + end |
| 74 | + |
| 75 | + options = {} |
| 76 | + |
| 77 | + if args.length == 2 |
| 78 | + options['url'] = args[1] |
| 79 | + end |
| 80 | + |
| 81 | + if !options['url'] && @tasks[@hid_tasks[args[0]]]['url'] == '' |
| 82 | + print_error('You need to specify a URL either as an argument to sqlmap_start_task or sqlmap_set_option') |
| 83 | + return |
| 84 | + end |
| 85 | + |
| 86 | + unless @manager |
| 87 | + print_error('Please run sqlmap_connect <host> first.') |
| 88 | + return |
| 89 | + end |
| 90 | + |
| 91 | + res = @manager.start_task(@hid_tasks[args[0]], options) |
| 92 | + print_status('Started task: ' + res['success'].to_s) |
| 93 | + end |
| 94 | + |
| 95 | + def cmd_sqlmap_get_log(*args) |
| 96 | + unless args.length == 1 |
| 97 | + print_error('Usage:') |
| 98 | + print_error('\tsqlmap_get_log <taskid>') |
| 99 | + return |
| 100 | + end |
| 101 | + |
| 102 | + unless @manager |
| 103 | + print_error('Please run sqlmap_connect <host> first.') |
| 104 | + return |
| 105 | + end |
| 106 | + |
| 107 | + res = @manager.get_task_log(@hid_tasks[args[0]]) |
| 108 | + |
| 109 | + res['log'].each do |message| |
| 110 | + print_status("[#{message["time"]}] #{message["level"]}: #{message["message"]}") |
| 111 | + end |
| 112 | + end |
| 113 | + |
| 114 | + def cmd_sqlmap_get_status(*args) |
| 115 | + unless args.length == 1 |
| 116 | + print_error('Usage:') |
| 117 | + print_error('\tsqlmap_get_status <taskid>') |
| 118 | + return |
| 119 | + end |
| 120 | + |
| 121 | + unless @manager |
| 122 | + print_error('Please run sqlmap_connect <host> first.') |
| 123 | + return |
| 124 | + end |
| 125 | + |
| 126 | + res = @manager.get_task_status(@hid_tasks[args[0]]) |
| 127 | + |
| 128 | + print_status('Status: ' + res['status']) |
| 129 | + end |
| 130 | + |
| 131 | + def cmd_sqlmap_get_data(*args) |
| 132 | + unless args.length == 1 |
| 133 | + print_error('Usage:') |
| 134 | + print_error('\tsqlmap_get_data <taskid>') |
| 135 | + return |
| 136 | + end |
| 137 | + |
| 138 | + @hid_tasks ||= {} |
| 139 | + @tasks ||= {} |
| 140 | + |
| 141 | + unless @manager |
| 142 | + print_error('Please run sqlmap_connect <host> first.') |
| 143 | + return |
| 144 | + end |
| 145 | + |
| 146 | + @tasks[@hid_tasks[args[0]]] = @manager.get_options(@hid_tasks[args[0]])['options'] |
| 147 | + |
| 148 | + print_line |
| 149 | + print_status('URL: ' + @tasks[@hid_tasks[args[0]]]['url']) |
| 150 | + |
| 151 | + res = @manager.get_task_data(@hid_tasks[args[0]]) |
| 152 | + |
| 153 | + tbl = Rex::Ui::Text::Table.new( |
| 154 | + 'Columns' => ['Title','Payload']) |
| 155 | + |
| 156 | + res['data'].each do |d| |
| 157 | + d['value'].each do |v| |
| 158 | + v['data'].each do |i| |
| 159 | + title = i[1]['title'].split('-')[0] |
| 160 | + payload = i[1]['payload'] |
| 161 | + tbl << [title, payload] |
| 162 | + end |
| 163 | + end |
| 164 | + end |
| 165 | + |
| 166 | + print_line |
| 167 | + print_line tbl.to_s |
| 168 | + print_line |
| 169 | + end |
| 170 | + |
| 171 | + def cmd_sqlmap_save_data(*args) |
| 172 | + unless args.length == 1 |
| 173 | + print_error('Usage:') |
| 174 | + print_error('\tsqlmap_save_data <taskid>') |
| 175 | + return |
| 176 | + end |
| 177 | + |
| 178 | + unless framework.db && framework.db.usable |
| 179 | + print_error('No database is connected or usable') |
| 180 | + return |
| 181 | + end |
| 182 | + |
| 183 | + @hid_tasks ||= {} |
| 184 | + @tasks ||= {} |
| 185 | + |
| 186 | + unless @manager |
| 187 | + print_error('Please run sqlmap_connect <host> first.') |
| 188 | + return |
| 189 | + end |
| 190 | + |
| 191 | + @tasks[@hid_tasks[args[0]]] = @manager.get_options(@hid_tasks[args[0]])['options'] |
| 192 | + |
| 193 | + print_line |
| 194 | + print_status('URL: ' + @tasks[@hid_tasks[args[0]]]['url']) |
| 195 | + |
| 196 | + res = @manager.get_task_data(@hid_tasks[args[0]]) |
| 197 | + web_vuln_info = {} |
| 198 | + url = @tasks[@hid_tasks[args[0]]]['url'] |
| 199 | + proto = url.split(':')[0] |
| 200 | + host = url.split('/')[2] |
| 201 | + port = 80 |
| 202 | + port = host.split(':')[1] if host.index(':') |
| 203 | + host = host.split(':')[0] if host.index(':') |
| 204 | + path = '/' + (url.split('/')[3..(url.split('/').length - 1)].join('/')) |
| 205 | + query = url.split('?')[1] |
| 206 | + web_vuln_info[:web_site] = url |
| 207 | + web_vuln_info[:path] = path |
| 208 | + web_vuln_info[:query] = query |
| 209 | + web_vuln_info[:host] = host |
| 210 | + web_vuln_info[:port] = port |
| 211 | + web_vuln_info[:ssl] = (proto =~ /https/) |
| 212 | + web_vuln_info[:category] = 'imported from sqlmap' |
| 213 | + res['data'].each do |d| |
| 214 | + d['value'].each do |v| |
| 215 | + web_vuln_info[:pname] = v['parameter'] |
| 216 | + web_vuln_info[:method] = v['place'] |
| 217 | + web_vuln_info[:payload] = v['suffix'] |
| 218 | + v['data'].each do |k,i| |
| 219 | + web_vuln_info[:name] = i['title'] |
| 220 | + web_vuln_info[:description] = res.to_json |
| 221 | + web_vuln_info[:proof] = i['payload'] |
| 222 | + framework.db.report_web_vuln(web_vuln_info) |
| 223 | + end |
| 224 | + end |
| 225 | + end |
| 226 | + print_good('Saved vulnerabilities to database.') |
| 227 | + end |
| 228 | + |
| 229 | + def cmd_sqlmap_get_option(*args) |
| 230 | + @hid_tasks ||= {} |
| 231 | + @tasks ||= {} |
| 232 | + |
| 233 | + unless args.length == 2 |
| 234 | + print_error('Usage:') |
| 235 | + print_error('\tsqlmap_get_option <taskid> <option_name>') |
| 236 | + end |
| 237 | + |
| 238 | + unless @manager |
| 239 | + print_error('Please run sqlmap_connect <host> first.') |
| 240 | + return |
| 241 | + end |
| 242 | + |
| 243 | + task_options = @manager.get_options(@hid_tasks[args[0]]) |
| 244 | + @tasks[@hid_tasks[args[0]]] = task_options['options'] |
| 245 | + |
| 246 | + if @tasks[@hid_tasks[args[0]]] |
| 247 | + print_good(args[1] + ': ' + @tasks[@hid_tasks[args[0]]][args[1]].to_s) |
| 248 | + else |
| 249 | + print_error('Option ' + args[0] + ' doesn\'t exist') |
| 250 | + end |
| 251 | + end |
| 252 | + |
| 253 | + def cmd_sqlmap_new_task(*args) |
| 254 | + @hid_tasks ||= {} |
| 255 | + @tasks ||= {} |
| 256 | + |
| 257 | + unless @manager |
| 258 | + print_error('Please run sqlmap_connect <host> first.') |
| 259 | + return |
| 260 | + end |
| 261 | + |
| 262 | + taskid = @manager.new_task['taskid'] |
| 263 | + @hid_tasks[(@hid_tasks.length+1).to_s] = taskid |
| 264 | + task_options = @manager.get_options(taskid) |
| 265 | + @tasks[@hid_tasks[@hid_tasks.length]] = task_options['options'] |
| 266 | + print_good('Created task: ' + @hid_tasks.length.to_s) |
| 267 | + end |
| 268 | + |
| 269 | + def cmd_sqlmap_list_tasks(*args) |
| 270 | + @hid_tasks ||= {} |
| 271 | + @tasks ||= {} |
| 272 | + @hid_tasks.each do |task, options| |
| 273 | + print_good('Task ID: ' + task.to_s) |
| 274 | + end |
| 275 | + end |
| 276 | + end |
| 277 | + |
| 278 | + def initialize(framework, opts) |
| 279 | + super |
| 280 | + |
| 281 | + add_console_dispatcher(SqlmapCommandDispatcher) |
| 282 | + |
| 283 | + print_status('Sqlmap plugin loaded') |
| 284 | + end |
| 285 | + |
| 286 | + def cleanup |
| 287 | + remove_console_dispatcher('Sqlmap') |
| 288 | + end |
| 289 | + |
| 290 | + def name |
| 291 | + 'Sqlmap' |
| 292 | + end |
| 293 | + |
| 294 | + def desc |
| 295 | + 'Use Sqlmap, yo!' |
| 296 | + end |
| 297 | + end |
| 298 | +end |
0 commit comments