Compare commits

..
125 Commits
Author SHA1 Message Date
Miroslav Stampar e3134cc965 Final preparation for 1.3 2019-01-05 23:14:28 +01:00
Miroslav Stampar 5957aad738 Update of checksums 2019-01-05 22:58:28 +01:00
Miroslav Stampar 4c4de54ad8 Prepare for 1.3 2019-01-05 21:48:39 +01:00
Miroslav Stampar 590e8ed5ae update_copyright_year() 2019-01-05 21:38:52 +01:00
Miroslav Stampar 12427ff6f8 Minor update 2019-01-05 21:29:59 +01:00
Miroslav Stampar 45d0010323 Most probably solves #3422 2018-12-31 01:20:43 +01:00
Miroslav Stampar e18b41fc82 Fixes #3421 2018-12-31 01:03:40 +01:00
Miroslav Stampar 586c461ae6 Minor patch 2018-12-31 01:01:19 +01:00
Miroslav Stampar c799e794f2 Minor update of modsecurity.py 2018-12-29 20:40:49 +01:00
Miroslav Stampar b31c264a59 Minor update 2018-12-28 20:49:40 +01:00
Miroslav Stampar a569f21ad7 Bug fix (--smoke hasn't tested wrapped functions) 2018-12-28 18:25:56 +01:00
Miroslav Stampar 8092551fa9 Minor refactoring 2018-12-28 18:22:44 +01:00
Miroslav Stampar 83972d405f Trivial text update 2018-12-28 17:54:58 +01:00
Miroslav Stampar de0df99d8e Update regarding #3418 (fallback for MsSQL's --passwords) 2018-12-28 00:41:48 +01:00
Miroslav Stampar ddee027afb Minor message update 2018-12-26 23:23:49 +01:00
Miroslav Stampar 6ce0350abc Fixes #3420 2018-12-26 22:12:13 +01:00
Miroslav Stampar 37de01e993 Fixes #3417 2018-12-23 10:18:27 +01:00
Miroslav Stampar 63cca82288 Fixes #3415 2018-12-23 09:58:04 +01:00
Denis 7d1c2633c9 Add contributed Ukrainian translation (#3414) 2018-12-23 09:24:53 +01:00
Miroslav Stampar 9564c8e8b1 Refactoring regarding casting warnings 2018-12-21 11:29:57 +01:00
Miroslav Stampar 5e099144d3 Minor message update 2018-12-21 10:38:27 +01:00
Miroslav Stampar a007cd30e5 Fixes #3412 2018-12-19 11:11:56 +01:00
Miroslav Stampar 4c9e0b9f1e Adding Bluedon WAF script 2018-12-18 00:35:08 +01:00
Miroslav Stampar 0c3fbc46df Adding Approach WAF script 2018-12-18 00:08:56 +01:00
Miroslav Stampar 107d9f90ad Minor message update 2018-12-17 23:41:04 +01:00
Miroslav Stampar daafe9b74a Bug fix (OR boolean based blind caused trouble to UNION with negative logic) 2018-12-17 23:25:23 +01:00
Miroslav Stampar 9727f0d691 Minor patch (--parse-errors with lots of HTML inside) 2018-12-17 22:49:09 +01:00
Miroslav Stampar 61e0459ec8 Minor update 2018-12-17 17:48:22 +01:00
Miroslav Stampar c5802a5367 Minor update related to the last commit 2018-12-17 17:43:11 +01:00
Miroslav Stampar 01d5da18e3 Adding experimental option --crack 2018-12-17 17:38:47 +01:00
Miroslav Stampar b288bfdbc3 Minor update 2018-12-17 17:03:51 +01:00
Miroslav Stampar 1e508547d8 Trivial console output update 2018-12-17 16:08:14 +01:00
Miroslav Stampar 4fe4c582c1 Minor output adjustments 2018-12-17 15:15:54 +01:00
Miroslav Stampar 28e7c8f378 Refactoring KeyboardInterrupt mess 2018-12-17 15:00:57 +01:00
Miroslav Stampar c497aa98ed Minor TCP optimization 2018-12-17 14:19:59 +01:00
Miroslav Stampar 4ba9e9397c One more update of DBMS error messages 2018-12-16 16:24:01 +01:00
Miroslav Stampar eedfa8c888 Another update of DBMS error messages 2018-12-16 16:00:04 +01:00
Miroslav Stampar c224ea0e37 Update of DBMS error messages 2018-12-16 15:20:46 +01:00
Miroslav Stampar f544554475 Bug fix (--forms with --url without protocol) 2018-12-16 02:56:31 +01:00
Miroslav Stampar c7c7e30130 Potential patch for #3374 2018-12-14 10:45:42 +01:00
Miroslav Stampar d1426a023f Fixes #3408 2018-12-14 10:09:40 +01:00
nil0x42 83a1b9b2e7 errors.xml: detect mysqli_*() errors. (#3407)
MySQL injection error message often happen with
mysqli_*() functions nowadays.
POC: https://duckduckgo.com/?q=%22warning..mysqli
2018-12-14 10:08:52 +01:00
Miroslav Stampar 38684ec220 Fixes #3403 2018-12-11 13:28:51 +01:00
Miroslav Stampar 2e5edce8b9 Fixes #3399 2018-12-10 15:22:53 +01:00
Miroslav Stampar a02662f03f Trivial cleanup 2018-12-10 14:53:53 +01:00
Miroslav Stampar 2c95b65eac Implementation for #2552 (sorry @mg98) 2018-12-10 14:53:11 +01:00
Miroslav Stampar e47c1aa61b Resolving some more hooking problems 2018-12-10 13:21:36 +01:00
Miroslav Stampar f81062d595 Resolving some more hooking problems 2018-12-10 13:20:34 +01:00
Miroslav Stampar ef911b6be4 Dummy commit (just to test hooks) 2018-12-10 13:10:01 +01:00
Miroslav Stampar 4f1b0787ed Commit hooks were disabled 2018-12-10 13:04:53 +01:00
Miroslav Stampar 070e173067 Another patch for #3389 (Fixes #3397) 2018-12-10 12:59:13 +01:00
Miroslav Stampar f04584bb68 Update of error message regexes 2018-12-07 11:22:53 +01:00
Miroslav Stampar 66d26f67bf Manual tagging (automatic tagging failed for some reason) 2018-12-07 10:06:31 +01:00
Miroslav Stampar 101d1f0d49 Fixes #3395 2018-12-03 23:18:52 +01:00
Miroslav Stampar 843126702d Fixes #3392 2018-12-03 23:12:45 +01:00
Miroslav Stampar 65f227fe65 Bug fix (privately reported: --technique=E --where='id=1') 2018-12-03 23:07:13 +01:00
Miroslav Stampar 536d9a597e Minor language update 2018-12-03 22:59:46 +01:00
Miroslav Stampar 0ce2128a9b Fixes #3394 2018-12-03 22:40:44 +01:00
Miroslav Stampar e7ed2bbcbb Fixes #3391) 2018-11-30 11:29:17 +01:00
Miroslav Stampar 560ff4154b Fixes #3388 (and refactors #1578) 2018-11-29 00:09:05 +01:00
Miroslav Stampar 1d0d5f1675 Fixes #3389 2018-11-28 23:09:13 +01:00
Miroslav Stampar f1a3c81aec Bug fix for handling of custom headers 2018-11-28 00:29:17 +01:00
Miroslav Stampar 277a4fa402 Potential patch for #3167 2018-11-26 23:40:47 +01:00
Miroslav Stampar 037db0f4a0 Fixes #3381 2018-11-23 15:55:05 +01:00
Miroslav Stampar 3f1bf742fc Fixes #3379 2018-11-22 08:07:27 +01:00
Miroslav Stampar abb911d741 Just for the sake of #3377 2018-11-19 09:53:09 +01:00
Miroslav Stampar dc5edf1a86 Patch regarding #3377 2018-11-19 09:52:09 +01:00
Miroslav Stampar e11febdcbc Fixes #3375 2018-11-19 09:44:13 +01:00
Miroslav Stampar f2af8861f9 Some more updates regarding #3140 2018-11-15 17:13:13 +01:00
Miroslav Stampar 2895e5c20f Initial commit for #3140 2018-11-15 15:27:17 +01:00
Miroslav Stampar b1e8c75672 Update README.md 2018-11-14 12:59:40 +01:00
Miroslav Stampar 6cc52cc12a Fixes #3366 2018-11-12 14:07:41 +01:00
Miroslav Stampar ddf353b86e Fixes #3357 2018-11-04 14:36:38 +01:00
Miroslav Stampar e6535d359d Update related to the #3358 2018-11-04 14:17:53 +01:00
Miroslav Stampar 90e381a5a5 Another update related to the #3356 2018-11-02 16:18:08 +01:00
Miroslav Stampar e99e9919cd Update related to the #3356 2018-11-02 15:44:44 +01:00
Miroslav Stampar dbdfbcc425 Adding dates to the start/end time 2018-11-01 22:59:20 +01:00
Miroslav Stampar 1d6832a84a Cosmetic update (not patch) related to the #3354 2018-11-01 22:41:33 +01:00
Miroslav Stampar 73d83280fe Minor patch (bounded injection case with leftover marker) 2018-11-01 22:24:36 +01:00
Miroslav Stampar 1bd8c519c3 Minor just in case update 2018-10-30 15:41:39 +01:00
Miroslav Stampar a4fdbf1343 Patch related to the #3348 2018-10-30 11:13:09 +01:00
Miroslav Stampar 130879fbf3 Minor patches 2018-10-30 10:37:39 +01:00
Miroslav Stampar db5ae9ae0b Minor update to #3326 (adding generic code >= 400) 2018-10-29 09:55:14 +01:00
Syed Afzal cc4833429f added china cache (#3326) 2018-10-29 09:51:18 +01:00
Miroslav Stampar 703b7079a4 Fixes #3319 2018-10-27 14:30:28 +02:00
Miroslav Stampar ef52ee977f Minor patch 2018-10-27 14:14:21 +02:00
Miroslav Stampar ba1b4c50be Trivial cleanup 2018-10-26 23:40:08 +02:00
Miroslav Stampar 1e7dfe11b4 Fixes #3318 2018-10-26 23:38:37 +02:00
Miroslav Stampar 92febd22a8 Minor update 2018-10-26 23:01:19 +02:00
Miroslav Stampar 83081b5e14 Minor patch related to the #3316 2018-10-26 14:00:51 +02:00
Miroslav Stampar f2035145fe Another update related to the #3316 2018-10-26 12:10:22 +02:00
Miroslav Stampar 48b407c0fa Updates regarding the #3316 2018-10-26 12:09:21 +02:00
Jennifer Torres 4466504f30 Lua-Nginx WAFs Bypass (#3316)
* Lua-Nginx WAFs Bypass

Lua-Nginx WAFs doesn't support processing for more than 100 parameters.
https://www.youtube.com/watch?v=JUvro7cqidY

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

Update header.

* Update luanginxwafbypass.py
2018-10-26 12:04:37 +02:00
Miroslav Stampar dc65afe65a Minor update related to the #3283 2018-10-24 16:33:23 +02:00
Miroslav Stampar 132e963b53 More general TypeMismatchException (for Hibernate too) 2018-10-24 15:12:13 +02:00
Miroslav Stampar f52beff7c3 Minor patch to handle late ImportError reports 2018-10-22 11:21:30 +02:00
Miroslav Stampar feb93dce44 Update related to the #3304 2018-10-17 12:24:52 +02:00
Miroslav Stampar e52422900e Fixes #3303 2018-10-16 19:37:27 +02:00
Miroslav Stampar c045afd842 Minor cleanup 2018-10-16 14:53:41 +02:00
Miroslav Stampar 0d2db32539 Finalizing #3283 2018-10-16 14:47:09 +02:00
Miroslav Stampar 77f4fd93e7 Minor leftover 2018-10-16 13:27:31 +02:00
Miroslav Stampar 68f5597b4a Some cleaning up for #3283 2018-10-16 13:26:55 +02:00
Miroslav Stampar 411f56e710 Initial implementation for #3283 2018-10-16 12:23:07 +02:00
Miroslav Stampar fb95ab8c17 Initial commit for #3283 (fixing H2 misidentification with PgSQL and/or HSQLDB) 2018-10-16 08:02:38 +02:00
Miroslav Stampar 9f6e04b141 Minor update of help text 2018-10-15 02:15:05 +02:00
Miroslav Stampar 1f2bdf5a3d Trivial message update 2018-10-15 00:56:23 +02:00
Miroslav Stampar 465a1e1a86 Minor update 2018-10-15 00:53:26 +02:00
Miroslav Stampar 6af127cb64 Fixes #3286 2018-10-14 22:17:10 +02:00
Miroslav Stampar 880d438418 Fixes #3284 2018-10-12 00:29:43 +02:00
Miroslav Stampar 5efe3228f8 Patch related to the #3282 2018-10-12 00:16:42 +02:00
Miroslav Stampar e005ba3f77 Minor patch 2018-10-11 23:59:09 +02:00
Miroslav Stampar f2b4dc3ffc Fixes #3275 2018-10-08 23:34:55 +02:00
Miroslav Stampar d1022f3f59 Fixes #3246 2018-10-04 13:51:41 +02:00
Miroslav Stampar 3984b94297 Fixes #3271 2018-10-04 13:42:13 +02:00
Miroslav Stampar eba01ee74e Just in case patch (for --api) 2018-10-03 12:46:40 +02:00
Miroslav Stampar 36b660309b Minor patch 2018-10-03 12:28:55 +02:00
Miroslav Stampar fd89fdf40b Minor cleaning up 2018-10-03 11:27:51 +02:00
Miroslav Stampar 2e53096962 Fixes #3268 2018-10-03 11:02:13 +02:00
Miroslav Stampar 79e45bd8d7 Minor update 2018-10-02 15:10:31 +02:00
Miroslav Stampar ed5f4abebd Minor updates 2018-10-02 14:56:20 +02:00
Miroslav Stampar 03bbfdbc56 Can't work out of the box (too many unknowns) 2018-10-02 14:11:26 +02:00
Miroslav Stampar 1b6365b195 Minor cleanup 2018-10-02 14:07:14 +02:00
Miroslav Stampar d38a0542d8 Minor update 2018-10-02 13:48:39 +02:00
Miroslav Stampar 9182b90b2b Removing an obsolete utility 2018-10-02 12:58:25 +02:00
Miroslav Stampar 80af22435a Update README.md 2018-10-02 12:21:29 +02:00
377 changed files with 2668 additions and 1396 deletions
+1 -1
View File
@@ -19,7 +19,7 @@
* Client OS (e.g. `Microsoft Windows 10`) * Client OS (e.g. `Microsoft Windows 10`)
* Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation): * Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation):
* Target DBMS (e.g. `Microsoft SQL Server`): * Target DBMS (e.g. `Microsoft SQL Server`):
* Detected WAF/IDS/IPS protection (e.g. `ModSecurity` or `unknown`): * Detected WAF/IPS protection (e.g. `ModSecurity` or `unknown`):
* SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`): * SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`):
* Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works): * Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works):
* Relevant console output (if any): * Relevant console output (if any):
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy COPYING -- Describes the terms under which sqlmap is distributed. A copy
of the GNU General Public License (GPL) is appended to this file. of the GNU General Public License (GPL) is appended to this file.
sqlmap is (C) 2006-2018 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar. sqlmap is (C) 2006-2019 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
This program is free software; you may redistribute and/or modify it under This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License as published by the Free the terms of the GNU General Public License as published by the Free
+3 -2
View File
@@ -1,10 +1,10 @@
# sqlmap # sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-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/[email protected])](https://twitter.com/sqlmap) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap 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 lasting from database fingerprinting, over data fetching from the database, to 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 lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/?utm_source=github.com&utm_medium=referral&utm_content=sqlmap+repo&utm_campaign=generic+advert).** **The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/scan-website-security-issues/?utm_source=sqlmap.org&utm_medium=banner&utm_campaign=github).**
Screenshots Screenshots
---- ----
@@ -67,3 +67,4 @@ Translations
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md) * [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md) * [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md) * [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
* [Ukrainian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-uk-UA.md)
+3
View File
@@ -565,6 +565,9 @@ Efrain Torres, <et(at)metasploit.com>
* for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository * for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository
* for his great Metasploit WMAP Framework * for his great Metasploit WMAP Framework
Jennifer Torres, <jtorresf42(at)gmail.com>
* for contributing a tamper script luanginx.py
Sandro Tosi, <matrixhasu(at)gmail.com> Sandro Tosi, <matrixhasu(at)gmail.com>
* for helping to create sqlmap Debian package correctly * for helping to create sqlmap Debian package correctly
+50
View File
@@ -0,0 +1,50 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення, безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній системі через out-of-band з'єднання.
Скриншоти
----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Ви можете ознайомитися з [колекцією скриншотів](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), які демонструють деякі функції в wiki.
Встановлення
----
Ви можете завантажити останню версію tarball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/tarball/master) або останню версію zipball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/zipball/master).
Найкраще завантажити sqlmap шляхом клонування [Git](https://github.com/sqlmapproject/sqlmap) репозиторію:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap «працює з коробки» з [Python](http://www.python.org/download/) версії **2.6.x** та **2.7.x** на будь-якій платформі.
Використання
----
Щоб отримати список основних опцій і перемикачів, використовуйте:
python sqlmap.py -h
Щоб отримати список всіх опцій і перемикачів, використовуйте:
python sqlmap.py -hh
Ви можете знайти приклад виконання [тут](https://asciinema.org/a/46601).
Для того, щоб ознайомитися з можливостями sqlmap, списком підтримуваних функцій та описом всіх параметрів і перемикачів, а також прикладами, вам рекомендується скористатися [інструкцією користувача](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Посилання
----
* Основний сайт: http://sqlmap.org
* Завантаження: [.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
* Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues
* Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki
* Поширенні питання (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
* Демо: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
* Скриншоти: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
beep.py - Make a beep sound beep.py - Make a beep sound
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
cloak.py - Simple file encryption/compression utility cloak.py - Simple file encryption/compression utility
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
dbgtool.py - Portable executable to ASCII debug script converter dbgtool.py - Portable executable to ASCII debug script converter
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -3,7 +3,7 @@
""" """
safe2bin.py - Simple safe(hex) to binary format converter safe2bin.py - Simple safe(hex) to binary format converter
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) # Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission # See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files # Removes duplicate entries in wordlist like files
+10
View File
@@ -1,5 +1,15 @@
#!/bin/bash #!/bin/bash
: '
cat > .git/hooks/post-commit << EOF
#!/bin/bash
source ./extra/shutils/postcommit-hook.sh
EOF
chmod +x .git/hooks/post-commit
'
SETTINGS="../../lib/core/settings.py" SETTINGS="../../lib/core/settings.py"
declare -x SCRIPTPATH="${0}" declare -x SCRIPTPATH="${0}"
+10
View File
@@ -1,5 +1,15 @@
#!/bin/bash #!/bin/bash
: '
cat > .git/hooks/pre-commit << EOF
#!/bin/bash
source ./extra/shutils/precommit-hook.sh
EOF
chmod +x .git/hooks/pre-commit
'
PROJECT="../../" PROJECT="../../"
SETTINGS="../../lib/core/settings.py" SETTINGS="../../lib/core/settings.py"
CHECKSUM="../../txt/checksum.md5" CHECKSUM="../../txt/checksum.md5"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) # Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission # See the file 'LICENSE' for copying permission
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle) # Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
+2 -2
View File
@@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -61,7 +61,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) # Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission # See the file 'LICENSE' for copying permission
import codecs import codecs
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+4 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -99,7 +99,7 @@ def main():
WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower()) WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower())
print colorize("[i] %d WAF scripts loaded" % len(WAF_FUNCTIONS)) print colorize("[i] checking '%s'..." % sys.argv[1])
found = False found = False
for function, product in WAF_FUNCTIONS: for function, product in WAF_FUNCTIONS:
@@ -115,5 +115,7 @@ def main():
print print
exit(int(not found))
if __name__ == "__main__": if __name__ == "__main__":
main() main()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+30 -17
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -69,11 +69,14 @@ from lib.core.enums import NULLCONNECTION
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import REDIRECTION from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapNoneDataException from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
from lib.core.settings import CHECK_INTERNET_ADDRESS from lib.core.settings import CHECK_INTERNET_ADDRESS
from lib.core.settings import CHECK_INTERNET_VALUE from lib.core.settings import CHECK_INTERNET_VALUE
@@ -89,6 +92,7 @@ from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
@@ -360,7 +364,7 @@ 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) 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
@@ -471,13 +475,13 @@ 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) 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) 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
@@ -859,8 +863,8 @@ def heuristicCheckDbms(injection):
if conf.noEscape and dbms not in FROM_DUMMY_TABLE: if conf.noEscape and dbms not in FROM_DUMMY_TABLE:
continue continue
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)): if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)): 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
@@ -1049,9 +1053,19 @@ def heuristicCheckSqlInjection(place, parameter):
kb.heuristicTest = HEURISTIC_TEST.CASTED if casting else HEURISTIC_TEST.NEGATIVE if not result else HEURISTIC_TEST.POSITIVE kb.heuristicTest = HEURISTIC_TEST.CASTED if casting else HEURISTIC_TEST.NEGATIVE if not result else HEURISTIC_TEST.POSITIVE
if casting: if casting:
errMsg = "possible %s casting " % ("integer" if origValue.isdigit() else "type") errMsg = "possible %s casting detected (e.g. '" % ("integer" if origValue.isdigit() else "type")
errMsg += "detected (e.g. \"$%s=intval($_REQUEST['%s'])\") " % (parameter, parameter)
errMsg += "at the back-end web application" platform = conf.url.split('.')[-1].lower()
if platform == WEB_PLATFORM.ASP:
errMsg += "%s=CInt(request.querystring(\"%s\"))" % (parameter, parameter)
elif platform == WEB_PLATFORM.ASPX:
errMsg += "int.TryParse(Request.QueryString[\"%s\"], out %s)" % (parameter, parameter)
elif platform == WEB_PLATFORM.JSP:
errMsg += "%s=Integer.parseInt(request.getParameter(\"%s\"))" % (parameter, parameter)
else:
errMsg += "$%s=intval($_REQUEST[\"%s\"])" % (parameter, parameter)
errMsg += "') at the back-end web application"
logger.error(errMsg) logger.error(errMsg)
if kb.ignoreCasted is None: if kb.ignoreCasted is None:
@@ -1116,14 +1130,6 @@ def checkDynParam(place, parameter, value):
try: try:
payload = agent.payload(place, parameter, value, getUnicode(randInt)) payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False) dynResult = Request.queryPage(payload, place, raise404=False)
if not dynResult:
infoMsg = "confirming that %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg)
randInt = randomInt()
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
except SqlmapConnectionException: except SqlmapConnectionException:
pass pass
@@ -1355,9 +1361,11 @@ def checkWaf():
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload)) value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
pushValue(kb.redirectChoice) pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect)
pushValue(conf.timeout) pushValue(conf.timeout)
kb.redirectChoice = REDIRECTION.YES kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IDS_WAF_CHECK_TIMEOUT conf.timeout = IDS_WAF_CHECK_TIMEOUT
try: try:
@@ -1368,6 +1376,7 @@ def checkWaf():
kb.matchRatio = None kb.matchRatio = None
conf.timeout = popValue() conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue() kb.redirectChoice = popValue()
if retVal: if retVal:
@@ -1537,6 +1546,10 @@ def checkConnection(suppressOutput=False):
errMsg = "problem occurred while " errMsg = "problem occurred while "
errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex)) errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
except UnicodeError, ex:
errMsg = "problem occurred while "
errMsg += "handling a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapDataException(errMsg)
if not suppressOutput and not conf.dummy and not conf.offline: if not suppressOutput and not conf.dummy and not conf.offline:
infoMsg = "testing connection to the target URL" infoMsg = "testing connection to the target URL"
+26 -12
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -56,9 +56,11 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapNotVulnerableException from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSilentQuitException from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException from lib.core.exception import SqlmapValueException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import ASP_NET_CONTROL_REGEX from lib.core.settings import ASP_NET_CONTROL_REGEX
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS from lib.core.settings import IGNORE_PARAMETERS
@@ -69,6 +71,7 @@ from lib.core.settings import REFERER_ALIASES
from lib.core.settings import USER_AGENT_ALIASES from lib.core.settings import USER_AGENT_ALIASES
from lib.core.target import initTargetEnv from lib.core.target import initTargetEnv
from lib.core.target import setupTargetEnv from lib.core.target import setupTargetEnv
from lib.utils.hash import crackHashFile
def _selectInjection(): def _selectInjection():
""" """
@@ -243,16 +246,20 @@ def _saveToResultsFile():
results[key].extend(injection.data.keys()) results[key].extend(injection.data.keys())
for key, value in results.items(): try:
place, parameter, notes = key for key, value in results.items():
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) place, parameter, notes = key
conf.resultsFP.write(line) 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)
if not results: if not results:
line = "%s,,,,%s" % (conf.url, os.linesep) line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line) conf.resultsFP.write(line)
conf.resultsFP.flush() conf.resultsFP.flush()
except IOError, ex:
errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFilename, getSafeExString(ex))
raise SqlmapSystemException(errMsg)
@stackedmethod @stackedmethod
def start(): def start():
@@ -262,6 +269,9 @@ def start():
check if they are dynamic and SQL injection affected check if they are dynamic and SQL injection affected
""" """
if conf.hashFile:
crackHashFile(conf.hashFile)
if conf.direct: if conf.direct:
initTargetEnv() initTargetEnv()
setupTargetEnv() setupTargetEnv()
@@ -307,6 +317,7 @@ def start():
conf.cookie = targetCookie conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders) conf.httpHeaders = list(initialHeaders)
conf.httpHeaders.extend(targetHeaders or []) conf.httpHeaders.extend(targetHeaders or [])
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()
@@ -498,14 +509,14 @@ def start():
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter) infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
elif parameter == conf.csrfToken: elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I):
testSqlInj = False testSqlInj = False
infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter
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 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 %s parameter '%s'" % (paramType, parameter) infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
@@ -524,7 +535,7 @@ def start():
testSqlInj = False testSqlInj = False
else: else:
infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter) infoMsg = "%s parameter '%s' appears to be dynamic" % (paramType, parameter)
logger.info(infoMsg) logger.info(infoMsg)
kb.testedParams.add(paramKey) kb.testedParams.add(paramKey)
@@ -631,6 +642,9 @@ def start():
errMsg += "involved (e.g. WAF) maybe you could try to use " errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')" errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
if not conf.randomAgent:
errMsg += " and/or switch '--random-agent'"
raise SqlmapNotVulnerableException(errMsg.rstrip('.')) raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else: else:
# Flush the flag # Flush the flag
+30 -13
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -10,6 +10,7 @@ from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.dicts import DBMS_DICT from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import MSSQL_ALIASES from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES from lib.core.settings import ORACLE_ALIASES
@@ -21,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES from lib.core.settings import INFORMIX_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy from lib.utils.sqlalchemy import SQLAlchemy
@@ -46,6 +48,8 @@ from plugins.dbms.db2 import DB2Map
from plugins.dbms.db2.connector import Connector as DB2Conn from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.hsqldb import HSQLDBMap from plugins.dbms.hsqldb import HSQLDBMap
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
from plugins.dbms.h2 import H2Map
from plugins.dbms.h2.connector import Connector as H2Conn
from plugins.dbms.informix import InformixMap from plugins.dbms.informix import InformixMap
from plugins.dbms.informix.connector import Connector as InformixConn from plugins.dbms.informix.connector import Connector as InformixConn
@@ -67,6 +71,7 @@ def setHandler():
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn), (DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn), (DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn), (DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn), (DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
] ]
@@ -90,29 +95,41 @@ def setHandler():
conf.dbmsConnector = Connector() conf.dbmsConnector = Connector()
if conf.direct: if conf.direct:
exception = None
dialect = DBMS_DICT[dbms][3] dialect = DBMS_DICT[dbms][3]
if dialect: if dialect:
sqlalchemy = SQLAlchemy(dialect=dialect) try:
sqlalchemy.connect() sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
if sqlalchemy.connector: if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy conf.dbmsConnector = sqlalchemy
else: except Exception, ex:
try: exception = ex
conf.dbmsConnector.connect()
except NameError: if not dialect or exception:
pass try:
else: conf.dbmsConnector.connect()
conf.dbmsConnector.connect() except Exception, ex:
if exception:
raise exception
else:
if not isinstance(ex, NameError):
raise
else:
msg = "support for direct connection to '%s' is not available. " % dbms
msg += "Please rerun with '--dependencies'"
raise SqlmapConnectionException(msg)
if conf.forceDbms == dbms or handler.checkDbms(): if conf.forceDbms == dbms or handler.checkDbms():
if kb.resolutionDbms: if kb.resolutionDbms:
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]() conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
conf.dbmsHandler._dbms = kb.resolutionDbms
else: else:
conf.dbmsHandler = handler conf.dbmsHandler = handler
conf.dbmsHandler._dbms = dbms
conf.dbmsHandler._dbms = dbms
break break
else: else:
conf.dbmsConnector = None conf.dbmsConnector = None
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+11 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -43,6 +43,7 @@ from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import NULL from lib.core.settings import NULL
from lib.core.settings import PAYLOAD_DELIMITER from lib.core.settings import PAYLOAD_DELIMITER
from lib.core.settings import REPLACEMENT_MARKER from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.unescaper import unescaper from lib.core.unescaper import unescaper
@@ -246,6 +247,9 @@ class Agent(object):
else: else:
query = kb.injection.prefix or prefix or "" query = kb.injection.prefix or prefix or ""
if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes
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 += " "
@@ -345,6 +349,7 @@ class Agent(object):
if payload: if payload:
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec)) payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)): for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)):
payload = payload.replace(_, str(randomInt())) payload = payload.replace(_, str(randomInt()))
@@ -619,7 +624,7 @@ class Agent(object):
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): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2):
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
@@ -818,7 +823,7 @@ class Agent(object):
limitRegExp2 = None limitRegExp2 = None
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit): if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
@@ -908,14 +913,14 @@ 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): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.HSQLDB): elif Backend.isDbms(DBMS.HSQLDB):
match = re.search(r"ORDER BY [^ ]+", limitedQuery) match = re.search(r"ORDER BY [^ ]+", limitedQuery)
if match: if match:
limitedQuery = re.sub(r"\s*%s\s*" % match.group(0), " ", limitedQuery).strip() limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
limitedQuery += " %s" % match.group(0) limitedQuery += " %s" % match.group(0)
if query.startswith("SELECT "): if query.startswith("SELECT "):
@@ -1089,7 +1094,7 @@ class Agent(object):
if conf.dumpWhere and query: if conf.dumpWhere and query:
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "") prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
if "%s)" % conf.tbl.upper() in prefix.upper(): if conf.tbl and "%s)" % conf.tbl.upper() in prefix.upper():
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix) prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
elif re.search(r"(?i)\bWHERE\b", prefix): elif re.search(r"(?i)\bWHERE\b", prefix):
prefix += " AND %s" % conf.dumpWhere prefix += " AND %s" % conf.dumpWhere
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+62 -43
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -165,7 +165,6 @@ from lib.core.settings import URI_QUESTION_MARKER
from lib.core.settings import URLENCODE_CHAR_LIMIT from lib.core.settings import URLENCODE_CHAR_LIMIT
from lib.core.settings import URLENCODE_FAILSAFE_CHARS from lib.core.settings import URLENCODE_FAILSAFE_CHARS
from lib.core.settings import USER_AGENT_ALIASES from lib.core.settings import USER_AGENT_ALIASES
from lib.core.settings import VERSION
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
from lib.core.settings import WEBSCARAB_SPLITTER from lib.core.settings import WEBSCARAB_SPLITTER
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
@@ -601,7 +600,7 @@ def paramToDict(place, parameters=None):
if condition: if condition:
testableParameters[parameter] = "=".join(parts[1:]) testableParameters[parameter] = "=".join(parts[1:])
if not conf.multipleTargets and not (conf.csrfToken and parameter == conf.csrfToken): if not conf.multipleTargets and not (conf.csrfToken and re.search(conf.csrfToken, parameter, re.I)):
_ = urldecode(testableParameters[parameter], convall=True) _ = urldecode(testableParameters[parameter], convall=True)
if (_.endswith("'") and _.count("'") == 1 or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX): if (_.endswith("'") and _.count("'") == 1 or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
warnMsg = "it appears that you have provided tainted parameter values " warnMsg = "it appears that you have provided tainted parameter values "
@@ -646,7 +645,7 @@ def paramToDict(place, parameters=None):
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER) current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
else: else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER) current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized), parameters) candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized, separators=(',', ':') if ", " not in testableParameters[parameter] else None), parameters)
current[key] = original current[key] = original
deserialized = json.loads(testableParameters[parameter]) deserialized = json.loads(testableParameters[parameter])
@@ -900,7 +899,7 @@ def clearColors(message):
retVal = message retVal = message
if message: if isinstance(message, str):
retVal = re.sub(r"\x1b\[[\d;]+m", "", message) retVal = re.sub(r"\x1b\[[\d;]+m", "", message)
return retVal return retVal
@@ -924,7 +923,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
try: try:
if conf.get("api"): if conf.get("api"):
sys.stdout.write(message, status, content_type) sys.stdout.write(clearColors(message), status, content_type)
else: else:
sys.stdout.write(setColor(message, bold=bold)) sys.stdout.write(setColor(message, bold=bold))
@@ -1199,7 +1198,7 @@ def banner():
This function prints sqlmap banner with its version This function prints sqlmap banner with its version
""" """
if not any(_ in sys.argv for _ in ("--version", "--api")): if not any(_ in sys.argv for _ in ("--version", "--api")) and not conf.get("disableBanner"):
_ = BANNER _ = BANNER
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv: if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
@@ -1408,8 +1407,10 @@ def parseTargetDirect():
__import__("pyodbc") __import__("pyodbc")
elif dbmsName == DBMS.FIREBIRD: elif dbmsName == DBMS.FIREBIRD:
__import__("kinterbasdb") __import__("kinterbasdb")
except (SqlmapSyntaxException, SqlmapMissingDependence):
raise
except: except:
if _sqlalchemy and data[3] in _sqlalchemy.dialects.__all__: if _sqlalchemy and data[3] and any(_ in _sqlalchemy.dialects.__all__ for _ in (data[3], data[3].split('+')[0])):
pass pass
else: else:
errMsg = "sqlmap requires '%s' third-party library " % data[1] errMsg = "sqlmap requires '%s' third-party library " % data[1]
@@ -2120,6 +2121,16 @@ def readXmlFile(xmlFile):
return retVal return retVal
def average(values):
"""
Computes the arithmetic mean of a list of numbers.
>>> average([0.9, 0.9, 0.9, 1.0, 0.8, 0.9])
0.9
"""
return (sum(values) / len(values)) if values else None
@cachedmethod @cachedmethod
def stdev(values): def stdev(values):
""" """
@@ -2134,19 +2145,9 @@ def stdev(values):
return None return None
else: else:
avg = average(values) avg = average(values)
_ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0) _ = 1.0 * sum(pow((_ or 0) - avg, 2) for _ in values)
return sqrt(_ / (len(values) - 1)) return sqrt(_ / (len(values) - 1))
def average(values):
"""
Computes the arithmetic mean of a list of numbers.
>>> average([0.9, 0.9, 0.9, 1.0, 0.8, 0.9])
0.9
"""
return (sum(values) / len(values)) if values else None
def calculateDeltaSeconds(start): def calculateDeltaSeconds(start):
""" """
Returns elapsed time from start till now Returns elapsed time from start till now
@@ -3371,7 +3372,7 @@ def getLatestRevision():
""" """
Retrieves latest revision from the offical repository Retrieves latest revision from the offical repository
>>> getLatestRevision() == VERSION >>> from lib.core.settings import VERSION; getLatestRevision() == VERSION
True True
""" """
@@ -3482,6 +3483,9 @@ def maskSensitiveData(msg):
for match in re.finditer(r"(?i)[ -]-(u|url|data|cookie)( |=)(.*?)(?= -?-[a-z]|\Z)", retVal): for match in re.finditer(r"(?i)[ -]-(u|url|data|cookie)( |=)(.*?)(?= -?-[a-z]|\Z)", retVal):
retVal = retVal.replace(match.group(3), '*' * len(match.group(3))) retVal = retVal.replace(match.group(3), '*' * len(match.group(3)))
# Fail-safe substitution
retVal = re.sub(r"(?i)\bhttps?://[^ ]+", lambda match: '*' * len(match.group(0)), retVal)
if getpass.getuser(): if getpass.getuser():
retVal = re.sub(r"(?i)\b%s\b" % re.escape(getpass.getuser()), '*' * len(getpass.getuser()), retVal) retVal = re.sub(r"(?i)\b%s\b" % re.escape(getpass.getuser()), '*' * len(getpass.getuser()), retVal)
@@ -3505,9 +3509,9 @@ def listToStrValue(value):
return retVal return retVal
def intersect(valueA, valueB, lowerCase=False): def intersect(containerA, containerB, lowerCase=False):
""" """
Returns intersection of the array-ized values Returns intersection of the container-ized values
>>> intersect([1, 2, 3], set([1,3])) >>> intersect([1, 2, 3], set([1,3]))
[1, 3] [1, 3]
@@ -3515,15 +3519,15 @@ def intersect(valueA, valueB, lowerCase=False):
retVal = [] retVal = []
if valueA and valueB: if containerA and containerB:
valueA = arrayizeValue(valueA) containerA = arrayizeValue(containerA)
valueB = arrayizeValue(valueB) containerB = arrayizeValue(containerB)
if lowerCase: if lowerCase:
valueA = [val.lower() if isinstance(val, basestring) else val for val in valueA] containerA = [val.lower() if isinstance(val, basestring) else val for val in containerA]
valueB = [val.lower() if isinstance(val, basestring) else val for val in valueB] containerB = [val.lower() if isinstance(val, basestring) else val for val in containerB]
retVal = [val for val in valueA if val in valueB] retVal = [val for val in containerA if val in containerB]
return retVal return retVal
@@ -3543,7 +3547,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
return value return value
payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True)) payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", REFLECTED_REPLACEMENT_REGEX.encode("string-escape"))) regex = _(filterStringValue(payload, r"[A-Za-z0-9]", REFLECTED_REPLACEMENT_REGEX.encode("string_escape")))
if regex != payload: if regex != payload:
if all(part.lower() in content.lower() for part in filter(None, regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check if all(part.lower() in content.lower() for part in filter(None, regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check
@@ -3650,16 +3654,20 @@ def safeSQLIdentificatorNaming(name, isTable=False):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
retVal = "`%s`" % retVal retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX):
retVal = "\"%s\"" % retVal retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.upper() retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE): elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
parts = retVal.split('.', 1) if isTable:
for i in xrange(len(parts)): parts = retVal.split('.', 1)
if ((parts[i] or " ")[0].isdigit() or not re.match(r"\A\w+\Z", parts[i], re.U)): for i in xrange(len(parts)):
parts[i] = "[%s]" % parts[i] if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
retVal = '.'.join(parts) parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal): if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal) retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -4112,7 +4120,12 @@ def checkSameHost(*urls):
elif len(urls) == 1: elif len(urls) == 1:
return True return True
else: else:
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(':')[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(':')[0]) for url in urls[1:]) def _(value):
if value and not re.search(r"\A\w+://", value):
value = "http://%s" % value
return value
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(_(url) or "").netloc.split(':')[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(_(urls[0]) or "").netloc.split(':')[0]) for url in urls[1:])
def getHostHeader(url): def getHostHeader(url):
""" """
@@ -4276,7 +4289,7 @@ def decodeHexValue(value, raw=False):
retVal = retVal.decode("utf-16-le") retVal = retVal.decode("utf-16-le")
except UnicodeDecodeError: except UnicodeDecodeError:
pass pass
elif Backend.isDbms(DBMS.HSQLDB): elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.H2):
try: try:
retVal = retVal.decode("utf-16-be") retVal = retVal.decode("utf-16-be")
except UnicodeDecodeError: except UnicodeDecodeError:
@@ -4334,19 +4347,23 @@ def hashDBWrite(key, value, serialize=False):
Helper function for writing session data to HashDB Helper function for writing session data to HashDB
""" """
_ = '|'.join((str(_) if not isinstance(_, basestring) else _) for _ in (conf.hostname, conf.path.strip('/') if conf.path is not None else conf.port, key, HASHDB_MILESTONE_VALUE)) if conf.hashDB:
conf.hashDB.write(_, value, serialize) _ = '|'.join((str(_) if not isinstance(_, basestring) else _) for _ in (conf.hostname, conf.path.strip('/') if conf.path is not None else conf.port, key, HASHDB_MILESTONE_VALUE))
conf.hashDB.write(_, value, serialize)
def hashDBRetrieve(key, unserialize=False, checkConf=False): def hashDBRetrieve(key, unserialize=False, checkConf=False):
""" """
Helper function for restoring session data from HashDB Helper function for restoring session data from HashDB
""" """
_ = '|'.join((str(_) if not isinstance(_, basestring) else _) for _ in (conf.hostname, conf.path.strip('/') if conf.path is not None else conf.port, key, HASHDB_MILESTONE_VALUE)) retVal = None
retVal = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any((conf.flushSession, conf.freshQueries))) else None
if not kb.inferenceMode and not kb.fileReadMode and isinstance(retVal, basestring) and any(_ in retVal for _ in (PARTIAL_VALUE_MARKER, PARTIAL_HEX_VALUE_MARKER)): if conf.hashDB:
retVal = None _ = '|'.join((str(_) if not isinstance(_, basestring) else _) for _ in (conf.hostname, conf.path.strip('/') if conf.path is not None else conf.port, key, HASHDB_MILESTONE_VALUE))
retVal = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any((conf.flushSession, conf.freshQueries))) else None
if not kb.inferenceMode and not kb.fileReadMode and isinstance(retVal, basestring) and any(_ in retVal for _ in (PARTIAL_VALUE_MARKER, PARTIAL_HEX_VALUE_MARKER)):
retVal = None
return retVal return retVal
@@ -4728,6 +4745,8 @@ def getSafeExString(ex, encoding=None):
retVal = ex.message retVal = ex.message
elif getattr(ex, "msg", None): elif getattr(ex, "msg", None):
retVal = ex.msg retVal = ex.msg
elif isinstance(ex, (list, tuple)) and len(ex) > 1 and isinstance(ex[1], basestring):
retVal = ex[1]
return getUnicode(retVal or "", encoding=encoding).strip() return getUnicode(retVal or "", encoding=encoding).strip()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+8 -1
View File
@@ -1,10 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import functools
import hashlib import hashlib
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
@@ -16,6 +17,7 @@ def cachedmethod(f, cache={}):
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/ Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
""" """
@functools.wraps(f)
def _(*args, **kwargs): def _(*args, **kwargs):
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
if key not in cache: if key not in cache:
@@ -26,6 +28,11 @@ def cachedmethod(f, cache={}):
return _ return _
def stackedmethod(f): def stackedmethod(f):
"""
Method using pushValue/popValue functions (fallback function for stack realignment)
"""
@functools.wraps(f)
def _(*args, **kwargs): def _(*args, **kwargs):
threadData = getCurrentThreadData() threadData = getCurrentThreadData()
originalLevel = len(threadData.valueStack) originalLevel = len(threadData.valueStack)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+3 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -22,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES from lib.core.settings import INFORMIX_ALIASES
FIREBIRD_TYPES = { FIREBIRD_TYPES = {
@@ -195,6 +196,7 @@ DBMS_DICT = {
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/ & http://jpype.sourceforge.net/", None), DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", 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"),
} }
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -171,7 +171,7 @@ class Dump(object):
def currentDb(self, data): def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB): if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current schema (equivalent to database 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)
+8 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -43,6 +43,7 @@ class DBMS:
SQLITE = "SQLite" SQLITE = "SQLite"
SYBASE = "Sybase" SYBASE = "Sybase"
HSQLDB = "HSQLDB" HSQLDB = "HSQLDB"
H2 = "H2"
INFORMIX = "Informix" INFORMIX = "Informix"
class DBMS_DIRECTORY_NAME: class DBMS_DIRECTORY_NAME:
@@ -57,6 +58,7 @@ class DBMS_DIRECTORY_NAME:
SQLITE = "sqlite" SQLITE = "sqlite"
SYBASE = "sybase" SYBASE = "sybase"
HSQLDB = "hsqldb" HSQLDB = "hsqldb"
H2 = "h2"
INFORMIX = "informix" INFORMIX = "informix"
class CUSTOM_LOGGING: class CUSTOM_LOGGING:
@@ -308,7 +310,7 @@ class ADJUST_TIME_DELAY:
NO = 0 NO = 0
YES = 1 YES = 1
class WEB_API: class WEB_PLATFORM:
PHP = "php" PHP = "php"
ASP = "asp" ASP = "asp"
ASPX = "aspx" ASPX = "aspx"
@@ -376,3 +378,7 @@ class TIMEOUT_STATE:
NORMAL = 0 NORMAL = 0
EXCEPTION = 1 EXCEPTION = 1
TIMEOUT = 2 TIMEOUT = 2
class HINT:
PREPEND = 0
APPEND = 1
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+55 -27
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -45,7 +45,6 @@ from lib.core.common import ntToPosixSlashes
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import parseRequestFile from lib.core.common import parseRequestFile
from lib.core.common import parseTargetDirect from lib.core.common import parseTargetDirect
from lib.core.common import parseTargetUrl
from lib.core.common import paths from lib.core.common import paths
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import readCachedFileContent from lib.core.common import readCachedFileContent
@@ -83,6 +82,7 @@ from lib.core.enums import PROXY_TYPE
from lib.core.enums import REFLECTIVE_COUNTER from lib.core.enums import REFLECTIVE_COUNTER
from lib.core.enums import WIZARD from lib.core.enums import WIZARD
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapFilePathException from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapInstallationException from lib.core.exception import SqlmapInstallationException
@@ -103,8 +103,8 @@ from lib.core.settings import DBMS_ALIASES
from lib.core.settings import DEFAULT_PAGE_ENCODING from lib.core.settings import DEFAULT_PAGE_ENCODING
from lib.core.settings import DEFAULT_TOR_HTTP_PORTS from lib.core.settings import DEFAULT_TOR_HTTP_PORTS
from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import DUMMY_URL from lib.core.settings import DUMMY_URL
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import KB_CHARS_BOUNDARY_CHAR from lib.core.settings import KB_CHARS_BOUNDARY_CHAR
from lib.core.settings import KB_CHARS_LOW_FREQUENCY_ALPHABET from lib.core.settings import KB_CHARS_LOW_FREQUENCY_ALPHABET
@@ -114,7 +114,6 @@ from lib.core.settings import MAX_NUMBER_OF_THREADS
from lib.core.settings import NULL from lib.core.settings import NULL
from lib.core.settings import PARAMETER_SPLITTING_REGEX from lib.core.settings import PARAMETER_SPLITTING_REGEX
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
from lib.core.settings import SITE
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
from lib.core.settings import SUPPORTED_DBMS from lib.core.settings import SUPPORTED_DBMS
@@ -124,7 +123,6 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNION_CHAR_REGEX from lib.core.settings import UNION_CHAR_REGEX
from lib.core.settings import UNKNOWN_DBMS_VERSION from lib.core.settings import UNKNOWN_DBMS_VERSION
from lib.core.settings import URI_INJECTABLE_REGEX from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import VERSION_STRING
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from lib.core.threads import setDaemon from lib.core.threads import setDaemon
from lib.core.update import update from lib.core.update import update
@@ -895,6 +893,12 @@ def _setSocketPreConnect():
family, type, proto, address = key family, type, proto, address = key
s = socket.socket(family, type, proto) s = socket.socket(family, type, proto)
s._connect(address) s._connect(address)
try:
if type == socket.SOCK_STREAM:
# Reference: https://www.techrepublic.com/article/tcp-ip-options-for-high-performance-data-transmission/
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
except:
pass
with kb.locks.socket: with kb.locks.socket:
socket._ready[key].append((s._sock, time.time())) socket._ready[key].append((s._sock, time.time()))
except KeyboardInterrupt: except KeyboardInterrupt:
@@ -1073,7 +1077,7 @@ def _setSafeVisit():
key, value = line.split(':', 1) key, value = line.split(':', 1)
value = value.strip() value = value.strip()
kb.safeReq.headers[key] = value kb.safeReq.headers[key] = value
if key == HTTP_HEADER.HOST: if key.upper() == HTTP_HEADER.HOST.upper():
if not value.startswith("http"): if not value.startswith("http"):
scheme = "http" scheme = "http"
if value.endswith(":443"): if value.endswith(":443"):
@@ -1258,14 +1262,6 @@ 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 _defaultHTTPUserAgent():
"""
@return: default sqlmap HTTP User-Agent header
@rtype: C{str}
"""
return "%s (%s)" % (VERSION_STRING, SITE)
def _setHTTPUserAgent(): def _setHTTPUserAgent():
""" """
Set the HTTP User-Agent header. Set the HTTP User-Agent header.
@@ -1305,12 +1301,12 @@ def _setHTTPUserAgent():
_ = True _ = True
for header, _ in conf.httpHeaders: for header, _ in conf.httpHeaders:
if header == HTTP_HEADER.USER_AGENT: if header.upper() == HTTP_HEADER.USER_AGENT.upper():
_ = False _ = False
break break
if _: if _:
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent())) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
else: else:
if not kb.userAgents: if not kb.userAgents:
@@ -1325,10 +1321,10 @@ def _setHTTPUserAgent():
warnMsg += "file '%s'" % paths.USER_AGENTS warnMsg += "file '%s'" % paths.USER_AGENTS
logger.warn(warnMsg) logger.warn(warnMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent())) conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
return return
userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0] userAgent = random.sample(kb.userAgents or [DEFAULT_USER_AGENT], 1)[0]
infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent
infoMsg += "file '%s'" % paths.USER_AGENTS infoMsg += "file '%s'" % paths.USER_AGENTS
@@ -1369,6 +1365,19 @@ def _setHTTPCookies():
conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie)) conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie))
def _setHostname():
"""
Set value conf.hostname
"""
if conf.url:
try:
conf.hostname = urlparse.urlsplit(conf.url).netloc.split(':')[0]
except ValueError, ex:
errMsg = "problem occurred while "
errMsg += "parsing an URL '%s' ('%s')" % (conf.url, getSafeExString(ex))
raise SqlmapDataException(errMsg)
def _setHTTPTimeout(): def _setHTTPTimeout():
""" """
Set the HTTP timeout Set the HTTP timeout
@@ -1508,6 +1517,8 @@ def _cleanupOptions():
if conf.url: if conf.url:
conf.url = conf.url.strip() conf.url = conf.url.strip()
if not re.search(r"\A\w+://", conf.url):
conf.url = "http://%s" % conf.url
if conf.fileRead: if conf.fileRead:
conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead)) conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead))
@@ -1533,14 +1544,6 @@ def _cleanupOptions():
if conf.optimize: if conf.optimize:
setOptimize() setOptimize()
match = re.search(INJECT_HERE_REGEX, conf.data or "")
if match:
kb.customInjectionMark = match.group(0)
match = re.search(INJECT_HERE_REGEX, conf.url or "")
if match:
kb.customInjectionMark = match.group(0)
if conf.os: if conf.os:
conf.os = conf.os.capitalize() conf.os = conf.os.capitalize()
@@ -1565,6 +1568,23 @@ def _cleanupOptions():
except re.error: except re.error:
conf.testFilter = re.escape(conf.testFilter) conf.testFilter = re.escape(conf.testFilter)
if conf.csrfToken:
original = conf.csrfToken
try:
re.compile(conf.csrfToken)
if re.escape(conf.csrfToken) != conf.csrfToken:
message = "provided value for option '--csrf-token' is a regular expression? [Y/n] "
if not readInput(message, default='Y', boolean=True):
conf.csrfToken = re.escape(conf.csrfToken)
except re.error:
conf.csrfToken = re.escape(conf.csrfToken)
finally:
class _(unicode):
pass
conf.csrfToken = _(conf.csrfToken)
conf.csrfToken._original = original
if conf.testSkip: if conf.testSkip:
conf.testSkip = conf.testSkip.strip('*+') conf.testSkip = conf.testSkip.strip('*+')
conf.testSkip = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testSkip) conf.testSkip = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testSkip)
@@ -2251,6 +2271,10 @@ def _basicOptionValidation():
errMsg = "option '-d' is incompatible with option '-u' ('--url')" errMsg = "option '-d' is incompatible with option '-u' ('--url')"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.direct and conf.dbms:
errMsg = "option '-d' is incompatible with option '--dbms'"
raise SqlmapSyntaxException(errMsg)
if conf.identifyWaf and conf.skipWaf: if conf.identifyWaf and conf.skipWaf:
errMsg = "switch '--identify-waf' is incompatible with switch '--skip-waf'" errMsg = "switch '--identify-waf' is incompatible with switch '--skip-waf'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -2417,6 +2441,10 @@ 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.liveTest, conf.wizard, conf.dependencies, conf.purge, conf.sitemapUrl, conf.listTampers)):
errMsg = "option '--crack' should be used as a standalone"
raise SqlmapSyntaxException(errMsg)
if isinstance(conf.uCols, basestring): if isinstance(conf.uCols, basestring):
if not conf.uCols.isdigit() and ("-" not in conf.uCols or len(conf.uCols.split("-")) != 2): if not conf.uCols.isdigit() and ("-" not in conf.uCols or len(conf.uCols.split("-")) != 2):
errMsg = "value for option '--union-cols' must be a range with hyphon " errMsg = "value for option '--union-cols' must be a range with hyphon "
@@ -2486,10 +2514,10 @@ def init():
_resolveCrossReferences() _resolveCrossReferences()
_checkWebSocket() _checkWebSocket()
parseTargetUrl()
parseTargetDirect() parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)): if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)):
_setHostname()
_setHTTPTimeout() _setHTTPTimeout()
_setHTTPExtraHeaders() _setHTTPExtraHeaders()
_setHTTPCookies() _setHTTPCookies()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+17 -10
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -19,12 +19,13 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.2.10.0" VERSION = "1.3"
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 = "http://sqlmap.org" SITE = "http://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
DEV_EMAIL_ADDRESS = "[email protected]" DEV_EMAIL_ADDRESS = "[email protected]"
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new" ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git" GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
@@ -71,6 +72,7 @@ RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]" RANDOM_STRING_MARKER = "[RANDSTR]"
SLEEP_TIME_MARKER = "[SLEEPTIME]" SLEEP_TIME_MARKER = "[SLEEPTIME]"
INFERENCE_MARKER = "[INFERENCE]" INFERENCE_MARKER = "[INFERENCE]"
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__" PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
CHAR_INFERENCE_MARK = "%c" CHAR_INFERENCE_MARK = "%c"
@@ -173,6 +175,9 @@ PUSH_VALUE_EXCEPTION_RETRY_COUNT = 3
# Minimum time response set needed for time-comparison based on standard deviation # Minimum time response set needed for time-comparison based on standard deviation
MIN_TIME_RESPONSES = 30 MIN_TIME_RESPONSES = 30
# Maximum time response set used during time-comparison based on standard deviation
MAX_TIME_RESPONSES = 200
# Minimum comparison ratio set needed for searching valid union column number based on standard deviation # Minimum comparison ratio set needed for searching valid union column number based on standard deviation
MIN_UNION_RESPONSES = 5 MIN_UNION_RESPONSES = 5
@@ -236,6 +241,7 @@ 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")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin") INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -249,20 +255,21 @@ MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server") SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2") DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql") HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",)
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix") INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
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 = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + INFORMIX_ALIASES SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES
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_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))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
HOST_ALIASES = ("host",) HOST_ALIASES = ("host",)
HSQLDB_DEFAULT_SCHEMA = "PUBLIC" H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
# 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")
@@ -325,7 +332,7 @@ FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>
# Regular expressions used for parsing error messages (--parse-errors) # Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = ( ERROR_PARSING_REGEXES = (
r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)", r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)",
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>", r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>[^<]+)",
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$", r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)", r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
r"<li>Error Type:<br>(?P<result>.+?)</li>", r"<li>Error Type:<br>(?P<result>.+?)</li>",
@@ -578,7 +585,7 @@ 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", "usufrutuario", "korisnik", "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 = '&'
@@ -590,7 +597,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
FORCE_COOKIE_EXPIRATION_TIME = "9999999999" FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
# Github OAuth token used for creating an automatic Issue for unhandled exceptions # Github OAuth token used for creating an automatic Issue for unhandled exceptions
GITHUB_REPORT_OAUTH_TOKEN = "NTMyNWNkMmZkMzRlMDZmY2JkMmY0MGI4NWI0MzVlM2Q5YmFjYWNhYQ==" GITHUB_REPORT_OAUTH_TOKEN = "NTYzYjhmZWJjYzc0Njg2ODJhNzhmNDg1YzM0YzlkYjk3N2JiMzE3Nw=="
# Skip unforced HashDB flush requests below the threshold number of cached items # Skip unforced HashDB flush requests below the threshold number of cached items
HASHDB_FLUSH_THRESHOLD = 32 HASHDB_FLUSH_THRESHOLD = 32
@@ -668,7 +675,7 @@ 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") 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")
# 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")
@@ -680,7 +687,7 @@ 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", "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", "DataTypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "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") 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", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "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")
# 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>[^"]+)'
+25 -22
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -53,30 +53,33 @@ def clearHistory():
readline.clear_history() readline.clear_history()
def saveHistory(completion=None): def saveHistory(completion=None):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try: try:
with open(historyPath, "w+"): if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
pass
except:
pass pass
except:
pass
readline.set_history_length(MAX_HISTORY_LENGTH) readline.set_history_length(MAX_HISTORY_LENGTH)
try: try:
readline.write_history_file(historyPath) readline.write_history_file(historyPath)
except IOError, msg: except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg) warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg) logger.warn(warnMsg)
except KeyboardInterrupt:
pass
def loadHistory(completion=None): def loadHistory(completion=None):
if not readlineAvailable(): if not readlineAvailable():
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+23 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -44,6 +44,7 @@ from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapFilePathException from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapMissingPrivileges from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSystemException from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUserQuitException from lib.core.exception import SqlmapUserQuitException
from lib.core.option import _setDBMS from lib.core.option import _setDBMS
@@ -51,9 +52,11 @@ from lib.core.option import _setKnowledgeBaseAttributes
from lib.core.option import _setAuthCred from lib.core.option import _setAuthCred
from lib.core.settings import ASTERISK_MARKER from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import HOST_ALIASES from lib.core.settings import HOST_ALIASES
from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import JSON_RECOGNITION_REGEX from lib.core.settings import JSON_RECOGNITION_REGEX
from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX
from lib.core.settings import MULTIPART_RECOGNITION_REGEX from lib.core.settings import MULTIPART_RECOGNITION_REGEX
@@ -343,7 +346,7 @@ def _setRequestParams():
# Url encoding of the header values should be avoided # Url encoding of the header values should be avoided
# Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value # Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value
if httpHeader.title() == HTTP_HEADER.USER_AGENT: if httpHeader.upper() == HTTP_HEADER.USER_AGENT.upper():
conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue) conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True)))
@@ -352,7 +355,7 @@ def _setRequestParams():
conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue} conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue}
testableParameters = True testableParameters = True
elif httpHeader.title() == HTTP_HEADER.REFERER: elif httpHeader.upper() == HTTP_HEADER.REFERER.upper():
conf.parameters[PLACE.REFERER] = urldecode(headerValue) conf.parameters[PLACE.REFERER] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True)))
@@ -361,7 +364,7 @@ def _setRequestParams():
conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue} conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue}
testableParameters = True testableParameters = True
elif httpHeader.title() == HTTP_HEADER.HOST: elif httpHeader.upper() == HTTP_HEADER.HOST.upper():
conf.parameters[PLACE.HOST] = urldecode(headerValue) conf.parameters[PLACE.HOST] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True))) condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True)))
@@ -390,8 +393,8 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg) raise SqlmapGenericException(errMsg)
if conf.csrfToken: if conf.csrfToken:
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(conf.csrfToken), conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}): if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(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, {}):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken 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)
else: else:
@@ -405,7 +408,10 @@ def _setRequestParams():
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):
conf.csrfToken = getUnicode(parameter) class _(unicode):
pass
conf.csrfToken = _(re.escape(getUnicode(parameter)))
conf.csrfToken._original = getUnicode(parameter)
break break
def _setHashDB(): def _setHashDB():
@@ -466,7 +472,13 @@ def _resumeDBMS():
value = hashDBRetrieve(HASHDB_KEYS.DBMS) value = hashDBRetrieve(HASHDB_KEYS.DBMS)
if not value: if not value:
return if conf.offline:
errMsg = "unable to continue in offline mode "
errMsg += "because of lack of usable "
errMsg += "session data"
raise SqlmapNoneDataException(errMsg)
else:
return
dbms = value.lower() dbms = value.lower()
dbmsVersion = [UNKNOWN_DBMS_VERSION] dbmsVersion = [UNKNOWN_DBMS_VERSION]
@@ -745,6 +757,9 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original) setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
kb.postSpaceToPlus = '+' in original kb.postSpaceToPlus = '+' in original
match = re.search(INJECT_HERE_REGEX, conf.data or "") or re.search(INJECT_HERE_REGEX, conf.url or "")
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv(): def setupTargetEnv():
_createTargetDirs() _createTargetDirs()
_setRequestParams() _setRequestParams()
+35 -31
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -17,6 +17,7 @@ import traceback
from extra.beep.beep import beep from extra.beep.beep import beep
from lib.controller.controller import start from lib.controller.controller import start
from lib.core.common import checkIntegrity
from lib.core.common import clearConsoleLine from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import getUnicode from lib.core.common import getUnicode
@@ -51,41 +52,44 @@ def smokeTest():
retVal = True retVal = True
count, length = 0, 0 count, length = 0, 0
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH): if not checkIntegrity():
if any(_ in root for _ in ("thirdparty", "extra")): retVal = False
continue else:
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
for filename in files: for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py": if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
length += 1 length += 1
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH): for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")): if any(_ in root for _ in ("thirdparty", "extra")):
continue continue
for filename in files: for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py": if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
path = os.path.join(root, os.path.splitext(filename)[0]) path = os.path.join(root, os.path.splitext(filename)[0])
path = path.replace(paths.SQLMAP_ROOT_PATH, '.') path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
path = path.replace(os.sep, '.').lstrip('.') path = path.replace(os.sep, '.').lstrip('.')
try: try:
__import__(path) __import__(path)
module = sys.modules[path] module = sys.modules[path]
except Exception, msg: except Exception, msg:
retVal = False
dataToStdout("\r")
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), msg)
logger.error(errMsg)
else:
# Run doc tests
# Reference: http://docs.python.org/library/doctest.html
(failure_count, test_count) = doctest.testmod(module)
if failure_count > 0:
retVal = False retVal = False
dataToStdout("\r")
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), msg)
logger.error(errMsg)
else:
# Run doc tests
# Reference: http://docs.python.org/library/doctest.html
(failure_count, test_count) = doctest.testmod(module)
if failure_count > 0:
retVal = False
count += 1 count += 1
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length)) status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status)) dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
clearConsoleLine() clearConsoleLine()
if retVal: if retVal:
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -92,7 +92,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
kb.threadException = True kb.threadException = True
raise raise
except Exception, ex: except Exception, ex:
if not silent: if not silent and kb.get("threadContinue"):
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message)) logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.get("verbose") > 1: if conf.get("verbose") > 1:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+13 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -99,16 +99,16 @@ def cmdLineParser(argv=None):
help="Force usage of given HTTP method (e.g. PUT)") help="Force usage of given HTTP method (e.g. PUT)")
request.add_option("--data", dest="data", request.add_option("--data", dest="data",
help="Data string to be sent through POST") help="Data string to be sent through POST (e.g. \"id=1\")")
request.add_option("--param-del", dest="paramDel", request.add_option("--param-del", dest="paramDel",
help="Character used for splitting parameter values") help="Character used for splitting parameter values (e.g. &)")
request.add_option("--cookie", dest="cookie", request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header value") help="HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\")")
request.add_option("--cookie-del", dest="cookieDel", request.add_option("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values") help="Character used for splitting cookie values (e.g. ;)")
request.add_option("--load-cookies", dest="loadCookies", request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format") help="File containing cookies in Netscape/wget format")
@@ -144,7 +144,7 @@ def cmdLineParser(argv=None):
help="HTTP authentication PEM cert/private key file") help="HTTP authentication PEM cert/private key file")
request.add_option("--ignore-code", dest="ignoreCode", type="int", request.add_option("--ignore-code", dest="ignoreCode", type="int",
help="Ignore HTTP error code (e.g. 401)") help="Ignore (problematic) HTTP error code (e.g. 401)")
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true", request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
help="Ignore system default proxy settings") help="Ignore system default proxy settings")
@@ -617,7 +617,7 @@ def cmdLineParser(argv=None):
help="Run host OS command(s) when SQL injection is found") help="Run host OS command(s) when SQL injection is found")
miscellaneous.add_option("--answers", dest="answers", miscellaneous.add_option("--answers", dest="answers",
help="Set question answers (e.g. \"quit=N,follow=N\")") help="Set predefined answers (e.g. \"quit=N,follow=N\")")
miscellaneous.add_option("--beep", dest="beep", action="store_true", miscellaneous.add_option("--beep", dest="beep", action="store_true",
help="Beep on question and/or when SQL injection is found") help="Beep on question and/or when SQL injection is found")
@@ -626,7 +626,7 @@ def cmdLineParser(argv=None):
help="Clean up the DBMS from sqlmap specific UDF and tables") help="Clean up the DBMS from sqlmap specific UDF and tables")
miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true", miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true",
help="Check for missing (non-core) sqlmap dependencies") help="Check for missing (optional) sqlmap dependencies")
miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true", miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true",
help="Disable console output coloring") help="Disable console output coloring")
@@ -668,6 +668,10 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users") help="Simple wizard interface for beginner users")
# Hidden and/or experimental options # Hidden and/or experimental options
parser.add_option("--crack", dest="hashFile",
help=SUPPRESS_HELP)
# help="Load and crack hashes from a file (standalone)")
parser.add_option("--dummy", dest="dummy", action="store_true", parser.add_option("--dummy", dest="dummy", action="store_true",
help=SUPPRESS_HELP) help=SUPPRESS_HELP)
@@ -884,7 +888,7 @@ def cmdLineParser(argv=None):
if args.dummy: if args.dummy:
args.url = args.url or DUMMY_URL args.url = args.url or DUMMY_URL
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers)): if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers, args.hashFile)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). " errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). "
errMsg += "Use -h for basic and -hh for advanced help\n" errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg) parser.error(errMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -342,7 +342,7 @@ def decodePage(page, contentEncoding, contentType):
retVal = match.group(0) retVal = match.group(0)
try: try:
retVal = unichr(int(match.group(1))) retVal = unichr(int(match.group(1)))
except ValueError: except (ValueError, OverflowError):
pass pass
return retVal return retVal
page = re.sub(r"&#(\d+);", _, page) page = re.sub(r"&#(\d+);", _, page)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+97 -65
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -64,11 +64,13 @@ from lib.core.common import urlencode
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.datatype import AttribDict
from lib.core.decorators import stackedmethod from lib.core.decorators import stackedmethod
from lib.core.dicts import POST_HINT_CONTENT_TYPES from lib.core.dicts import POST_HINT_CONTENT_TYPES
from lib.core.enums import ADJUST_TIME_DELAY from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE from lib.core.enums import AUTH_TYPE
from lib.core.enums import CUSTOM_LOGGING from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import HINT
from lib.core.enums import HTTP_HEADER from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION from lib.core.enums import NULLCONNECTION
@@ -76,7 +78,7 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import POST_HINT from lib.core.enums import POST_HINT
from lib.core.enums import REDIRECTION from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_API from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapCompressionException from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException from lib.core.exception import SqlmapGenericException
@@ -88,6 +90,7 @@ from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import DEFAULT_CONTENT_TYPE from lib.core.settings import DEFAULT_CONTENT_TYPE
from lib.core.settings import DEFAULT_COOKIE_DELIMITER from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import EVALCODE_KEYWORD_SUFFIX from lib.core.settings import EVALCODE_KEYWORD_SUFFIX
from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
@@ -98,6 +101,7 @@ from lib.core.settings import MAX_CONSECUTIVE_CONNECTION_ERRORS
from lib.core.settings import MAX_MURPHY_SLEEP_TIME from lib.core.settings import MAX_MURPHY_SLEEP_TIME
from lib.core.settings import META_REFRESH_REGEX from lib.core.settings import META_REFRESH_REGEX
from lib.core.settings import MIN_TIME_RESPONSES from lib.core.settings import MIN_TIME_RESPONSES
from lib.core.settings import MAX_TIME_RESPONSES
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import LARGE_CHUNK_TRIM_MARKER from lib.core.settings import LARGE_CHUNK_TRIM_MARKER
@@ -170,9 +174,11 @@ class Connect(object):
warnMsg += "(e.g. 'https://help.ubuntu.com/community/Tor')" warnMsg += "(e.g. 'https://help.ubuntu.com/community/Tor')"
else: else:
warnMsg = "if the problem persists please check that the provided " warnMsg = "if the problem persists please check that the provided "
warnMsg += "target URL is valid. In case that it is, you can try to rerun " warnMsg += "target URL is reachable. In case that it is, "
warnMsg += "with the switch '--random-agent' turned on " warnMsg += "you can try to rerun with "
warnMsg += "and/or proxy switches ('--ignore-proxy', '--proxy',...)" if not conf.randomAgent:
warnMsg += "switch '--random-agent' and/or "
warnMsg += "proxy switches ('--ignore-proxy', '--proxy',...)"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
elif conf.threads > 1: elif conf.threads > 1:
@@ -359,14 +365,21 @@ class Connect(object):
if kb.proxyAuthHeader: if kb.proxyAuthHeader:
headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader
if not getHeader(headers, HTTP_HEADER.ACCEPT): if not conf.requestFile or not target:
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE if not getHeader(headers, HTTP_HEADER.HOST):
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.HOST) or not target: if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.HOST] = getHostHeader(url) 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:
for header in headers:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
del headers[header]
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) headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE)
@@ -383,10 +396,6 @@ class Connect(object):
if conf.keepAlive: if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive" headers[HTTP_HEADER.CONNECTION] = "keep-alive"
# Reset header values to original in case of provided request file
if target and conf.requestFile:
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie})
if auxHeaders: if auxHeaders:
headers = forgeHeaders(auxHeaders, headers) headers = forgeHeaders(auxHeaders, headers)
@@ -590,7 +599,7 @@ class Connect(object):
threadData.lastHTTPError = (threadData.lastRequestUID, code, status) threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1 kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status) responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders: if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
@@ -749,7 +758,7 @@ class Connect(object):
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status) responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
else: else:
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status) responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders: if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()]) logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
@@ -816,10 +825,14 @@ class Connect(object):
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)
if not disableTampering and kb.tamperFunctions: if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions: for function in kb.tamperFunctions:
hints = {}
try: try:
payload = function(payload=payload, headers=auxHeaders) payload = function(payload=payload, headers=auxHeaders, delimiter=delimiter, hints=hints)
except Exception, ex: except Exception, ex:
errMsg = "error occurred while running tamper " errMsg = "error occurred while running tamper "
errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex)) errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex))
@@ -832,6 +845,18 @@ class Connect(object):
value = agent.replacePayload(value, payload) value = agent.replacePayload(value, payload)
if hints:
if HINT.APPEND in hints:
value = "%s%s%s" % (value, delimiter, hints[HINT.APPEND])
if HINT.PREPEND in hints:
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)
if match:
value = value.replace(match.group(0), "%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0)))
else:
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:
@@ -848,10 +873,10 @@ class Connect(object):
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] == HTTP_HEADER.COOKIE) 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] == HTTP_HEADER.COOKIE: if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper():
if kb.cookieEncodeChoice is None: if kb.cookieEncodeChoice 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" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True) kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True)
@@ -866,7 +891,7 @@ class Connect(object):
postUrlEncode = False postUrlEncode = False
if conf.hpp: if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)): if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_PLATFORM.ASP, WEB_PLATFORM.ASPX)):
warnMsg = "HTTP parameter pollution should work only against " warnMsg = "HTTP parameter pollution should work only against "
warnMsg += "ASP(.NET) targets" warnMsg += "ASP(.NET) targets"
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
@@ -938,75 +963,77 @@ class Connect(object):
if conf.csrfToken: if conf.csrfToken:
def _adjustParameter(paramString, parameter, newValue): def _adjustParameter(paramString, parameter, newValue):
retVal = paramString retVal = paramString
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString) match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
if match: if match:
retVal = re.sub(re.escape(match.group(0)), "%s=%s" % (parameter, newValue), paramString) retVal = re.sub("(?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) match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
if match: if match:
retVal = re.sub(re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString) retVal = re.sub("(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
return retVal return retVal
token = AttribDict()
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.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.data if conf.csrfUrl == conf.url else None, method=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))
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken), page or "") match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
if match:
token.name, token.value = match.group("name"), match.group("value")
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
if match:
token.value = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token: if not token:
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "") if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == httplib.OK:
if not token:
match = re.search(r"%s[\"']:[\"']([^\"']+)" % re.escape(conf.csrfToken), page or "")
token = match.group(1) if match else None
if not token:
token = extractRegexResult(r"\b%s\s*[:=]\s*(?P<result>\w+)" % re.escape(conf.csrfToken), str(headers))
if not token:
token = extractRegexResult(r"\b%s\s*=\s*['\"]?(?P<result>[^;'\"]+)" % re.escape(conf.csrfToken), page or "")
if token:
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token)
if match:
token = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token:
if conf.csrfUrl != conf.url and code == httplib.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""): if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token = page token.name = conf.csrfToken
token.value = page
if not token and conf.cj and any(_.name == conf.csrfToken for _ in conf.cj): if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
for _ in conf.cj: for _ in conf.cj:
if _.name == conf.csrfToken: if re.search(conf.csrfToken, _.name, re.I):
token = _.value token.name, token.value = _.name, _.value
if not any(conf.csrfToken in _ 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, conf.csrfToken, token) 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, conf.csrfToken, token) get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else: else:
get = "%s=%s" % (conf.csrfToken, token) 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, 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'"
raise SqlmapTokenException(errMsg) raise SqlmapTokenException(errMsg)
if token: if token:
token = token.strip("'\"") token.value = token.value.strip("'\"")
for place in (PLACE.GET, PLACE.POST): for place in (PLACE.GET, PLACE.POST):
if place in conf.parameters: if place in conf.parameters:
if place == PLACE.GET and get: if place == PLACE.GET and get:
get = _adjustParameter(get, conf.csrfToken, token) get = _adjustParameter(get, token.name, token.value)
elif place == PLACE.POST and post: elif place == PLACE.POST and post:
post = _adjustParameter(post, conf.csrfToken, token) post = _adjustParameter(post, token.name, token.value)
for i in xrange(len(conf.httpHeaders)): for i in xrange(len(conf.httpHeaders)):
if conf.httpHeaders[i][0].lower() == conf.csrfToken.lower(): if conf.httpHeaders[i][0].lower() == token.name.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token) conf.httpHeaders[i] = (conf.httpHeaders[i][0], token.value)
if conf.rParam: if conf.rParam:
def _randomizeParameter(paramString, randomParameter): def _randomizeParameter(paramString, randomParameter):
@@ -1232,14 +1259,17 @@ class Connect(object):
_, 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:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH): try:
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH]) if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE): pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0])
pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:]) 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:])
except ValueError:
pass
finally: finally:
kb.pageCompress = popValue() kb.pageCompress = popValue()
if not pageLength: 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:
@@ -1276,6 +1306,8 @@ class Connect(object):
elif noteResponseTime: elif noteResponseTime:
kb.responseTimes.setdefault(kb.responseTimeMode, []) kb.responseTimes.setdefault(kb.responseTimeMode, [])
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration) kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
if len(kb.responseTimes) > MAX_TIME_RESPONSES:
kb.responseTimes = kb.responseTimes[-MAX_TIME_RESPONSES:]
if not response and removeReflection: if not response and removeReflection:
page = removeReflectiveValues(page, payload) page = removeReflectiveValues(page, payload)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+3 -16
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -20,7 +20,6 @@ from lib.core.common import dataToStdout
from lib.core.common import Backend from lib.core.common import Backend
from lib.core.common import getLocalIP from lib.core.common import getLocalIP
from lib.core.common import getRemoteIP from lib.core.common import getRemoteIP
from lib.core.common import getUnicode
from lib.core.common import normalizePath from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes from lib.core.common import ntToPosixSlashes
from lib.core.common import pollProcess from lib.core.common import pollProcess
@@ -39,7 +38,6 @@ from lib.core.exception import SqlmapGenericException
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import METASPLOIT_SESSION_TIMEOUT from lib.core.settings import METASPLOIT_SESSION_TIMEOUT
from lib.core.settings import SHELLCODEEXEC_RANDOM_STRING_MARKER from lib.core.settings import SHELLCODEEXEC_RANDOM_STRING_MARKER
from lib.core.settings import UNICODE_ENCODING
from lib.core.subprocessng import blockingReadFromFD from lib.core.subprocessng import blockingReadFromFD
from lib.core.subprocessng import blockingWriteToFD from lib.core.subprocessng import blockingWriteToFD
from lib.core.subprocessng import Popen as execute from lib.core.subprocessng import Popen as execute
@@ -168,19 +166,8 @@ class Metasploit:
choice = readInput(message, default="%d" % default) choice = readInput(message, default="%d" % default)
if not choice: if not choice or not choice.isdigit() or int(choice) > maxValue or int(choice) < 1:
if lst: choice = default
choice = getUnicode(default, UNICODE_ENCODING)
else:
return default
elif not choice.isdigit():
logger.warn("invalid value, only digits are allowed")
return self._skeletonSelection(msg, lst, maxValue, default)
elif int(choice) > maxValue or int(choice) < 1:
logger.warn("invalid value, it must be a digit between 1 and %d" % maxValue)
return self._skeletonSelection(msg, lst, maxValue, default)
choice = int(choice) choice = int(choice)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+18 -18
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -43,7 +43,7 @@ from lib.core.enums import HTTP_HEADER
from lib.core.enums import OS from lib.core.enums import OS
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE from lib.core.enums import PLACE
from lib.core.enums import WEB_API from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapNoneDataException from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT from lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUT
from lib.core.settings import EVENTVALIDATION_REGEX from lib.core.settings import EVENTVALIDATION_REGEX
@@ -60,7 +60,7 @@ class Web:
""" """
def __init__(self): def __init__(self):
self.webApi = None self.webPlatform = None
self.webBaseUrl = None self.webBaseUrl = None
self.webBackdoorUrl = None self.webBackdoorUrl = None
self.webBackdoorFilePath = None self.webBackdoorFilePath = None
@@ -109,14 +109,14 @@ class Web:
except TypeError: except TypeError:
pass pass
if self.webApi in getPublicTypeMembers(WEB_API, True): if self.webPlatform in getPublicTypeMembers(WEB_PLATFORM, True):
multipartParams = { multipartParams = {
"upload": "1", "upload": "1",
"file": stream, "file": stream,
"uploadDir": directory, "uploadDir": directory,
} }
if self.webApi == WEB_API.ASPX: if self.webPlatform == WEB_PLATFORM.ASPX:
multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION
multipartParams['__VIEWSTATE'] = kb.data.__VIEWSTATE multipartParams['__VIEWSTATE'] = kb.data.__VIEWSTATE
@@ -130,7 +130,7 @@ class Web:
else: else:
return True return True
else: else:
logger.error("sqlmap hasn't got a web backdoor nor a web file stager for %s" % self.webApi) logger.error("sqlmap hasn't got a web backdoor nor a web file stager for %s" % self.webPlatform)
return False return False
def _webFileInject(self, fileContent, fileName, directory): def _webFileInject(self, fileContent, fileName, directory):
@@ -158,13 +158,13 @@ class Web:
remote directory within the web server document root. remote directory within the web server document root.
""" """
if self.webBackdoorUrl is not None and self.webStagerUrl is not None and self.webApi is not None: if self.webBackdoorUrl is not None and self.webStagerUrl is not None and self.webPlatform is not None:
return return
self.checkDbmsOs() self.checkDbmsOs()
default = None default = None
choices = list(getPublicTypeMembers(WEB_API, True)) choices = list(getPublicTypeMembers(WEB_PLATFORM, True))
for ext in choices: for ext in choices:
if conf.url.endswith(ext): if conf.url.endswith(ext):
@@ -172,7 +172,7 @@ class Web:
break break
if not default: if not default:
default = WEB_API.ASP if Backend.isOs(OS.WINDOWS) else WEB_API.PHP default = WEB_PLATFORM.ASP if Backend.isOs(OS.WINDOWS) else WEB_PLATFORM.PHP
message = "which web application language does the web server " message = "which web application language does the web server "
message += "support?\n" message += "support?\n"
@@ -196,7 +196,7 @@ class Web:
logger.warn("invalid value, it must be between 1 and %d" % len(choices)) logger.warn("invalid value, it must be between 1 and %d" % len(choices))
else: else:
self.webApi = choices[int(choice) - 1] self.webPlatform = choices[int(choice) - 1]
break break
if not kb.absFilePaths: if not kb.absFilePaths:
@@ -266,16 +266,16 @@ class Web:
_.append("%s/%s" % (directory.rstrip('/'), path.strip('/'))) _.append("%s/%s" % (directory.rstrip('/'), path.strip('/')))
directories = _ directories = _
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webPlatform)
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webApi)) backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webPlatform))
stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi)) stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webPlatform))
for directory in directories: for directory in directories:
if not directory: if not directory:
continue continue
stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webPlatform)
self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName) self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName)
uploaded = False uploaded = False
@@ -317,14 +317,14 @@ class Web:
infoMsg += "via UNION method" infoMsg += "via UNION method"
logger.info(infoMsg) logger.info(infoMsg)
stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webPlatform)
self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName) self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName)
handle, filename = tempfile.mkstemp() handle, filename = tempfile.mkstemp()
os.close(handle) os.close(handle)
with open(filename, "w+b") as f: with open(filename, "w+b") as f:
_ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webApi)) _ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webPlatform))
_ = _.replace(SHELL_WRITABLE_DIR_TAG, utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)) _ = _.replace(SHELL_WRITABLE_DIR_TAG, utf8encode(directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory))
f.write(_) f.write(_)
@@ -353,7 +353,7 @@ class Web:
logger.warn(warnMsg) logger.warn(warnMsg)
continue continue
elif self.webApi == WEB_API.ASPX: elif self.webPlatform == WEB_PLATFORM.ASPX:
kb.data.__EVENTVALIDATION = extractRegexResult(EVENTVALIDATION_REGEX, uplPage) kb.data.__EVENTVALIDATION = extractRegexResult(EVENTVALIDATION_REGEX, uplPage)
kb.data.__VIEWSTATE = extractRegexResult(VIEWSTATE_REGEX, uplPage) kb.data.__VIEWSTATE = extractRegexResult(VIEWSTATE_REGEX, uplPage)
@@ -361,7 +361,7 @@ class Web:
infoMsg += "on '%s' - %s" % (directory, self.webStagerUrl) infoMsg += "on '%s' - %s" % (directory, self.webStagerUrl)
logger.info(infoMsg) logger.info(infoMsg)
if self.webApi == WEB_API.ASP: if self.webPlatform == WEB_PLATFORM.ASP:
match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage) match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage)
if match: if match:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
+8 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/) Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
@@ -244,7 +244,7 @@ def _errorFields(expression, expressionFields, expressionFieldsList, num=None, e
if kb.fileReadMode and output and output.strip(): if kb.fileReadMode and output and output.strip():
print print
elif output is not None and not (threadData.resumed and kb.suppressResumeInfo) and not (emptyFields and field in emptyFields): elif output is not None and not (threadData.resumed and kb.suppressResumeInfo) and not (emptyFields and field in emptyFields):
status = "[%s] [INFO] %s: %s" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", output if kb.safeCharEncode else safecharencode(output)) status = "[%s] [INFO] %s: '%s'" % (time.strftime("%X"), "resumed" if threadData.resumed else "retrieved", output if kb.safeCharEncode else safecharencode(output))
if len(status) > width: if len(status) > width:
status = "%s..." % status[:width - 3] status = "%s..." % status[:width - 3]
@@ -332,7 +332,7 @@ def errorUse(expression, dump=False):
stopLimit = int(count) stopLimit = int(count)
infoMsg = "used SQL query returns " infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit infoMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry")
logger.info(infoMsg) logger.info(infoMsg)
elif count and not count.isdigit(): elif count and not count.isdigit():
@@ -444,8 +444,11 @@ def errorUse(expression, dump=False):
if not value and not abortedFlag: if not value and not abortedFlag:
value = _errorFields(expression, expressionFields, expressionFieldsList) value = _errorFields(expression, expressionFields, expressionFieldsList)
if value and isListLike(value) and len(value) == 1 and isinstance(value[0], basestring): if value and isListLike(value):
value = unArrayizeValue(value) if len(value) == 1 and isinstance(value[0], basestring):
value = unArrayizeValue(value)
elif len(value) > 1 and stopLimit == 1:
value = [value]
duration = calculateDeltaSeconds(start) duration = calculateDeltaSeconds(start)

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