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`)
* Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation):
* 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`):
* 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):
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy
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
the terms of the GNU General Public License as published by the Free
+3 -2
View File
@@ -1,10 +1,10 @@
# 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.
**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
----
@@ -67,3 +67,4 @@ Translations
* [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)
* [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 his great Metasploit WMAP Framework
Jennifer Torres, <jtorresf42(at)gmail.com>
* for contributing a tamper script luanginx.py
Sandro Tosi, <matrixhasu(at)gmail.com>
* 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
"""
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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -3,7 +3,7 @@
"""
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
"""
+1 -1
View File
@@ -1,6 +1,6 @@
#!/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
# Removes duplicate entries in wordlist like files
+10
View File
@@ -1,5 +1,15 @@
#!/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"
declare -x SCRIPTPATH="${0}"
+10
View File
@@ -1,5 +1,15 @@
#!/bin/bash
: '
cat > .git/hooks/pre-commit << EOF
#!/bin/bash
source ./extra/shutils/precommit-hook.sh
EOF
chmod +x .git/hooks/pre-commit
'
PROJECT="../../"
SETTINGS="../../lib/core/settings.py"
CHECKSUM="../../txt/checksum.md5"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/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
# 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
"""
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
"""
@@ -61,7 +61,7 @@ cat > sqlmap/__init__.py << EOF
#!/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
"""
+1 -1
View File
@@ -1,6 +1,6 @@
#!/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
import codecs
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+4 -2
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -99,7 +99,7 @@ def main():
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
for function, product in WAF_FUNCTIONS:
@@ -115,5 +115,7 @@ def main():
print
exit(int(not found))
if __name__ == "__main__":
main()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+30 -17
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -69,11 +69,14 @@ from lib.core.enums import NULLCONNECTION
from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
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 CHECK_INTERNET_ADDRESS
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 NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
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 SUHOSIN_MAX_VALUE_LENGTH
from lib.core.settings import SUPPORTED_DBMS
@@ -360,7 +364,7 @@ def checkSqlInjection(place, parameter, value):
# Parse test's <request>
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:
injectable = False
@@ -471,13 +475,13 @@ def checkSqlInjection(place, parameter, value):
# payload was successful
# Parse test's <response>
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
if method == PAYLOAD.METHOD.COMPARISON:
# Generate payload used for comparison
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
# 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:
continue
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
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%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms
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
if casting:
errMsg = "possible %s casting " % ("integer" if origValue.isdigit() else "type")
errMsg += "detected (e.g. \"$%s=intval($_REQUEST['%s'])\") " % (parameter, parameter)
errMsg += "at the back-end web application"
errMsg = "possible %s casting detected (e.g. '" % ("integer" if origValue.isdigit() else "type")
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)
if kb.ignoreCasted is None:
@@ -1116,14 +1130,6 @@ def checkDynParam(place, parameter, value):
try:
payload = agent.payload(place, parameter, value, getUnicode(randInt))
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:
pass
@@ -1355,9 +1361,11 @@ def checkWaf():
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect)
pushValue(conf.timeout)
kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IDS_WAF_CHECK_TIMEOUT
try:
@@ -1368,6 +1376,7 @@ def checkWaf():
kb.matchRatio = None
conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue()
if retVal:
@@ -1537,6 +1546,10 @@ def checkConnection(suppressOutput=False):
errMsg = "problem occurred while "
errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
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:
infoMsg = "testing connection to the target URL"
+26 -12
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -56,9 +56,11 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException
from lib.core.exception import SqlmapUserQuitException
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 EMPTY_FORM_FIELDS_REGEX
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.target import initTargetEnv
from lib.core.target import setupTargetEnv
from lib.utils.hash import crackHashFile
def _selectInjection():
"""
@@ -243,16 +246,20 @@ def _saveToResultsFile():
results[key].extend(injection.data.keys())
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
try:
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
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
def start():
@@ -262,6 +269,9 @@ def start():
check if they are dynamic and SQL injection affected
"""
if conf.hashFile:
crackHashFile(conf.hashFile)
if conf.direct:
initTargetEnv()
setupTargetEnv()
@@ -307,6 +317,7 @@ def start():
conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders)
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()
parseTargetUrl()
@@ -498,14 +509,14 @@ def start():
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg)
elif parameter == conf.csrfToken:
elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I):
testSqlInj = False
infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter
logger.info(infoMsg)
# 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
infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
@@ -524,7 +535,7 @@ def start():
testSqlInj = False
else:
infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter)
infoMsg = "%s parameter '%s' appears to be dynamic" % (paramType, parameter)
logger.info(infoMsg)
kb.testedParams.add(paramKey)
@@ -631,6 +642,9 @@ def start():
errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
if not conf.randomAgent:
errMsg += " and/or switch '--random-agent'"
raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else:
# Flush the flag
+30 -13
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -10,6 +10,7 @@ from lib.core.data import conf
from lib.core.data import kb
from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_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 DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
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.hsqldb import HSQLDBMap
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.connector import Connector as InformixConn
@@ -67,6 +71,7 @@ def setHandler():
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
]
@@ -90,29 +95,41 @@ def setHandler():
conf.dbmsConnector = Connector()
if conf.direct:
exception = None
dialect = DBMS_DICT[dbms][3]
if dialect:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
try:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
else:
try:
conf.dbmsConnector.connect()
except NameError:
pass
else:
conf.dbmsConnector.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
except Exception, ex:
exception = ex
if not dialect or exception:
try:
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 kb.resolutionDbms:
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
conf.dbmsHandler._dbms = kb.resolutionDbms
else:
conf.dbmsHandler = handler
conf.dbmsHandler._dbms = dbms
conf.dbmsHandler._dbms = dbms
break
else:
conf.dbmsConnector = None
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+11 -6
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -43,6 +43,7 @@ from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import NULL
from lib.core.settings import PAYLOAD_DELIMITER
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.unescaper import unescaper
@@ -246,6 +247,9 @@ class Agent(object):
else:
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] == '('):
query += " "
@@ -345,6 +349,7 @@ class Agent(object):
if payload:
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)):
payload = payload.replace(_, str(randomInt()))
@@ -619,7 +624,7 @@ class Agent(object):
elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -818,7 +823,7 @@ class Agent(object):
limitRegExp2 = None
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
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
@@ -908,14 +913,14 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
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)
limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.HSQLDB):
match = re.search(r"ORDER BY [^ ]+", limitedQuery)
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)
if query.startswith("SELECT "):
@@ -1089,7 +1094,7 @@ class Agent(object):
if conf.dumpWhere and 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)
elif re.search(r"(?i)\bWHERE\b", prefix):
prefix += " AND %s" % conf.dumpWhere
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+62 -43
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -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_FAILSAFE_CHARS
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 WEBSCARAB_SPLITTER
from lib.core.threads import getCurrentThreadData
@@ -601,7 +600,7 @@ def paramToDict(place, parameters=None):
if condition:
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)
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 "
@@ -646,7 +645,7 @@ def paramToDict(place, parameters=None):
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized), 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
deserialized = json.loads(testableParameters[parameter])
@@ -900,7 +899,7 @@ def clearColors(message):
retVal = message
if message:
if isinstance(message, str):
retVal = re.sub(r"\x1b\[[\d;]+m", "", message)
return retVal
@@ -924,7 +923,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
try:
if conf.get("api"):
sys.stdout.write(message, status, content_type)
sys.stdout.write(clearColors(message), status, content_type)
else:
sys.stdout.write(setColor(message, bold=bold))
@@ -1199,7 +1198,7 @@ def banner():
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
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
@@ -1408,8 +1407,10 @@ def parseTargetDirect():
__import__("pyodbc")
elif dbmsName == DBMS.FIREBIRD:
__import__("kinterbasdb")
except (SqlmapSyntaxException, SqlmapMissingDependence):
raise
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
else:
errMsg = "sqlmap requires '%s' third-party library " % data[1]
@@ -2120,6 +2121,16 @@ def readXmlFile(xmlFile):
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
def stdev(values):
"""
@@ -2134,19 +2145,9 @@ def stdev(values):
return None
else:
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))
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):
"""
Returns elapsed time from start till now
@@ -3371,7 +3372,7 @@ def getLatestRevision():
"""
Retrieves latest revision from the offical repository
>>> getLatestRevision() == VERSION
>>> from lib.core.settings import VERSION; getLatestRevision() == VERSION
True
"""
@@ -3482,6 +3483,9 @@ def maskSensitiveData(msg):
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)))
# Fail-safe substitution
retVal = re.sub(r"(?i)\bhttps?://[^ ]+", lambda match: '*' * len(match.group(0)), retVal)
if getpass.getuser():
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
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]))
[1, 3]
@@ -3515,15 +3519,15 @@ def intersect(valueA, valueB, lowerCase=False):
retVal = []
if valueA and valueB:
valueA = arrayizeValue(valueA)
valueB = arrayizeValue(valueB)
if containerA and containerB:
containerA = arrayizeValue(containerA)
containerB = arrayizeValue(containerB)
if lowerCase:
valueA = [val.lower() if isinstance(val, basestring) else val for val in valueA]
valueB = [val.lower() if isinstance(val, basestring) else val for val in valueB]
containerA = [val.lower() if isinstance(val, basestring) else val for val in containerA]
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
@@ -3543,7 +3547,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
return value
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 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):
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
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if ((parts[i] or " ")[0].isdigit() or not re.match(r"\A\w+\Z", parts[i], re.U)):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
if isTable:
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -4112,7 +4120,12 @@ def checkSameHost(*urls):
elif len(urls) == 1:
return True
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):
"""
@@ -4276,7 +4289,7 @@ def decodeHexValue(value, raw=False):
retVal = retVal.decode("utf-16-le")
except UnicodeDecodeError:
pass
elif Backend.isDbms(DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.H2):
try:
retVal = retVal.decode("utf-16-be")
except UnicodeDecodeError:
@@ -4334,19 +4347,23 @@ def hashDBWrite(key, value, serialize=False):
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))
conf.hashDB.write(_, value, serialize)
if conf.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))
conf.hashDB.write(_, value, serialize)
def hashDBRetrieve(key, unserialize=False, checkConf=False):
"""
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 = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any((conf.flushSession, conf.freshQueries))) else None
retVal = 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
if conf.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 = 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
@@ -4728,6 +4745,8 @@ def getSafeExString(ex, encoding=None):
retVal = ex.message
elif getattr(ex, "msg", None):
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()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+8 -1
View File
@@ -1,10 +1,11 @@
#!/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
"""
import functools
import hashlib
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/
"""
@functools.wraps(f)
def _(*args, **kwargs):
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
if key not in cache:
@@ -26,6 +28,11 @@ def cachedmethod(f, cache={}):
return _
def stackedmethod(f):
"""
Method using pushValue/popValue functions (fallback function for stack realignment)
"""
@functools.wraps(f)
def _(*args, **kwargs):
threadData = getCurrentThreadData()
originalLevel = len(threadData.valueStack)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+3 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -22,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
FIREBIRD_TYPES = {
@@ -195,6 +196,7 @@ DBMS_DICT = {
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.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"),
}
+2 -2
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -171,7 +171,7 @@ class Dump(object):
def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB):
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)
else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
+8 -2
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -43,6 +43,7 @@ class DBMS:
SQLITE = "SQLite"
SYBASE = "Sybase"
HSQLDB = "HSQLDB"
H2 = "H2"
INFORMIX = "Informix"
class DBMS_DIRECTORY_NAME:
@@ -57,6 +58,7 @@ class DBMS_DIRECTORY_NAME:
SQLITE = "sqlite"
SYBASE = "sybase"
HSQLDB = "hsqldb"
H2 = "h2"
INFORMIX = "informix"
class CUSTOM_LOGGING:
@@ -308,7 +310,7 @@ class ADJUST_TIME_DELAY:
NO = 0
YES = 1
class WEB_API:
class WEB_PLATFORM:
PHP = "php"
ASP = "asp"
ASPX = "aspx"
@@ -376,3 +378,7 @@ class TIMEOUT_STATE:
NORMAL = 0
EXCEPTION = 1
TIMEOUT = 2
class HINT:
PREPEND = 0
APPEND = 1
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+55 -27
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -45,7 +45,6 @@ from lib.core.common import ntToPosixSlashes
from lib.core.common import openFile
from lib.core.common import parseRequestFile
from lib.core.common import parseTargetDirect
from lib.core.common import parseTargetUrl
from lib.core.common import paths
from lib.core.common import randomStr
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 WIZARD
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException
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_TOR_HTTP_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 INJECT_HERE_REGEX
from lib.core.settings import IS_WIN
from lib.core.settings import KB_CHARS_BOUNDARY_CHAR
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 PARAMETER_SPLITTING_REGEX
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 SQLMAP_ENVIRONMENT_PREFIX
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 UNKNOWN_DBMS_VERSION
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 setDaemon
from lib.core.update import update
@@ -895,6 +893,12 @@ def _setSocketPreConnect():
family, type, proto, address = key
s = socket.socket(family, type, proto)
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:
socket._ready[key].append((s._sock, time.time()))
except KeyboardInterrupt:
@@ -1073,7 +1077,7 @@ def _setSafeVisit():
key, value = line.split(':', 1)
value = value.strip()
kb.safeReq.headers[key] = value
if key == HTTP_HEADER.HOST:
if key.upper() == HTTP_HEADER.HOST.upper():
if not value.startswith("http"):
scheme = "http"
if value.endswith(":443"):
@@ -1258,14 +1262,6 @@ def _setHTTPExtraHeaders():
# Reference: http://stackoverflow.com/a/1383359
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():
"""
Set the HTTP User-Agent header.
@@ -1305,12 +1301,12 @@ def _setHTTPUserAgent():
_ = True
for header, _ in conf.httpHeaders:
if header == HTTP_HEADER.USER_AGENT:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
_ = False
break
if _:
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
else:
if not kb.userAgents:
@@ -1325,10 +1321,10 @@ def _setHTTPUserAgent():
warnMsg += "file '%s'" % paths.USER_AGENTS
logger.warn(warnMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
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 += "file '%s'" % paths.USER_AGENTS
@@ -1369,6 +1365,19 @@ def _setHTTPCookies():
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():
"""
Set the HTTP timeout
@@ -1508,6 +1517,8 @@ def _cleanupOptions():
if conf.url:
conf.url = conf.url.strip()
if not re.search(r"\A\w+://", conf.url):
conf.url = "http://%s" % conf.url
if conf.fileRead:
conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead))
@@ -1533,14 +1544,6 @@ def _cleanupOptions():
if conf.optimize:
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:
conf.os = conf.os.capitalize()
@@ -1565,6 +1568,23 @@ def _cleanupOptions():
except re.error:
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:
conf.testSkip = conf.testSkip.strip('*+')
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')"
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:
errMsg = "switch '--identify-waf' is incompatible with switch '--skip-waf'"
raise SqlmapSyntaxException(errMsg)
@@ -2417,6 +2441,10 @@ def _basicOptionValidation():
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
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 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 "
@@ -2486,10 +2514,10 @@ def init():
_resolveCrossReferences()
_checkWebSocket()
parseTargetUrl()
parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)):
_setHostname()
_setHTTPTimeout()
_setHTTPExtraHeaders()
_setHTTPCookies()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+17 -10
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -19,12 +19,13 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# 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_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)
DESCRIPTION = "automatic SQL injection and database takeover tool"
SITE = "http://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
DEV_EMAIL_ADDRESS = "[email protected]"
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
@@ -71,6 +72,7 @@ RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
SLEEP_TIME_MARKER = "[SLEEPTIME]"
INFERENCE_MARKER = "[INFERENCE]"
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
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
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
MIN_UNION_RESPONSES = 5
@@ -236,6 +241,7 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
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")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",)
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
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")
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")
REFERER_ALIASES = ("ref", "referer", "referrer")
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
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)
ERROR_PARSING_REGEXES = (
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"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
r"<li>Error Type:<br>(?P<result>.+?)</li>",
@@ -578,7 +585,7 @@ UNION_CHAR_REGEX = r"\A\w+\Z"
UNENCODED_ORIGINAL_VALUE = "original"
# 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_GET_POST_DELIMITER = '&'
@@ -590,7 +597,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
# 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
HASHDB_FLUSH_THRESHOLD = 32
@@ -668,7 +675,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# Boldify all logger messages containing these "patterns"
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported")
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_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
@@ -680,7 +687,7 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100
# 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
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
+25 -22
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -53,30 +53,33 @@ def clearHistory():
readline.clear_history()
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:
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
except:
pass
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
except KeyboardInterrupt:
pass
def loadHistory(completion=None):
if not readlineAvailable():
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+23 -8
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -44,6 +44,7 @@ from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUserQuitException
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.settings import ASTERISK_MARKER
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 HOST_ALIASES
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_LIKE_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
# 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)
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}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.REFERER:
elif httpHeader.upper() == HTTP_HEADER.REFERER.upper():
conf.parameters[PLACE.REFERER] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True)))
@@ -361,7 +364,7 @@ def _setRequestParams():
conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.HOST:
elif httpHeader.upper() == HTTP_HEADER.HOST.upper():
conf.parameters[PLACE.HOST] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True)))
@@ -390,8 +393,8 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg)
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, {}):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
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._original
errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg)
else:
@@ -405,7 +408,10 @@ def _setRequestParams():
message += "Do you want sqlmap to automatically update it in further requests? [y/N] "
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
def _setHashDB():
@@ -466,7 +472,13 @@ def _resumeDBMS():
value = hashDBRetrieve(HASHDB_KEYS.DBMS)
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()
dbmsVersion = [UNKNOWN_DBMS_VERSION]
@@ -745,6 +757,9 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, 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():
_createTargetDirs()
_setRequestParams()
+35 -31
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -17,6 +17,7 @@ import traceback
from extra.beep.beep import beep
from lib.controller.controller import start
from lib.core.common import checkIntegrity
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import getUnicode
@@ -51,41 +52,44 @@ def smokeTest():
retVal = True
count, length = 0, 0
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
if not checkIntegrity():
retVal = False
else:
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
length += 1
for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
length += 1
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
path = os.path.join(root, os.path.splitext(filename)[0])
path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
path = path.replace(os.sep, '.').lstrip('.')
try:
__import__(path)
module = sys.modules[path]
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:
for filename in files:
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
path = os.path.join(root, os.path.splitext(filename)[0])
path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
path = path.replace(os.sep, '.').lstrip('.')
try:
__import__(path)
module = sys.modules[path]
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
count += 1
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
count += 1
status = '%d/%d (%d%%) ' % (count, length, round(100.0 * count / length))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
clearConsoleLine()
if retVal:
+2 -2
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -92,7 +92,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
kb.threadException = True
raise
except Exception, ex:
if not silent:
if not silent and kb.get("threadContinue"):
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.get("verbose") > 1:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+13 -9
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -99,16 +99,16 @@ def cmdLineParser(argv=None):
help="Force usage of given HTTP method (e.g. PUT)")
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",
help="Character used for splitting parameter values")
help="Character used for splitting parameter values (e.g. &)")
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",
help="Character used for splitting cookie values")
help="Character used for splitting cookie values (e.g. ;)")
request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format")
@@ -144,7 +144,7 @@ def cmdLineParser(argv=None):
help="HTTP authentication PEM cert/private key file")
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",
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")
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",
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")
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",
help="Disable console output coloring")
@@ -668,6 +668,10 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users")
# 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",
help=SUPPRESS_HELP)
@@ -884,7 +888,7 @@ def cmdLineParser(argv=None):
if args.dummy:
args.url = args.url or DUMMY_URL
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.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 += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -342,7 +342,7 @@ def decodePage(page, contentEncoding, contentType):
retVal = match.group(0)
try:
retVal = unichr(int(match.group(1)))
except ValueError:
except (ValueError, OverflowError):
pass
return retVal
page = re.sub(r"&#(\d+);", _, page)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+97 -65
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -64,11 +64,13 @@ from lib.core.common import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.datatype import AttribDict
from lib.core.decorators import stackedmethod
from lib.core.dicts import POST_HINT_CONTENT_TYPES
from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE
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 HTTPMETHOD
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 POST_HINT
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 SqlmapConnectionException
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_COOKIE_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 HTTP_ACCEPT_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 META_REFRESH_REGEX
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 IS_WIN
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')"
else:
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 += "with the switch '--random-agent' turned on "
warnMsg += "and/or proxy switches ('--ignore-proxy', '--proxy',...)"
warnMsg += "target URL is reachable. In case that it is, "
warnMsg += "you can try to rerun with "
if not conf.randomAgent:
warnMsg += "switch '--random-agent' and/or "
warnMsg += "proxy switches ('--ignore-proxy', '--proxy',...)"
singleTimeWarnMessage(warnMsg)
elif conf.threads > 1:
@@ -359,14 +365,21 @@ class Connect(object):
if kb.proxyAuthHeader:
headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not conf.requestFile or not target:
if not getHeader(headers, HTTP_HEADER.HOST):
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.HOST) or not target:
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
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):
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:
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:
headers = forgeHeaders(auxHeaders, headers)
@@ -590,7 +599,7 @@ class Connect(object):
threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
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:
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)
else:
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
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()])
@@ -816,10 +825,14 @@ class Connect(object):
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
if payload:
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions:
hints = {}
try:
payload = function(payload=payload, headers=auxHeaders)
payload = function(payload=payload, headers=auxHeaders, delimiter=delimiter, hints=hints)
except Exception, ex:
errMsg = "error occurred while running tamper "
errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex))
@@ -832,6 +845,18 @@ class Connect(object):
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, '\\'))
if place == PLACE.CUSTOM_POST and kb.postHint:
@@ -848,10 +873,10 @@ class Connect(object):
value = agent.replacePayload(value, payload)
else:
# 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
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:
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)
@@ -866,7 +891,7 @@ class Connect(object):
postUrlEncode = False
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 += "ASP(.NET) targets"
singleTimeWarnMessage(warnMsg)
@@ -938,75 +963,77 @@ class Connect(object):
if conf.csrfToken:
def _adjustParameter(paramString, parameter, newValue):
retVal = paramString
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString)
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
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:
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
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
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))
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:
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "")
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 conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == httplib.OK:
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:
if _.name == conf.csrfToken:
token = _.value
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if re.search(conf.csrfToken, _.name, re.I):
token.name, token.value = _.name, _.value
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else:
get = "%s=%s" % (conf.csrfToken, token)
get = "%s=%s" % (token.name, token.value)
break
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:
errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'"
raise SqlmapTokenException(errMsg)
if token:
token = token.strip("'\"")
token.value = token.value.strip("'\"")
for place in (PLACE.GET, PLACE.POST):
if place in conf.parameters:
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:
post = _adjustParameter(post, conf.csrfToken, token)
post = _adjustParameter(post, token.name, token.value)
for i in xrange(len(conf.httpHeaders)):
if conf.httpHeaders[i][0].lower() == conf.csrfToken.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token)
if conf.httpHeaders[i][0].lower() == token.name.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token.value)
if conf.rParam:
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))
if headers:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH])
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:])
try:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0])
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:
kb.pageCompress = popValue()
if not pageLength:
if pageLength is None:
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)
except MemoryError:
@@ -1276,6 +1306,8 @@ class Connect(object):
elif noteResponseTime:
kb.responseTimes.setdefault(kb.responseTimeMode, [])
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:
page = removeReflectiveValues(page, payload)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+3 -16
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -20,7 +20,6 @@ from lib.core.common import dataToStdout
from lib.core.common import Backend
from lib.core.common import getLocalIP
from lib.core.common import getRemoteIP
from lib.core.common import getUnicode
from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes
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 METASPLOIT_SESSION_TIMEOUT
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 blockingWriteToFD
from lib.core.subprocessng import Popen as execute
@@ -168,19 +166,8 @@ class Metasploit:
choice = readInput(message, default="%d" % default)
if not choice:
if lst:
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)
if not choice or not choice.isdigit() or int(choice) > maxValue or int(choice) < 1:
choice = default
choice = int(choice)
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+18 -18
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -43,7 +43,7 @@ from lib.core.enums import HTTP_HEADER
from lib.core.enums import OS
from lib.core.enums import PAYLOAD
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.settings import BACKDOOR_RUN_CMD_TIMEOUT
from lib.core.settings import EVENTVALIDATION_REGEX
@@ -60,7 +60,7 @@ class Web:
"""
def __init__(self):
self.webApi = None
self.webPlatform = None
self.webBaseUrl = None
self.webBackdoorUrl = None
self.webBackdoorFilePath = None
@@ -109,14 +109,14 @@ class Web:
except TypeError:
pass
if self.webApi in getPublicTypeMembers(WEB_API, True):
if self.webPlatform in getPublicTypeMembers(WEB_PLATFORM, True):
multipartParams = {
"upload": "1",
"file": stream,
"uploadDir": directory,
}
if self.webApi == WEB_API.ASPX:
if self.webPlatform == WEB_PLATFORM.ASPX:
multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATION
multipartParams['__VIEWSTATE'] = kb.data.__VIEWSTATE
@@ -130,7 +130,7 @@ class Web:
else:
return True
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
def _webFileInject(self, fileContent, fileName, directory):
@@ -158,13 +158,13 @@ class Web:
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
self.checkDbmsOs()
default = None
choices = list(getPublicTypeMembers(WEB_API, True))
choices = list(getPublicTypeMembers(WEB_PLATFORM, True))
for ext in choices:
if conf.url.endswith(ext):
@@ -172,7 +172,7 @@ class Web:
break
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 += "support?\n"
@@ -196,7 +196,7 @@ class Web:
logger.warn("invalid value, it must be between 1 and %d" % len(choices))
else:
self.webApi = choices[int(choice) - 1]
self.webPlatform = choices[int(choice) - 1]
break
if not kb.absFilePaths:
@@ -266,16 +266,16 @@ class Web:
_.append("%s/%s" % (directory.rstrip('/'), path.strip('/')))
directories = _
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi)
backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webApi))
backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webPlatform)
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:
if not directory:
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)
uploaded = False
@@ -317,14 +317,14 @@ class Web:
infoMsg += "via UNION method"
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)
handle, filename = tempfile.mkstemp()
os.close(handle)
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))
f.write(_)
@@ -353,7 +353,7 @@ class Web:
logger.warn(warnMsg)
continue
elif self.webApi == WEB_API.ASPX:
elif self.webPlatform == WEB_PLATFORM.ASPX:
kb.data.__EVENTVALIDATION = extractRegexResult(EVENTVALIDATION_REGEX, uplPage)
kb.data.__VIEWSTATE = extractRegexResult(VIEWSTATE_REGEX, uplPage)
@@ -361,7 +361,7 @@ class Web:
infoMsg += "on '%s' - %s" % (directory, self.webStagerUrl)
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)
if match:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/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
"""
+8 -5
View File
@@ -1,7 +1,7 @@
#!/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
"""
@@ -244,7 +244,7 @@ def _errorFields(expression, expressionFields, expressionFieldsList, num=None, e
if kb.fileReadMode and output and output.strip():
print
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:
status = "%s..." % status[:width - 3]
@@ -332,7 +332,7 @@ def errorUse(expression, dump=False):
stopLimit = int(count)
infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit
infoMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry")
logger.info(infoMsg)
elif count and not count.isdigit():
@@ -444,8 +444,11 @@ def errorUse(expression, dump=False):
if not value and not abortedFlag:
value = _errorFields(expression, expressionFields, expressionFieldsList)
if value and isListLike(value) and len(value) == 1 and isinstance(value[0], basestring):
value = unArrayizeValue(value)
if value and isListLike(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)

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