mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
295cd15dff | ||
|
|
3463341bad | ||
|
|
88553d3540 | ||
|
|
ab90447600 | ||
|
|
a23faaeb8c | ||
|
|
6942abf090 | ||
|
|
3c25f79a9b | ||
|
|
94ab17829e | ||
|
|
c4c1571902 | ||
|
|
da86486cd9 | ||
|
|
dccc837703 | ||
|
|
452915ed4a | ||
|
|
35e575c287 | ||
|
|
015a8f0a6d | ||
|
|
0896a49500 | ||
|
|
95511c8ff9 | ||
|
|
8bf1650d65 | ||
|
|
ff645a767b | ||
|
|
cfa7b3c3bd | ||
|
|
76b310cc43 | ||
|
|
9a6acd2054 | ||
|
|
387020ece8 | ||
|
|
732b9670d2 | ||
|
|
1159c9ccae | ||
|
|
cadbf170f0 | ||
|
|
fc486c8b34 | ||
|
|
cfe43e3f2b | ||
|
|
6395481aa4 | ||
|
|
2380ab1e86 | ||
|
|
dd32bfb0cc | ||
|
|
b7d90bbe03 | ||
|
|
86170e177c | ||
|
|
bce3abc829 | ||
|
|
8d6125f067 | ||
|
|
506e3f0871 | ||
|
|
6145944dc7 | ||
|
|
61186b979b | ||
|
|
4d4b9a1175 | ||
|
|
133e2c8c61 | ||
|
|
38c341076d | ||
|
|
40e4422bbd | ||
|
|
98ac1cf9c1 | ||
|
|
56721240fa | ||
|
|
c81414cf25 | ||
|
|
2e195a35dc | ||
|
|
89d25a16ce | ||
|
|
9bc466edac | ||
|
|
32b7f3040e | ||
|
|
f066e215e5 | ||
|
|
4e65ff4689 | ||
|
|
1e8bf1c78a | ||
|
|
657c6519ea | ||
|
|
970c7f6a76 | ||
|
|
105e314ec8 | ||
|
|
dd963a042d | ||
|
|
0df2592622 |
@@ -0,0 +1 @@
|
||||
custom: 'https://www.paypal.com/donate?hosted_button_id=A34GMDLKA2V7G'
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester, and a broad range of switches including database fingerprinting, over data fetching from the database, accessing the underlying file system, and executing commands on the operating system via out-of-band connections.
|
||||
|
||||
**sqlmap is sponsored by [SpyderSec](https://spydersec.com/).**
|
||||
|
||||
Screenshots
|
||||
----
|
||||
|
||||
@@ -68,6 +66,7 @@ Translations
|
||||
* [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md)
|
||||
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
||||
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
|
||||
* [Serbian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-rs-RS.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)
|
||||
|
||||
@@ -734,6 +734,9 @@ rmillet, <rmillet42(at)gmail.com>
|
||||
Rub3nCT, <rub3nct(at)gmail.com>
|
||||
* for reporting a minor bug
|
||||
|
||||
sapra, <amanistaken(at)gmail.com>
|
||||
* for helping out with Python multiprocessing library on MacOS
|
||||
|
||||
shiftzwei, <shiftzwei(at)gmail.com>
|
||||
* for reporting a couple of bugs
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
|
||||
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur handal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
|
||||
|
||||
Tangkapan Layar
|
||||
----
|
||||
@@ -14,8 +14,7 @@ Anda dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapprojec
|
||||
Instalasi
|
||||
----
|
||||
|
||||
Anda dapat mengunduh tarball versi terbaru [di sini]
|
||||
(https://github.com/sqlmapproject/sqlmap/tarball/master) atau zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master).
|
||||
Anda dapat mengunduh tarball versi terbaru [di sini](https://github.com/sqlmapproject/sqlmap/tarball/master) atau zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master).
|
||||
|
||||
Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_ repositori [Git](https://github.com/sqlmapproject/sqlmap):
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# sqlmap
|
||||
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap je alat otvorenog koda namenjen za penetraciono testiranje koji automatizuje proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije i preuzimanje baza podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko uzimanja podataka iz baze, do pristupa zahvaćenom fajl sistemu i izvršavanja komandi na operativnom sistemu korištenjem tzv. "out-of-band" veza.
|
||||
|
||||
Slike
|
||||
----
|
||||
|
||||

|
||||
|
||||
Možete posetiti [kolekciju slika](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gde su demonstrirane neke od e se demonstriraju neke od funkcija na wiki stranicama.
|
||||
|
||||
Instalacija
|
||||
----
|
||||
|
||||
Možete preuzeti najnoviji tarball klikom [ovde](https://github.com/sqlmapproject/sqlmap/tarball/master) ili najnoviji zipball klikom [ovde](https://github.com/sqlmapproject/sqlmap/zipball/master).
|
||||
|
||||
Opciono, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproject/sqlmap) repozitorija:
|
||||
|
||||
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||
|
||||
sqlmap radi bez posebnih zahteva korištenjem [Python](http://www.python.org/download/) verzije **2.6**, **2.7** i/ili **3.x** na bilo kojoj platformi.
|
||||
|
||||
Korišćenje
|
||||
----
|
||||
|
||||
Kako biste dobili listu osnovnih opcija i prekidača koristite:
|
||||
|
||||
python sqlmap.py -h
|
||||
|
||||
Kako biste dobili listu svih opcija i prekidača koristite:
|
||||
|
||||
python sqlmap.py -hh
|
||||
|
||||
Možete pronaći primer izvršavanja [ovde](https://asciinema.org/a/46601).
|
||||
Kako biste dobili pregled mogućnosti sqlmap-a, liste podržanih funkcija, te opis svih opcija i prekidača, zajedno s primerima, preporučen je uvid u [korisnički priručnik](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
|
||||
|
||||
Linkovi
|
||||
----
|
||||
|
||||
* Početna stranica: http://sqlmap.org
|
||||
* Preuzimanje: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) ili [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||
* RSS feed promena u kodu: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||
* Prijava problema: https://github.com/sqlmapproject/sqlmap/issues
|
||||
* Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki
|
||||
* Najčešće postavljena pitanja (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
|
||||
* Demo: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
|
||||
* Slike: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
||||
@@ -3,15 +3,14 @@
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL và tiếp quản các máy chủ cơ sở dữ liệu. Nó đi kèm với
|
||||
một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập và một loạt các tùy chọn bao gồm lấy dấu cơ sở dữ liệu, truy xuất dữ liệu từ cơ sở dữ
|
||||
liệu, truy cập tệp của hệ thống và thực hiện các lệnh trên hệ điều hành thông qua kết nối ngoài.
|
||||
một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập (pentester) và một loạt các tùy chọn bao gồm phát hiện cơ sở dữ liệu, truy xuất dữ liệu từ cơ sở dữ liệu, truy cập tệp của hệ thống và thực hiện các lệnh trên hệ điều hành từ xa.
|
||||
|
||||
Ảnh chụp màn hình
|
||||
----
|
||||
|
||||

|
||||
|
||||
Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng trình bày một số tính năng trên wiki.
|
||||
Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng trình bày một số tính năng có thể tìm thấy trong wiki.
|
||||
|
||||
Cài đặt
|
||||
----
|
||||
@@ -19,11 +18,11 @@ Cài đặt
|
||||
|
||||
Bạn có thể tải xuống tập tin nén tar mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc tập tin nén zip mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/zipball/master).
|
||||
|
||||
Tốt hơn là bạn có thể tải xuống sqlmap bằng cách clone với [Git](https://github.com/sqlmapproject/sqlmap):
|
||||
Tốt hơn là bạn nên tải xuống sqlmap bằng cách clone với [Git](https://github.com/sqlmapproject/sqlmap):
|
||||
|
||||
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||
|
||||
sqlmap hoạt động hiệu quả với [Python](http://www.python.org/download/) phiên bản **2.6**, **2.7** và **3.x** trên bất kì nền tảng nào.
|
||||
sqlmap hoạt động hiệu quả với [Python](http://www.python.org/download/) phiên bản **2.6**, **2.7** và **3.x** trên bất kì hệ điều hành nào.
|
||||
|
||||
Sử dụng
|
||||
----
|
||||
@@ -36,7 +35,7 @@ Sử dụng
|
||||
|
||||
python sqlmap.py -hh
|
||||
|
||||
Bạn có thể tìm thấy video chạy mẫu [tại đây](https://asciinema.org/a/46601).
|
||||
Bạn có thể xem video chạy thử [tại đây](https://asciinema.org/a/46601).
|
||||
Để có cái nhìn tổng quan về các khả năng của sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (Tiếng Anh).
|
||||
|
||||
Liên kết
|
||||
@@ -44,7 +43,7 @@ Liên kết
|
||||
|
||||
* Trang chủ: http://sqlmap.org
|
||||
* Tải xuống: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||
* Lịch sử thay nguồn đổi cấp dữ liệu RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||
* Nguồn cấp dữ liệu RSS về commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||
* Theo dõi vấn đề: https://github.com/sqlmapproject/sqlmap/issues
|
||||
* Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki
|
||||
* Các câu hỏi thường gặp (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
|
||||
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带外数据连接的方式执行操作系统命令。
|
||||
|
||||
演示截图
|
||||
----
|
||||
|
||||
@@ -404,8 +404,8 @@ def checkSqlInjection(place, parameter, value):
|
||||
continue
|
||||
|
||||
# Parse boundary's <prefix>, <suffix> and <ptype>
|
||||
prefix = boundary.prefix if boundary.prefix else ""
|
||||
suffix = boundary.suffix if boundary.suffix else ""
|
||||
prefix = boundary.prefix or ""
|
||||
suffix = boundary.suffix or ""
|
||||
ptype = boundary.ptype
|
||||
|
||||
# Options --prefix/--suffix have a higher priority (if set by user)
|
||||
@@ -642,7 +642,7 @@ def checkSqlInjection(place, parameter, value):
|
||||
output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
|
||||
|
||||
if output:
|
||||
result = output == "1"
|
||||
result = output == '1'
|
||||
|
||||
if result:
|
||||
infoMsg = "%sparameter '%s' is '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title)
|
||||
@@ -991,7 +991,7 @@ def checkSuhosinPatch(injection):
|
||||
Checks for existence of Suhosin-patch (and alike) protection mechanism(s)
|
||||
"""
|
||||
|
||||
if injection.place == PLACE.GET:
|
||||
if injection.place in (PLACE.GET, PLACE.URI):
|
||||
debugMsg = "checking for parameter length "
|
||||
debugMsg += "constraining mechanisms"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
+25
-2
@@ -22,7 +22,10 @@ from lib.core.exception import SqlmapSystemException
|
||||
from lib.core.settings import BIGARRAY_CHUNK_SIZE
|
||||
from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
|
||||
|
||||
DEFAULT_SIZE_OF = sys.getsizeof(object())
|
||||
try:
|
||||
DEFAULT_SIZE_OF = sys.getsizeof(object())
|
||||
except TypeError:
|
||||
DEFAULT_SIZE_OF = 16
|
||||
|
||||
def _size_of(instance):
|
||||
"""
|
||||
@@ -56,6 +59,12 @@ class BigArray(list):
|
||||
>>> _[20] = 0
|
||||
>>> _[99999]
|
||||
99999
|
||||
>>> _ += [0]
|
||||
>>> _[100000]
|
||||
0
|
||||
>>> _ = _ + [1]
|
||||
>>> _[-1]
|
||||
1
|
||||
"""
|
||||
|
||||
def __init__(self, items=None):
|
||||
@@ -69,6 +78,20 @@ class BigArray(list):
|
||||
for item in (items or []):
|
||||
self.append(item)
|
||||
|
||||
def __add__(self, value):
|
||||
retval = BigArray(self)
|
||||
|
||||
for _ in value:
|
||||
retval.append(_)
|
||||
|
||||
return retval
|
||||
|
||||
def __iadd__(self, value):
|
||||
for _ in value:
|
||||
self.append(_)
|
||||
|
||||
return self
|
||||
|
||||
def append(self, value):
|
||||
self.chunks[-1].append(value)
|
||||
|
||||
@@ -145,7 +168,7 @@ class BigArray(list):
|
||||
self.chunks, self.filenames = state
|
||||
|
||||
def __getitem__(self, y):
|
||||
if y < 0:
|
||||
while y < 0:
|
||||
y += len(self)
|
||||
|
||||
index = y // self.chunk_length
|
||||
|
||||
+10
-2
@@ -2270,6 +2270,7 @@ def isMultiThreadMode():
|
||||
"""
|
||||
Checks if running in multi-thread(ing) mode
|
||||
|
||||
>>> import time
|
||||
>>> isMultiThreadMode()
|
||||
False
|
||||
>>> _ = lambda: time.sleep(0.1)
|
||||
@@ -2707,7 +2708,14 @@ def popValue():
|
||||
'foobar'
|
||||
"""
|
||||
|
||||
return getCurrentThreadData().valueStack.pop()
|
||||
retVal = None
|
||||
|
||||
try:
|
||||
retVal = getCurrentThreadData().valueStack.pop()
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
return retVal
|
||||
|
||||
def wasLastResponseDBMSError():
|
||||
"""
|
||||
@@ -5249,7 +5257,7 @@ def parseRequestFile(reqFile, checkParams=True):
|
||||
if "HTTP/" not in request:
|
||||
continue
|
||||
|
||||
if re.search(r"^[\n]*%s.*?\.(%s)\sHTTP\/" % (HTTPMETHOD.GET, "|".join(CRAWL_EXCLUDE_EXTENSIONS)), request, re.I | re.M):
|
||||
if re.search(r"^[\n]*%s[^?]*?\.(%s)\sHTTP\/" % (HTTPMETHOD.GET, "|".join(CRAWL_EXCLUDE_EXTENSIONS)), request, re.I | re.M):
|
||||
if not re.search(r"^[\n]*%s[^\n]*\*[^\n]*\sHTTP\/" % HTTPMETHOD.GET, request, re.I | re.M):
|
||||
continue
|
||||
|
||||
|
||||
+1
-1
@@ -370,10 +370,10 @@ OBSOLETE_OPTIONS = {
|
||||
"--check-payload": None,
|
||||
"--check-waf": None,
|
||||
"--pickled-options": "use '--api -c ...' instead",
|
||||
"--identify-waf": "functionality being done automatically",
|
||||
}
|
||||
|
||||
DEPRECATED_OPTIONS = {
|
||||
"--identify-waf": "functionality being done automatically",
|
||||
}
|
||||
|
||||
DUMP_DATA_PREPROCESS = {
|
||||
|
||||
+5
-3
@@ -16,9 +16,11 @@ from lib.core.common import Backend
|
||||
from lib.core.common import checkFile
|
||||
from lib.core.common import dataToDumpFile
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import filterNone
|
||||
from lib.core.common import getSafeExString
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import isMultiThreadMode
|
||||
from lib.core.common import isNoneValue
|
||||
from lib.core.common import normalizeUnicode
|
||||
from lib.core.common import openFile
|
||||
from lib.core.common import prioritySortColumns
|
||||
@@ -200,9 +202,9 @@ class Dump(object):
|
||||
self._write("%s:" % header)
|
||||
|
||||
for user in users:
|
||||
settings = userSettings[user]
|
||||
settings = filterNone(userSettings[user])
|
||||
|
||||
if settings is None:
|
||||
if isNoneValue(settings):
|
||||
stringSettings = ""
|
||||
else:
|
||||
stringSettings = " [%d]:" % len(settings)
|
||||
@@ -609,7 +611,7 @@ class Dump(object):
|
||||
_ = safechardecode(value, True)
|
||||
f.write(_)
|
||||
|
||||
except magic.MagicException as ex:
|
||||
except Exception as ex:
|
||||
logger.debug(getSafeExString(ex))
|
||||
|
||||
if conf.dumpFormat == DUMP_FORMAT.CSV:
|
||||
|
||||
+5
-4
@@ -201,16 +201,16 @@ class HASH(object):
|
||||
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
|
||||
class MOBILES(object):
|
||||
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+")
|
||||
GALAXY = ("Samsung Galaxy S7", "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36")
|
||||
GALAXY = ("Samsung Galaxy S8", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.0.0.50263AP")
|
||||
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
|
||||
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36")
|
||||
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36")
|
||||
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
|
||||
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.14977")
|
||||
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063")
|
||||
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
|
||||
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
|
||||
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR3.170623.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36")
|
||||
XIAOMI = ("Xiaomi Mi 3", "Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; MI 3W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 XiaoMi/MiuiBrowser/2.1.1")
|
||||
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 10; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.117 Mobile Safari/537.36")
|
||||
XIAOMI = ("Xiaomi Mi 8 Pro", "Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36")
|
||||
|
||||
class PROXY_TYPE(object):
|
||||
HTTP = "HTTP"
|
||||
@@ -402,6 +402,7 @@ class CONTENT_STATUS(object):
|
||||
class AUTH_TYPE(object):
|
||||
BASIC = "basic"
|
||||
DIGEST = "digest"
|
||||
BEARER = "bearer"
|
||||
NTLM = "ntlm"
|
||||
PKI = "pki"
|
||||
|
||||
|
||||
+7
-1
@@ -20,6 +20,7 @@ from lib.core.data import paths
|
||||
from lib.core.defaults import defaults
|
||||
from lib.core.enums import MKSTEMP_PREFIX
|
||||
from lib.core.exception import SqlmapMissingDependence
|
||||
from lib.core.exception import SqlmapSystemException
|
||||
from lib.core.settings import DEV_EMAIL_ADDRESS
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import ISSUES_PAGE
|
||||
@@ -72,7 +73,12 @@ def runGui(parser):
|
||||
tab = event.widget.nametowidget(event.widget.select())
|
||||
event.widget.configure(height=tab.winfo_reqheight())
|
||||
|
||||
window = _tkinter.Tk()
|
||||
try:
|
||||
window = _tkinter.Tk()
|
||||
except Exception as ex:
|
||||
errMsg = "unable to create GUI window ('%s')" % getSafeExString(ex)
|
||||
raise SqlmapSystemException(errMsg)
|
||||
|
||||
window.title(VERSION_STRING)
|
||||
|
||||
# Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
|
||||
|
||||
+13
-4
@@ -76,6 +76,7 @@ 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 DUMP_FORMAT
|
||||
from lib.core.enums import FORK
|
||||
from lib.core.enums import HTTP_HEADER
|
||||
from lib.core.enums import HTTPMETHOD
|
||||
from lib.core.enums import MKSTEMP_PREFIX
|
||||
@@ -727,7 +728,7 @@ def _setDBMS():
|
||||
|
||||
if conf.dbms not in SUPPORTED_DBMS:
|
||||
errMsg = "you provided an unsupported back-end database management "
|
||||
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted(_ for _ in DBMS_DICT))
|
||||
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted((_ for _ in (list(DBMS_DICT) + getPublicTypeMembers(FORK, True))), key=str.lower))
|
||||
errMsg += "If you do not know the back-end DBMS, do not provide "
|
||||
errMsg += "it and sqlmap will fingerprint it for you."
|
||||
raise SqlmapUnsupportedDBMSException(errMsg)
|
||||
@@ -1310,7 +1311,7 @@ def _setAuthCred():
|
||||
|
||||
def _setHTTPAuthentication():
|
||||
"""
|
||||
Check and set the HTTP(s) authentication method (Basic, Digest, NTLM or PKI),
|
||||
Check and set the HTTP(s) authentication method (Basic, Digest, Bearer, NTLM or PKI),
|
||||
username and password for first three methods, or PEM private key file for
|
||||
PKI authentication
|
||||
"""
|
||||
@@ -1333,9 +1334,9 @@ def _setHTTPAuthentication():
|
||||
errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
|
||||
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.BEARER, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
|
||||
errMsg = "HTTP authentication type value must be "
|
||||
errMsg += "Basic, Digest, NTLM or PKI"
|
||||
errMsg += "Basic, Digest, Bearer, NTLM or PKI"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if not conf.authFile:
|
||||
@@ -1348,6 +1349,9 @@ def _setHTTPAuthentication():
|
||||
regExp = "^(.*?):(.*?)$"
|
||||
errMsg = "HTTP %s authentication credentials " % authType
|
||||
errMsg += "value must be in format 'username:password'"
|
||||
elif authType == AUTH_TYPE.BEARER:
|
||||
conf.httpHeaders.append((HTTP_HEADER.AUTHORIZATION, "Bearer %s" % conf.authCred.strip()))
|
||||
return
|
||||
elif authType == AUTH_TYPE.NTLM:
|
||||
regExp = "^(.*\\\\.*):(.*?)$"
|
||||
errMsg = "HTTP NTLM authentication credentials value must "
|
||||
@@ -1997,6 +2001,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.cache = AttribDict()
|
||||
kb.cache.addrinfo = {}
|
||||
kb.cache.content = {}
|
||||
kb.cache.comparison = {}
|
||||
kb.cache.encoding = {}
|
||||
kb.cache.alphaBoundaries = None
|
||||
kb.cache.hashRegex = None
|
||||
@@ -2553,6 +2558,10 @@ def _basicOptionValidation():
|
||||
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.base64Parameter and conf.tamper:
|
||||
errMsg = "option '--base64' is incompatible with option '--tamper'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.eta and conf.verbose > defaults.verbose:
|
||||
errMsg = "switch '--eta' is incompatible with option '-v'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
+11
-4
@@ -11,6 +11,7 @@ import random
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import time
|
||||
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||
@@ -18,7 +19,7 @@ from lib.core.enums import OS
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.5.3.0"
|
||||
VERSION = "1.5.6.0"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
@@ -105,7 +106,7 @@ FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|comparable|compatible|conversion|conv
|
||||
FUZZ_UNION_MAX_COLUMNS = 10
|
||||
|
||||
# Regular expression used for recognition of generic maximum connection messages
|
||||
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
|
||||
MAX_CONNECTIONS_REGEX = r"\bmax.{1,100}\bconnection"
|
||||
|
||||
# Maximum consecutive connection errors before asking the user if he wants to continue
|
||||
MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
|
||||
@@ -125,6 +126,9 @@ MAX_MURPHY_SLEEP_TIME = 3
|
||||
# Regular expression used for extracting results from Google search
|
||||
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
|
||||
|
||||
# Google Search consent cookie
|
||||
GOOGLE_CONSENT_COOKIE = "CONSENT=YES+shp.gws-%s-0-RC1.%s+FX+740" % (time.strftime("%Y%m%d"), "".join(random.sample(string.ascii_lowercase, 2)))
|
||||
|
||||
# Regular expression used for extracting results from DuckDuckGo search
|
||||
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'
|
||||
|
||||
@@ -288,7 +292,7 @@ VIRTUOSO_SYSTEM_DBS = ("",)
|
||||
# Note: (<regular>) + (<forks>)
|
||||
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona", "drizzle")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte", "yugabytedb")
|
||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "amazon redshift", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte", "yugabytedb")
|
||||
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
||||
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
||||
ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet")
|
||||
@@ -297,7 +301,7 @@ MAXDB_ALIASES = ("max", "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", "ignite")
|
||||
H2_ALIASES = ("h2",) + ("ignite", "apache ignite")
|
||||
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
|
||||
MONETDB_ALIASES = ("monet", "monetdb",)
|
||||
DERBY_ALIASES = ("derby", "apache derby",)
|
||||
@@ -505,6 +509,9 @@ REFLECTED_MAX_REGEX_PARTS = 10
|
||||
# Chars which can be used as a failsafe values in case of too long URL encoding value
|
||||
URLENCODE_FAILSAFE_CHARS = "()|,"
|
||||
|
||||
# Factor used for yuge page multiplication
|
||||
YUGE_FACTOR = 1000
|
||||
|
||||
# Maximum length of URL encoded value after which failsafe procedure takes away
|
||||
URLENCODE_CHAR_LIMIT = 2000
|
||||
|
||||
|
||||
+10
-107
@@ -42,7 +42,7 @@ def vulnTest():
|
||||
("--dependencies --deprecations", ("sqlmap requires", "third-party library", "~DeprecationWarning:")),
|
||||
("-u <url> --data='reflect=1' --flush-session --wizard --disable-coloring", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
|
||||
("-u <url> --data='code=1' --code=200 --technique=B --banner --no-cast --flush-session", ("back-end DBMS: SQLite", "banner: '3.", "~COALESCE(CAST(")),
|
||||
(u"-c <config> --flush-session --output-dir=\"<tmdir>\"--smart --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible", "as the output directory")),
|
||||
(u"-c <config> --flush-session --output-dir=\"<tmpdir>\" --smart --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible", "as the output directory")),
|
||||
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
|
||||
("-m <multiple> --flush-session --technique=B --banner", ("URL 3:", "back-end DBMS: SQLite", "banner: '3.")),
|
||||
("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable", "there is not at least one", "~might be injectable")),
|
||||
@@ -61,8 +61,8 @@ def vulnTest():
|
||||
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
|
||||
("-u <base> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||
("-u <base> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
||||
("-u <base> --flush-session --method=PUT --data='a=1;id=1;b=2' --param-del=';' --skip-static --har=<tmp> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmp>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <base> --flush-session --method=PUT --data='a=1;id=1;b=2' --param-del=';' --skip-static --har=<tmpfile> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmpfile>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
||||
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 5")),
|
||||
@@ -145,10 +145,10 @@ def vulnTest():
|
||||
|
||||
cmd = "%s \"%s\" %s --batch --non-interactive --debug" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||
|
||||
if "<tmp>" in cmd:
|
||||
if "<tmpfile>" in cmd:
|
||||
handle, tmp = tempfile.mkstemp()
|
||||
os.close(handle)
|
||||
cmd = cmd.replace("<tmp>", tmp)
|
||||
cmd = cmd.replace("<tmpfile>", tmp)
|
||||
|
||||
if "<piped>" in cmd:
|
||||
cmd = re.sub(r"<piped>\s*", "", cmd)
|
||||
@@ -171,107 +171,6 @@ def vulnTest():
|
||||
|
||||
return retVal
|
||||
|
||||
def bedTest():
|
||||
"""
|
||||
Runs the testing against 'testbed'
|
||||
"""
|
||||
|
||||
TESTS = (
|
||||
# MaxDB
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'SAP MaxDB'", "the back-end DBMS is SAP MaxDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is SAP MaxDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Kernel____7.9.10___Build_003-123-265-343", "current database (equivalent to owner on SAP MaxDB): 'SYS'", "current user: 'DBADMIN'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# Informix
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("retrieved: 47", "IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# Altibase
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Altibase'", "the back-end DBMS is Altibase", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Altibase", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("x86_64-unknown-linux-gnu", "current database (equivalent to owner on Altibase): 'SYS'", "current user: 'SYS'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# CockroachDB
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: PostgreSQL AND error-based", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-unknown-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'root'", "[1 column]", "| surname | varchar |")),
|
||||
|
||||
# CrateDB
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("4.0.10", "Database: doc", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'CrateDB'", "the back-end DBMS is CrateDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("4.0.10", "current database (equivalent to schema on CrateDB): 'doc'", "current user: 'crate'", "[1 column]", "| surname |")),
|
||||
|
||||
# Drizzle
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "7.1.36-stable", "current database: 'testdb'", "current user: 'root'", "[1 column]", "| surname | VARCHAR |")),
|
||||
|
||||
# Firebird
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "possible DBMS: 'Firebird'", "the back-end DBMS is Firebird", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --is-dba --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Firebird", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --search -C surname --answers='dump=n'", ("banner: '2.5", "current user: 'SYSDBA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# H2
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'H2'", "the back-end DBMS is H2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is H2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: Generic inline queries", "Title: Generic UNION query (NULL) - 3 columns", "1.4.192", "current database (equivalent to schema on H2): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# HSQLDB
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'HSQLDB'", "the back-end DBMS is HSQLDB", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is HSQLDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: HSQLDB > 2.0 AND time-based blind (heavy query)", "Title: Generic UNION query (NULL) - 3 columns", "2.3.4", "current database (equivalent to schema on HSQLDB): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||
|
||||
# IBM DB2
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'IBM DB2'", "the back-end DBMS is IBM DB2", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is IBM DB2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("banner: 'DB2 v", "current database (equivalent to owner on IBM DB2): 'DB2INST1'", "current user: 'DB2INST1'", "[1 column]", "| SURNAME | VARCHAR(1000) |")),
|
||||
|
||||
# MariaDB
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "10.4.12-MariaDB-1:10.4.12+maria~bionic", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# MySQL
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.1 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "8.0.19", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||
|
||||
# PostgreSQL
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: False", ": 'foobar'")),
|
||||
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-pc-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||
)
|
||||
|
||||
retVal = True
|
||||
count = 0
|
||||
|
||||
for options, checks in TESTS:
|
||||
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||
|
||||
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||
output = shellExec(cmd)
|
||||
|
||||
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||
for check in checks:
|
||||
if check not in output:
|
||||
print(cmd, check)
|
||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||
dataToStdout("%s---\n" % output, coloring=False)
|
||||
retVal = False
|
||||
|
||||
count += 1
|
||||
|
||||
clearConsoleLine()
|
||||
if retVal:
|
||||
logger.info("bed test final result: PASSED")
|
||||
else:
|
||||
logger.error("best test final result: FAILED")
|
||||
|
||||
return retVal
|
||||
|
||||
def fuzzTest():
|
||||
count = 0
|
||||
address, port = "127.0.0.10", random.randint(1025, 65535)
|
||||
@@ -309,11 +208,15 @@ def fuzzTest():
|
||||
if any(_ in lines[j] for _ in ("googleDork",)):
|
||||
continue
|
||||
|
||||
if re.search(r"= (True|False)", lines[j]):
|
||||
lines[j] = lines[j].replace(" = False", " = True")
|
||||
continue
|
||||
|
||||
if lines[j].strip().endswith('='):
|
||||
lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0]
|
||||
|
||||
k = random.randint(0, len(lines) - 1)
|
||||
if '=' in lines[k]:
|
||||
if '=' in lines[k] and not re.search(r"= (True|False)", lines[k]):
|
||||
lines[k] += chr(random.randint(0, 255))
|
||||
|
||||
open(config, "w+").write("\n".join(lines))
|
||||
|
||||
@@ -193,7 +193,7 @@ def cmdLineParser(argv=None):
|
||||
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
|
||||
|
||||
request.add_argument("--auth-type", dest="authType",
|
||||
help="HTTP authentication type (Basic, Digest, NTLM or PKI)")
|
||||
help="HTTP authentication type (Basic, Digest, Bearer, ...)")
|
||||
|
||||
request.add_argument("--auth-cred", dest="authCred",
|
||||
help="HTTP authentication credentials (name:password)")
|
||||
@@ -704,7 +704,7 @@ def cmdLineParser(argv=None):
|
||||
help="Regexp for filtering targets")
|
||||
|
||||
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
|
||||
help="Skip heuristic detection of SQLi/XSS/FI vulnerabilities")
|
||||
help="Skip heuristic detection of vulnerabilities")
|
||||
|
||||
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
|
||||
help="Skip heuristic detection of WAF/IPS protection")
|
||||
@@ -731,7 +731,7 @@ def cmdLineParser(argv=None):
|
||||
help="Run host OS command(s) when SQL injection is found")
|
||||
|
||||
miscellaneous.add_argument("--beep", dest="beep", action="store_true",
|
||||
help="Beep on question and/or when SQLi/XSS/FI is found")
|
||||
help="Beep on question and/or when vulnerability is found")
|
||||
|
||||
miscellaneous.add_argument("--dependencies", dest="dependencies", action="store_true",
|
||||
help="Check for missing (optional) sqlmap dependencies")
|
||||
@@ -824,9 +824,6 @@ def cmdLineParser(argv=None):
|
||||
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
||||
help=SUPPRESS)
|
||||
|
||||
@@ -979,6 +976,8 @@ def cmdLineParser(argv=None):
|
||||
argv[i] = ""
|
||||
elif argv[i].startswith("--data-raw"):
|
||||
argv[i] = argv[i].replace("--data-raw", "--data", 1)
|
||||
elif argv[i].startswith("--auth-creds"):
|
||||
argv[i] = argv[i].replace("--auth-creds", "--auth-cred", 1)
|
||||
elif argv[i].startswith("--drop-cookie"):
|
||||
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
|
||||
elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")):
|
||||
@@ -1066,7 +1065,7 @@ def cmdLineParser(argv=None):
|
||||
else:
|
||||
args.stdinPipe = None
|
||||
|
||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.bedTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
|
||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
|
||||
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). "
|
||||
errMsg += "Use -h for basic and -hh for advanced help\n"
|
||||
parser.error(errMsg)
|
||||
|
||||
@@ -13,6 +13,7 @@ from lib.core.common import extractRegexResult
|
||||
from lib.core.common import getFilteredPageContent
|
||||
from lib.core.common import listToStrValue
|
||||
from lib.core.common import removeDynamicContent
|
||||
from lib.core.common import getLastRequestHTTPError
|
||||
from lib.core.common import wasLastResponseDBMSError
|
||||
from lib.core.common import wasLastResponseHTTPError
|
||||
from lib.core.convert import getBytes
|
||||
@@ -91,7 +92,8 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
if page:
|
||||
# In case of an DBMS error page return None
|
||||
if kb.errorIsNone and (wasLastResponseDBMSError() or wasLastResponseHTTPError()) and not kb.negativeLogic:
|
||||
return None
|
||||
if not (wasLastResponseHTTPError() and getLastRequestHTTPError() in (conf.ignoreCode or [])):
|
||||
return None
|
||||
|
||||
# Dynamic content lines to be excluded before comparison
|
||||
if not kb.nullConnection:
|
||||
@@ -151,10 +153,20 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||
seq1 = seq1.split("\n")
|
||||
seq2 = seq2.split("\n")
|
||||
|
||||
key = None
|
||||
else:
|
||||
key = (hash(seq1), hash(seq2))
|
||||
|
||||
seqMatcher.set_seq1(seq1)
|
||||
seqMatcher.set_seq2(seq2)
|
||||
|
||||
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
|
||||
if key in kb.cache.comparison:
|
||||
ratio = kb.cache.comparison[key]
|
||||
else:
|
||||
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
|
||||
|
||||
if key:
|
||||
kb.cache.comparison[key] = ratio
|
||||
|
||||
# If the url is stable and we did not set yet the match ratio and the
|
||||
# current injected value changes the url page content
|
||||
|
||||
@@ -126,6 +126,7 @@ from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.settings import URI_HTTP_HEADER
|
||||
from lib.core.settings import WARN_TIME_STDEV
|
||||
from lib.core.settings import WEBSOCKET_INITIAL_TIMEOUT
|
||||
from lib.core.settings import YUGE_FACTOR
|
||||
from lib.request.basic import decodePage
|
||||
from lib.request.basic import forgeHeaders
|
||||
from lib.request.basic import processResponse
|
||||
@@ -253,7 +254,7 @@ class Connect(object):
|
||||
break
|
||||
|
||||
if conf.yuge:
|
||||
retVal = 100 * retVal
|
||||
retVal = YUGE_FACTOR * retVal
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -788,7 +789,7 @@ class Connect(object):
|
||||
debugMsg = "got HTTP error code: %d ('%s')" % (code, status)
|
||||
logger.debug(debugMsg)
|
||||
|
||||
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError):
|
||||
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError, AttributeError):
|
||||
tbMsg = traceback.format_exc()
|
||||
|
||||
if conf.debug:
|
||||
@@ -796,6 +797,11 @@ class Connect(object):
|
||||
|
||||
if checking:
|
||||
return None, None, None
|
||||
elif "AttributeError:" in tbMsg:
|
||||
if "WSAECONNREFUSED" in tbMsg:
|
||||
return None, None, None
|
||||
else:
|
||||
raise
|
||||
elif "no host given" in tbMsg:
|
||||
warnMsg = "invalid URL address used (%s)" % repr(url)
|
||||
raise SqlmapSyntaxException(warnMsg)
|
||||
|
||||
+2
-2
@@ -68,8 +68,8 @@ class DNSServer(object):
|
||||
raw request
|
||||
|
||||
Reference(s):
|
||||
http://code.activestate.com/recipes/491264-mini-fake-dns-server/
|
||||
https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py
|
||||
https://code.activestate.com/recipes/491264-mini-fake-dns-server/
|
||||
https://web.archive.org/web/20150418152405/https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -26,6 +26,7 @@ from lib.core.common import goGoodSamaritan
|
||||
from lib.core.common import hashDBRetrieve
|
||||
from lib.core.common import hashDBWrite
|
||||
from lib.core.common import incrementCounter
|
||||
from lib.core.common import isListLike
|
||||
from lib.core.common import safeStringFormat
|
||||
from lib.core.common import singleTimeWarnMessage
|
||||
from lib.core.data import conf
|
||||
@@ -217,7 +218,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
|
||||
markingValue = "'%s'" % CHAR_INFERENCE_MARK
|
||||
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
|
||||
forgedPayload = agent.extractPayload(payload)
|
||||
forgedPayload = agent.extractPayload(payload) or ""
|
||||
forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue)).replace(markingValue, unescapedCharValue)
|
||||
result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
|
||||
incrementCounter(getTechnique())
|
||||
@@ -504,6 +505,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||
else:
|
||||
break
|
||||
|
||||
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4629
|
||||
if not isListLike(threadData.shared.value):
|
||||
break
|
||||
|
||||
with kb.locks.value:
|
||||
threadData.shared.value[currentCharIndex - 1 - firstChar] = val
|
||||
currentValue = list(threadData.shared.value)
|
||||
|
||||
+20
-18
@@ -13,22 +13,6 @@ except: # removed ImportError because of https://github.com/sqlmapproject/sqlma
|
||||
from thirdparty.fcrypt.fcrypt import crypt
|
||||
|
||||
_multiprocessing = None
|
||||
try:
|
||||
import multiprocessing
|
||||
|
||||
# problems on FreeBSD (Reference: https://web.archive.org/web/20110710041353/http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
||||
_ = multiprocessing.Queue()
|
||||
|
||||
# problems with ctypes (Reference: https://github.com/sqlmapproject/sqlmap/issues/2952)
|
||||
_ = multiprocessing.Value('i')
|
||||
except (ImportError, OSError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
if multiprocessing.cpu_count() > 1:
|
||||
_multiprocessing = multiprocessing
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
@@ -367,7 +351,7 @@ def crypt_generic_passwd(password, salt, **kwargs):
|
||||
'rl.3StKT.4T8M'
|
||||
"""
|
||||
|
||||
return crypt(password, salt)
|
||||
return getText(crypt(password, salt))
|
||||
|
||||
def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
|
||||
"""
|
||||
@@ -983,6 +967,24 @@ def dictionaryAttack(attack_dict):
|
||||
|
||||
if conf.disableMulti:
|
||||
_multiprocessing = None
|
||||
else:
|
||||
# Note: https://github.com/sqlmapproject/sqlmap/issues/4367
|
||||
try:
|
||||
import multiprocessing
|
||||
|
||||
# problems on FreeBSD (Reference: https://web.archive.org/web/20110710041353/http://www.eggheadcafe.com/microsoft/Python/35880259/multiprocessing-on-freebsd.aspx)
|
||||
_ = multiprocessing.Queue()
|
||||
|
||||
# problems with ctypes (Reference: https://github.com/sqlmapproject/sqlmap/issues/2952)
|
||||
_ = multiprocessing.Value('i')
|
||||
except (ImportError, OSError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
if multiprocessing.cpu_count() > 1:
|
||||
_multiprocessing = multiprocessing
|
||||
except NotImplementedError:
|
||||
pass
|
||||
|
||||
for (_, hashes) in attack_dict.items():
|
||||
for hash_ in hashes:
|
||||
@@ -1133,7 +1135,7 @@ def dictionaryAttack(attack_dict):
|
||||
custom_wordlist.append(normalizeUnicode(user))
|
||||
|
||||
# Algorithms without extra arguments (e.g. salt and/or username)
|
||||
if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD):
|
||||
if hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1):
|
||||
for suffix in suffix_list:
|
||||
if not attack_info or processException:
|
||||
break
|
||||
|
||||
+3
-1
@@ -28,6 +28,7 @@ from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.settings import BING_REGEX
|
||||
from lib.core.settings import DUCKDUCKGO_REGEX
|
||||
from lib.core.settings import DUMMY_SEARCH_USER_AGENT
|
||||
from lib.core.settings import GOOGLE_CONSENT_COOKIE
|
||||
from lib.core.settings import GOOGLE_REGEX
|
||||
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
@@ -52,6 +53,7 @@ def _search(dork):
|
||||
|
||||
requestHeaders[HTTP_HEADER.USER_AGENT] = dict(conf.httpHeaders).get(HTTP_HEADER.USER_AGENT, DUMMY_SEARCH_USER_AGENT)
|
||||
requestHeaders[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE
|
||||
requestHeaders[HTTP_HEADER.COOKIE] = GOOGLE_CONSENT_COOKIE
|
||||
|
||||
try:
|
||||
req = _urllib.request.Request("https://www.google.com/ncr", headers=requestHeaders)
|
||||
@@ -63,7 +65,7 @@ def _search(dork):
|
||||
gpage = conf.googlePage if conf.googlePage > 1 else 1
|
||||
logger.info("using search result page #%d" % gpage)
|
||||
|
||||
url = "https://www.google.com/search?"
|
||||
url = "https://www.google.com/search?" # NOTE: if consent fails, try to use the "http://"
|
||||
url += "q=%s&" % urlencode(dork, convall=True)
|
||||
url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search"
|
||||
url += "&start=%d" % ((gpage - 1) * 100)
|
||||
|
||||
+11
-2
@@ -101,13 +101,22 @@ class SQLAlchemy(GenericConnector):
|
||||
return None
|
||||
|
||||
def execute(self, query):
|
||||
retVal = False
|
||||
|
||||
try:
|
||||
self.cursor = self.connector.execute(query)
|
||||
retVal = True
|
||||
except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError) as ex:
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||
except _sqlalchemy.exc.InternalError as ex:
|
||||
raise SqlmapConnectionException(getSafeExString(ex))
|
||||
|
||||
return retVal
|
||||
|
||||
def select(self, query):
|
||||
self.execute(query)
|
||||
return self.fetchall()
|
||||
retVal = None
|
||||
|
||||
if self.execute(query):
|
||||
retVal = self.fetchall()
|
||||
|
||||
return retVal
|
||||
|
||||
@@ -22,9 +22,8 @@ from plugins.generic.connector import Connector as GenericConnector
|
||||
|
||||
class Connector(GenericConnector):
|
||||
"""
|
||||
Homepage: http://pyodbc.googlecode.com/
|
||||
User guide: http://code.google.com/p/pyodbc/wiki/GettingStarted
|
||||
API: http://code.google.com/p/pyodbc/w/list
|
||||
Homepage: https://github.com/mkleehammer/pyodbc
|
||||
User guide: https://github.com/mkleehammer/pyodbc/wiki
|
||||
Debian package: python-pyodbc
|
||||
License: MIT
|
||||
"""
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
|
||||
@@ -150,7 +150,8 @@ class Fingerprint(GenericFingerprint):
|
||||
"Vista or 2008": ("6.0", (2, 1)),
|
||||
"7 or 2008 R2": ("6.1", (1, 0)),
|
||||
"8 or 2012": ("6.2", (0,)),
|
||||
"8.1 or 2012 R2": ("6.3", (0,))
|
||||
"8.1 or 2012 R2": ("6.3", (0,)),
|
||||
"10 or 2016 or 2019": ("10.0", (0,))
|
||||
}
|
||||
|
||||
# Get back-end DBMS underlying operating system version
|
||||
|
||||
@@ -21,10 +21,9 @@ from plugins.generic.connector import Connector as GenericConnector
|
||||
|
||||
class Connector(GenericConnector):
|
||||
"""
|
||||
Homepage: http://code.google.com/p/pymysql/
|
||||
User guide: http://code.google.com/p/pymysql/
|
||||
API: http://code.google.com/p/pymysql/
|
||||
Debian package: <none>
|
||||
Homepage: https://github.com/PyMySQL/PyMySQL
|
||||
User guide: https://pymysql.readthedocs.io/en/latest/
|
||||
Debian package: python3-pymysql
|
||||
License: MIT
|
||||
|
||||
Possible connectors: http://wiki.python.org/moin/MySQL
|
||||
|
||||
@@ -45,10 +45,10 @@ class Fingerprint(GenericFingerprint):
|
||||
# Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/
|
||||
|
||||
versions = (
|
||||
(80000, 80021), # MySQL 8.0
|
||||
(80000, 80028), # MySQL 8.0
|
||||
(60000, 60014), # MySQL 6.0
|
||||
(50700, 50731), # MySQL 5.7
|
||||
(50600, 50649), # MySQL 5.6
|
||||
(50700, 50736), # MySQL 5.7
|
||||
(50600, 50652), # MySQL 5.6
|
||||
(50500, 50563), # MySQL 5.5
|
||||
(50400, 50404), # MySQL 5.4
|
||||
(50100, 50174), # MySQL 5.1
|
||||
|
||||
@@ -105,7 +105,7 @@ class Fingerprint(GenericFingerprint):
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Reference: https://en.wikipedia.org/wiki/Oracle_Database
|
||||
for version in ("19c", "18c", "12c", "11g", "10g", "9i", "8i", "7"):
|
||||
for version in ("21c", "19c", "18c", "12c", "11g", "10g", "9i", "8i", "7"):
|
||||
number = int(re.search(r"([\d]+)", version).group(1))
|
||||
output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))
|
||||
|
||||
|
||||
@@ -131,7 +131,9 @@ class Fingerprint(GenericFingerprint):
|
||||
infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
|
||||
logger.info(infoMsg)
|
||||
|
||||
if inject.checkBooleanExpression("SINH(0)=0"):
|
||||
if inject.checkBooleanExpression("GEN_RANDOM_UUID() IS NOT NULL"):
|
||||
Backend.setVersion(">= 13.0")
|
||||
elif inject.checkBooleanExpression("SINH(0)=0"):
|
||||
Backend.setVersion(">= 12.0")
|
||||
elif inject.checkBooleanExpression("SHA256(NULL) IS NULL"):
|
||||
Backend.setVersion(">= 11.0")
|
||||
|
||||
@@ -5,35 +5,18 @@ Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import binascii
|
||||
|
||||
from lib.core.common import isDBMSVersionAtLeast
|
||||
from lib.core.convert import getBytes
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.convert import getOrds
|
||||
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||
|
||||
class Syntax(GenericSyntax):
|
||||
@staticmethod
|
||||
def escape(expression, quote=True):
|
||||
"""
|
||||
>>> from lib.core.common import Backend
|
||||
>>> Backend.setVersion('2')
|
||||
['2']
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT 'abcdefgh' FROM foobar"
|
||||
True
|
||||
>>> Backend.setVersion('3')
|
||||
['3']
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CAST(X'6162636465666768' AS TEXT) FROM foobar"
|
||||
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97,98,99,100,101,102,103,104) FROM foobar"
|
||||
True
|
||||
"""
|
||||
|
||||
def escaper(value):
|
||||
# Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3
|
||||
return "CAST(X'%s' AS TEXT)" % getUnicode(binascii.hexlify(getBytes(value)))
|
||||
return "CHAR(%s)" % ','.join("%d" % _ for _ in getOrds(value))
|
||||
|
||||
retVal = expression
|
||||
|
||||
if isDBMSVersionAtLeast('3'):
|
||||
retVal = Syntax._escape(expression, quote, escaper)
|
||||
|
||||
return retVal
|
||||
return Syntax._escape(expression, quote, escaper)
|
||||
|
||||
@@ -63,20 +63,20 @@ class Connector(object):
|
||||
|
||||
def connect(self):
|
||||
errMsg = "'connect' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def fetchall(self):
|
||||
errMsg = "'fetchall' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def execute(self, query):
|
||||
errMsg = "'execute' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
def select(self, query):
|
||||
errMsg = "'select' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
errMsg += "inside the specific DBMS plugin"
|
||||
raise SqlmapUndefinedMethod(errMsg)
|
||||
|
||||
@@ -21,6 +21,7 @@ from lib.core.dicts import SQL_STATEMENTS
|
||||
from lib.core.enums import AUTOCOMPLETE_TYPE
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.exception import SqlmapNoneDataException
|
||||
from lib.core.settings import METADB_SUFFIX
|
||||
from lib.core.settings import NULL
|
||||
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
||||
from lib.core.shell import autoCompletion
|
||||
@@ -56,6 +57,8 @@ class Custom(object):
|
||||
if match and match.group(2).count('.') == 1:
|
||||
query = query.replace(match.group(0), "%s%s" % (match.group(1), match.group(2).replace('.', ".dbo.")))
|
||||
|
||||
query = re.sub(r"(?i)\w+%s\.?" % METADB_SUFFIX, "", query)
|
||||
|
||||
output = inject.getValue(query, fromUser=True)
|
||||
|
||||
return output
|
||||
|
||||
@@ -594,7 +594,7 @@ class Databases(object):
|
||||
if conf.db is not None and len(kb.data.cachedColumns) > 0 \
|
||||
and conf.db in kb.data.cachedColumns and tbl in \
|
||||
kb.data.cachedColumns[conf.db]:
|
||||
infoMsg = "fetched tables' columns on "
|
||||
infoMsg = "fetched table columns from "
|
||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -619,7 +619,7 @@ class Databases(object):
|
||||
query += condQuery
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("column_type", "data_type")
|
||||
query = re.sub("column_type", "data_type", query, flags=re.I)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||
@@ -730,7 +730,7 @@ class Databases(object):
|
||||
if conf.db is not None and len(kb.data.cachedColumns) > 0 \
|
||||
and conf.db in kb.data.cachedColumns and tbl in \
|
||||
kb.data.cachedColumns[conf.db]:
|
||||
infoMsg = "fetched tables' columns on "
|
||||
infoMsg = "fetched table columns from "
|
||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
logger.info(infoMsg)
|
||||
|
||||
@@ -1050,7 +1050,7 @@ class Databases(object):
|
||||
query = rootQuery.blind.count
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||
query = re.sub("INFORMATION_SCHEMA", "DATA_DICTIONARY", query, flags=re.I)
|
||||
|
||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||
|
||||
@@ -1078,7 +1078,7 @@ class Databases(object):
|
||||
query = rootQuery.blind.query % index
|
||||
|
||||
if Backend.isFork(FORK.DRIZZLE):
|
||||
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||
query = re.sub("INFORMATION_SCHEMA", "DATA_DICTIONARY", query, flags=re.I)
|
||||
|
||||
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class Entries(object):
|
||||
singleTimeLogMessage(infoMsg)
|
||||
return
|
||||
|
||||
conf.db = safeSQLIdentificatorNaming(conf.db)
|
||||
conf.db = safeSQLIdentificatorNaming(conf.db) or ""
|
||||
|
||||
if conf.tbl:
|
||||
if Backend.getIdentifiedDbms() in UPPER_CASE_DBMSES:
|
||||
@@ -101,7 +101,7 @@ class Entries(object):
|
||||
|
||||
if tblList and isListLike(tblList[0]):
|
||||
tblList = tblList[0]
|
||||
elif not conf.search:
|
||||
elif conf.db and not conf.search:
|
||||
errMsg = "unable to retrieve the tables "
|
||||
errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||
raise SqlmapNoneDataException(errMsg)
|
||||
@@ -190,7 +190,7 @@ class Entries(object):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||
# Partial inband and error
|
||||
if not (isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
table = "%s.%s" % (conf.db, tbl) if conf.db else tbl
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
|
||||
warnMsg = "in case of table dumping problems (e.g. column entry order) "
|
||||
@@ -297,7 +297,7 @@ class Entries(object):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.MAXDB, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB, DBMS.RAIMA):
|
||||
query = rootQuery.blind.count % tbl
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
|
||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl)) if conf.db else tbl
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
query = rootQuery.blind.count % (conf.db, tbl)
|
||||
else:
|
||||
@@ -334,9 +334,9 @@ class Entries(object):
|
||||
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.RAIMA):
|
||||
table = tbl
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB):
|
||||
table = "%s.%s" % (conf.db, tbl)
|
||||
table = "%s.%s" % (conf.db, tbl) if conf.db else tbl
|
||||
elif Backend.isDbms(DBMS.INFORMIX):
|
||||
table = "%s:%s" % (conf.db, tbl)
|
||||
table = "%s:%s" % (conf.db, tbl) if conf.db else tbl
|
||||
|
||||
if Backend.isDbms(DBMS.MSSQL) and not conf.forcePivoting:
|
||||
warnMsg = "in case of table dumping problems (e.g. column entry order) "
|
||||
|
||||
@@ -145,7 +145,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry):
|
||||
except ImportError:
|
||||
errMsg = "sqlmap requires 'python-impacket' third-party library "
|
||||
errMsg += "in order to run icmpsh master. You can get it at "
|
||||
errMsg += "http://code.google.com/p/impacket/downloads/list"
|
||||
errMsg += "https://github.com/SecureAuthCorp/impacket"
|
||||
raise SqlmapMissingDependence(errMsg)
|
||||
|
||||
filename = "/proc/sys/net/ipv4/icmp_echo_ignore_all"
|
||||
|
||||
+3
-3
@@ -87,12 +87,12 @@ headers = Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9
|
||||
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
|
||||
|
||||
# HTTP Authentication type. Useful only if the target URL requires
|
||||
# HTTP Basic, Digest or NTLM authentication and you have such data.
|
||||
# Valid: Basic, Digest, NTLM or PKI
|
||||
# HTTP Basic, Digest, Bearer or NTLM authentication and you have such data.
|
||||
# Valid: Basic, Digest, Bearer, NTLM or PKI
|
||||
authType =
|
||||
|
||||
# HTTP authentication credentials. Useful only if the target URL requires
|
||||
# HTTP Basic, Digest or NTLM authentication and you have such data.
|
||||
# HTTP Basic, Digest, Token or NTLM authentication and you have such data.
|
||||
# Syntax: username:password
|
||||
authCred =
|
||||
|
||||
|
||||
@@ -175,9 +175,6 @@ def main():
|
||||
elif conf.vulnTest:
|
||||
from lib.core.testing import vulnTest
|
||||
os._exitcode = 1 - (vulnTest() or 0)
|
||||
elif conf.bedTest:
|
||||
from lib.core.testing import bedTest
|
||||
os._exitcode = 1 - (bedTest() or 0)
|
||||
elif conf.fuzzTest:
|
||||
from lib.core.testing import fuzzTest
|
||||
fuzzTest()
|
||||
@@ -193,6 +190,8 @@ def main():
|
||||
targets = getFileItems(conf.bulkFile)
|
||||
|
||||
for i in xrange(len(targets)):
|
||||
target = None
|
||||
|
||||
try:
|
||||
kb.targets.clear()
|
||||
target = targets[i]
|
||||
@@ -205,7 +204,7 @@ def main():
|
||||
|
||||
crawl(target)
|
||||
except Exception as ex:
|
||||
if not isinstance(ex, SqlmapUserQuitException):
|
||||
if target and not isinstance(ex, SqlmapUserQuitException):
|
||||
errMsg = "problem occurred while crawling '%s' ('%s')" % (target, getSafeExString(ex))
|
||||
logger.error(errMsg)
|
||||
else:
|
||||
@@ -387,6 +386,12 @@ def main():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif "'WebSocket' object has no attribute 'status'" in excMsg:
|
||||
errMsg = "wrong websocket library detected"
|
||||
errMsg += " (Reference: 'https://github.com/sqlmapproject/sqlmap/issues/4572#issuecomment-775041086')"
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("window = tkinter.Tk()",)):
|
||||
errMsg = "there has been a problem in initialization of GUI interface "
|
||||
errMsg += "('%s')" % excMsg.strip().split('\n')[-1]
|
||||
@@ -436,6 +441,11 @@ def main():
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("No such file", "sqlmap.conf", "Test")):
|
||||
errMsg = "you are trying to run (hidden) development tests inside the production environment"
|
||||
logger.critical(errMsg)
|
||||
raise SystemExit
|
||||
|
||||
elif all(_ in excMsg for _ in ("HTTPNtlmAuthHandler", "'str' object has no attribute 'decode'")):
|
||||
errMsg = "package 'python-ntlm' has a known compatibility issue with the "
|
||||
errMsg += "Python 3 (Reference: 'https://github.com/mullender/python-ntlm/pull/61')"
|
||||
|
||||
Vendored
-1
@@ -4,7 +4,6 @@
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
-2
@@ -85,7 +85,6 @@ __copyright__ = "Copyright (c) 2004-2012 Leonard Richardson"
|
||||
__license__ = "New-style BSD"
|
||||
|
||||
import codecs
|
||||
import types
|
||||
import re
|
||||
import sys
|
||||
|
||||
@@ -2029,6 +2028,5 @@ class UnicodeDammit:
|
||||
|
||||
#By default, act as an HTML pretty-printer.
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
soup = BeautifulSoup(sys.stdin)
|
||||
print(soup.prettify())
|
||||
|
||||
Vendored
+1
-1
@@ -119,7 +119,7 @@ __all__ = ['crypt']
|
||||
# ----- END fcrypt.c LICENSE -----
|
||||
|
||||
|
||||
import string, struct, sys
|
||||
import struct, sys
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
xrange = range
|
||||
|
||||
Vendored
+14
-2
@@ -303,6 +303,12 @@
|
||||
"9bf2:RVdXum61OElCWapAYKYPk4JzWOtohM4IiUYMr2RXg1uQJbX2uhdOn9htOj+hX7AB16FcPxJPdLsXo2tKaK99n+i7c4RmkgI2FZjxtDtAeq+c3qA4chS1XKTC"
|
||||
]
|
||||
},
|
||||
"duedge": {
|
||||
"company": "Baidu",
|
||||
"name": "DuEdge",
|
||||
"regex": "(?s)<h1>403<small>.+DuEdge Event ID: [0-9a-f]{16}.+IP: [0-9.]+",
|
||||
"signatures": []
|
||||
},
|
||||
"expressionengine": {
|
||||
"company": "EllisLab",
|
||||
"name": "ExpressionEngine",
|
||||
@@ -536,6 +542,12 @@
|
||||
"125a:RVdXum61OElCWKpAYKYPk4JzWOtohM4JiUcMr2RXg1uQJbX3uhdOn9htOj+hX7AB16FcPxJPdLsXo2tLaK99n+i7c4VmkwI3FZnxtDtBeq+c36A5chW1XaTC"
|
||||
]
|
||||
},
|
||||
"openrasp": {
|
||||
"company": "Blackbaud",
|
||||
"name": "OpenRASP",
|
||||
"regex": "400 - Request blocked by OpenRASP|https://rasp.baidu.com/blocked2?/",
|
||||
"signatures": []
|
||||
},
|
||||
"paloalto": {
|
||||
"company": "Palo Alto Networks",
|
||||
"name": "Palo Alto",
|
||||
@@ -749,8 +761,8 @@
|
||||
},
|
||||
"tencent": {
|
||||
"company": "Tencent Cloud Computing",
|
||||
"name": "Tencent Cloud",
|
||||
"regex": "waf\\.tencent-cloud\\.com",
|
||||
"name": "Tencent Cloud|Waterproof Wall",
|
||||
"regex": "waf\\.tencent-cloud\\.com|window.location.href=.https://waf.tencent.com/501page.html",
|
||||
"signatures": [
|
||||
"3f82:RVZXum60OEhCWapBYKcPk4JzWOpohM4IiUYMr2RXg1uQJbX3uhdOnthtOj+hX7AB16FcPxJPdLsXo2tKaK99nui7c4RmkgI2FZjxtDtAeq+c36A5chW1XaTD"
|
||||
]
|
||||
|
||||
Vendored
+6
-6
@@ -165,11 +165,11 @@ class ConnectionManager:
|
||||
|
||||
def get_ready_conn(self, host):
|
||||
conn = None
|
||||
self._lock.acquire()
|
||||
try:
|
||||
self._lock.acquire()
|
||||
if host in self._hostmap:
|
||||
for c in self._hostmap[host]:
|
||||
if self._readymap[c]:
|
||||
if self._readymap.get(c):
|
||||
self._readymap[c] = 0
|
||||
conn = c
|
||||
break
|
||||
@@ -517,7 +517,7 @@ def error_handler(url):
|
||||
keepalive_handler.close_all()
|
||||
|
||||
def continuity(url):
|
||||
import md5
|
||||
from hashlib import md5
|
||||
format = '%25s: %s'
|
||||
|
||||
# first fetch the file with the normal http handler
|
||||
@@ -526,7 +526,7 @@ def continuity(url):
|
||||
fo = _urllib.request.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
m = md5(foo)
|
||||
print(format % ('normal urllib', m.hexdigest()))
|
||||
|
||||
# now install the keepalive handler and try again
|
||||
@@ -536,7 +536,7 @@ def continuity(url):
|
||||
fo = _urllib.request.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
m = md5(foo)
|
||||
print(format % ('keepalive read', m.hexdigest()))
|
||||
|
||||
fo = _urllib.request.urlopen(url)
|
||||
@@ -546,7 +546,7 @@ def continuity(url):
|
||||
if f: foo = foo + f
|
||||
else: break
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
m = md5(foo)
|
||||
print(format % ('keepalive readline', m.hexdigest()))
|
||||
|
||||
def comp(N, url):
|
||||
|
||||
Vendored
+1
-2
@@ -117,7 +117,6 @@ try:
|
||||
pass
|
||||
|
||||
if not libmagic or not libmagic._name:
|
||||
import sys
|
||||
platform_to_lib = {'darwin': ['/opt/local/lib/libmagic.dylib',
|
||||
'/usr/local/lib/libmagic.dylib',
|
||||
'/usr/local/Cellar/libmagic/5.10/lib/libmagic.dylib'],
|
||||
@@ -223,4 +222,4 @@ MAGIC_NO_CHECK_ASCII = 0x020000 # Don't check for ascii files
|
||||
MAGIC_NO_CHECK_TROFF = 0x040000 # Don't check ascii/troff
|
||||
MAGIC_NO_CHECK_FORTRAN = 0x080000 # Don't check ascii/fortran
|
||||
MAGIC_NO_CHECK_TOKENS = 0x100000 # Don't check ascii/tokens
|
||||
MAGIC_UNKNOWN_FILETYPE = b"unknown"
|
||||
MAGIC_UNKNOWN_FILETYPE = b"unknown"
|
||||
|
||||
-1
@@ -29,7 +29,6 @@ import sys
|
||||
|
||||
from lib.core.compat import choose_boundary
|
||||
from lib.core.convert import getBytes
|
||||
from lib.core.convert import getText
|
||||
from lib.core.exception import SqlmapDataException
|
||||
from thirdparty.six.moves import urllib as _urllib
|
||||
|
||||
|
||||
Vendored
+11
-1
@@ -29,7 +29,7 @@ import sys
|
||||
import types
|
||||
|
||||
__author__ = "Benjamin Peterson <[email protected]>"
|
||||
__version__ = "1.15.0"
|
||||
__version__ = "1.16.0"
|
||||
|
||||
|
||||
# Useful for very coarse version differentiation.
|
||||
@@ -71,6 +71,11 @@ else:
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
|
||||
if PY34:
|
||||
from importlib.util import spec_from_loader
|
||||
else:
|
||||
spec_from_loader = None
|
||||
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
@@ -186,6 +191,11 @@ class _SixMetaPathImporter(object):
|
||||
return self
|
||||
return None
|
||||
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
if fullname in self.known_modules:
|
||||
return spec_from_loader(fullname, self)
|
||||
return None
|
||||
|
||||
def __get_module(self, fullname):
|
||||
try:
|
||||
return self.known_modules[fullname]
|
||||
|
||||
Reference in New Issue
Block a user