Compare commits

...

91 Commits
1.5.2 ... 1.5.7

Author SHA1 Message Date
Miroslav Stampar
69c679cf06 Fixes #4728 2021-07-04 23:07:55 +02:00
Miroslav Stampar
5ea08b397a Fixes #4710 2021-06-24 21:03:22 +02:00
Miroslav Stampar
7c41967865 Fixes #4719 2021-06-21 17:17:41 +02:00
Miroslav Stampar
255dce8c49 Fixes #4712 2021-06-15 21:04:51 +02:00
Miroslav Stampar
7c7c338705 Fixes #4705 2021-06-11 09:48:00 +02:00
Miroslav Stampar
63073a1873 15% speedup in some cases (avoiding heuristic char detection) 2021-06-08 21:48:43 +02:00
Miroslav Stampar
295cd15dff Version bump related to the merged pulls 2021-06-08 14:05:05 +02:00
Stefan Pejcic
3463341bad link to rs translation (#4692) 2021-06-08 14:04:03 +02:00
Stefan Pejcic
88553d3540 rs translation (#4691) 2021-06-08 14:03:52 +02:00
Pham Sy Minh
ab90447600 Update README-vi-VN.md (#4701) 2021-06-08 14:02:38 +02:00
Miroslav Stampar
a23faaeb8c Patch related to #4693 2021-05-31 00:34:14 +02:00
Miroslav Stampar
6942abf090 Minor update 2021-05-27 12:29:40 +02:00
Miroslav Stampar
3c25f79a9b Fixes #4671 2021-05-25 14:40:15 +02:00
Miroslav Stampar
94ab17829e Fixes #4688 2021-05-25 09:01:41 +02:00
Miroslav Stampar
c4c1571902 Making sqlmap compatible with PyPy/PyPy3 2021-05-24 13:49:35 +02:00
Miroslav Stampar
da86486cd9 Couple of minor patches 2021-05-24 13:12:18 +02:00
Miroslav Stampar
dccc837703 Minor update 2021-05-19 18:32:03 +02:00
Miroslav Stampar
452915ed4a Minor update 2021-05-19 18:20:39 +02:00
Miroslav Stampar
35e575c287 Minor update 2021-05-17 10:43:58 +02:00
Miroslav Stampar
015a8f0a6d Fixes #4678 2021-05-17 10:40:27 +02:00
Miroslav Stampar
0896a49500 Minor update 2021-05-12 13:14:13 +02:00
Miroslav Stampar
95511c8ff9 Fixes #4659 2021-05-01 13:25:00 +02:00
Miroslav Stampar
8bf1650d65 Fixes #4664 2021-05-01 11:40:42 +02:00
Sutrisno Efendi
ff645a767b Update README-id-ID.md (#4663) 2021-05-01 11:33:14 +02:00
Miroslav Stampar
cfa7b3c3bd Implements #4656 2021-04-28 18:06:15 +02:00
Miroslav Stampar
76b310cc43 Fixes #4650 2021-04-25 20:36:19 +02:00
Miroslav Stampar
9a6acd2054 Fixes #4637 2021-04-13 17:55:54 +02:00
Miroslav Stampar
387020ece8 Better yet for #4633 2021-04-09 11:43:01 +02:00
Miroslav Stampar
732b9670d2 Minor fix related to last commit 2021-04-05 19:00:35 +02:00
Miroslav Stampar
1159c9ccae Fixes #4629 2021-04-05 18:38:47 +02:00
Miroslav Stampar
cadbf170f0 Fixes #4630 2021-04-05 18:21:09 +02:00
Miroslav Stampar
fc486c8b34 Minor update 2021-04-02 13:55:37 +02:00
Miroslav Stampar
cfe43e3f2b Patch for #4626 2021-04-02 12:56:31 +02:00
Miroslav Stampar
6395481aa4 Fixes #4625 2021-04-02 12:47:03 +02:00
Miroslav Stampar
2380ab1e86 Dummy patch for #4623 2021-03-31 10:42:40 +02:00
Miroslav Stampar
dd32bfb0cc Minor patch for #4613 2021-03-28 21:41:45 +02:00
Daniel Igarashi
b7d90bbe03 Correct a typo (#4619) 2021-03-28 20:01:21 +02:00
Miroslav Stampar
86170e177c Dirty patch for #4618 2021-03-28 19:58:06 +02:00
Miroslav Stampar
bce3abc829 Fixes #4612 2021-03-25 17:29:14 +01:00
Miroslav Stampar
8d6125f067 Minor patch 2021-03-22 12:00:32 +01:00
Miroslav Stampar
506e3f0871 Fixes #4611 2021-03-22 11:03:57 +01:00
Miroslav Stampar
6145944dc7 Fixes #4609 2021-03-18 11:40:39 +01:00
Miroslav Stampar
61186b979b Update THANKS.md 2021-03-16 10:11:23 +01:00
Miroslav Stampar
4d4b9a1175 Potential (hide the cause) patch for #4367 2021-03-15 23:02:31 +01:00
Miroslav Stampar
133e2c8c61 Trivial update 2021-03-11 21:31:28 +01:00
Miroslav Stampar
38c341076d Update regarding #4142 (--auth-type bearer) 2021-03-11 20:41:05 +01:00
Miroslav Stampar
40e4422bbd Trivial cosmetics (breaking help into two lines) 2021-03-11 20:14:36 +01:00
Bernardo Damele A. G
98ac1cf9c1 Update FUNDING.yml 2021-03-11 18:11:28 +00:00
Bernardo Damele A. G
56721240fa Update FUNDING.yml 2021-03-11 17:22:58 +00:00
Bernardo Damele A. G
c81414cf25 Update FUNDING.yml 2021-03-11 15:41:21 +00:00
Bernardo Damele A. G
2e195a35dc Create FUNDING.yml 2021-03-11 15:38:12 +00:00
Miroslav Stampar
89d25a16ce Trivial patches 2021-03-11 11:11:29 +01:00
Miroslav Stampar
9bc466edac Removing deprecated piece of code 2021-03-11 11:02:23 +01:00
Miroslav Stampar
32b7f3040e Trivial consistency update 2021-03-11 11:00:38 +01:00
Miroslav Stampar
f066e215e5 Minor patch 2021-03-11 10:55:09 +01:00
Miroslav Stampar
4e65ff4689 Proper patch for #4591 2021-03-08 15:40:05 +01:00
Miroslav Stampar
1e8bf1c78a Trivial update for #4595 2021-03-07 21:22:17 +01:00
Miroslav Stampar
657c6519ea Graceful fail for --gui (#4601) 2021-03-07 21:15:59 +01:00
Miroslav Stampar
970c7f6a76 Fixes #4599 2021-03-07 20:35:51 +01:00
Miroslav Stampar
105e314ec8 Fixes #4596 2021-03-07 20:31:11 +01:00
Miroslav Stampar
dd963a042d Fixes #4591 2021-03-04 08:26:23 +01:00
Miroslav Stampar
0df2592622 Trivial speedup 2021-03-03 23:28:27 +01:00
Miroslav Stampar
eeacab0f19 Speedup of caching for char encoding (non-Unicode chars in page) 2021-03-03 23:08:00 +01:00
Miroslav Stampar
b3e454d0b1 Trivial update 2021-02-25 12:19:08 +01:00
Miroslav Stampar
99d0031d65 Minor update 2021-02-25 11:39:08 +01:00
Miroslav Stampar
5916bc2d39 Minor update 2021-02-25 11:22:10 +01:00
Miroslav Stampar
2159944de4 Minor update 2021-02-23 12:00:59 +01:00
Miroslav Stampar
f87aa83e9b Dirty implementation for #4571 2021-02-21 22:49:57 +01:00
Miroslav Stampar
b902cca791 Minor update 2021-02-19 11:38:02 +01:00
Miroslav Stampar
86467e196b Periodical recloak 2021-02-19 11:08:14 +01:00
Miroslav Stampar
30f137699d Trivial bug patch 2021-02-19 11:07:13 +01:00
Miroslav Stampar
7741154383 Fixes #4580 2021-02-16 14:27:02 +01:00
Miroslav Stampar
a6262a3aa9 Adding support for Virtuoso DBMS 2021-02-15 14:07:36 +01:00
Miroslav Stampar
1f33b16e01 Fixes #4579 2021-02-14 14:47:28 +01:00
Miroslav Stampar
04396c97e2 Minor refactoring 2021-02-11 13:00:54 +01:00
Miroslav Stampar
b1cdbdae61 Minor update of tests 2021-02-11 12:30:21 +01:00
Miroslav Stampar
747951b80b Another patch for #4576 2021-02-10 14:09:13 +01:00
Miroslav Stampar
1bef2f8fda Fixes #4576 2021-02-10 14:02:42 +01:00
Miroslav Stampar
b0ac442096 Minor patch of links 2021-02-08 22:42:08 +01:00
Miroslav Stampar
99a5fb243c Trivial update 2021-02-08 21:50:20 +01:00
Miroslav Stampar
b2a575482e Proxies dislike non-browser user-agents 2021-02-08 21:47:36 +01:00
Miroslav Stampar
365e08b710 Allowing empty database names in -d 2021-02-08 20:47:37 +01:00
Miroslav Stampar
af3b79ff8b Trivial update of doctests 2021-02-08 12:28:24 +01:00
hugoduar
3724a53466 Add spanish common names (#4573) 2021-02-08 11:30:39 +01:00
Miroslav Stampar
01e83cb4a0 Minor patch for ws 2021-02-08 11:18:27 +01:00
Miroslav Stampar
cd77cdd1e8 It seems that JSON_GROUP_ARRAY is not available in all Travis CI deployments 2021-02-05 15:15:58 +01:00
Miroslav Stampar
22c421a427 Debugging the testing case 2021-02-05 14:46:23 +01:00
Miroslav Stampar
59fe89f076 Minor update of testing cases 2021-02-05 12:44:39 +01:00
Miroslav Stampar
160011bd87 Couple of bug fixes 2021-02-03 11:52:50 +01:00
Miroslav Stampar
36ee4d68c7 Trivial update 2021-02-01 22:19:20 +01:00
Miroslav Stampar
dfc5bc5d87 Minor update of testing cases 2021-02-01 21:58:36 +01:00
123 changed files with 866 additions and 363 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
custom: 'https://www.paypal.com/donate?hosted_button_id=A34GMDLKA2V7G'

View File

@@ -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 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 Screenshots
---- ----
@@ -68,6 +66,7 @@ Translations
* [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md) * [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md)
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md) * [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) * [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) * [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md) * [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
* [Ukrainian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-uk-UA.md) * [Ukrainian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-uk-UA.md)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -485,6 +485,8 @@ llave
chaveta chaveta
tono tono
cuna cuna
correo
contrasenia
# german # german

View File

@@ -3223,6 +3223,10 @@ nuke_gallery_pictures_newpicture
Books Books
grupo grupo
facturas facturas
aclaraciones
preguntas
personas
estadisticas
# site:cn # site:cn

View File

@@ -223,4 +223,12 @@
<error regexp="-10048: Syntax error"/> <error regexp="-10048: Syntax error"/>
<error regexp="rdmStmtPrepare\(.+?\) returned"/> <error regexp="rdmStmtPrepare\(.+?\) returned"/>
</dbms> </dbms>
<dbms value="Virtuoso">
<error regexp="SQ074: Line \d+:"/>
<error regexp="SR185: Undefined procedure"/>
<error regexp="SQ200: No table "/>
<error regexp="Virtuoso S0002 Error"/>
<error regexp="\[(Virtuoso Driver|Virtuoso iODBC Driver)\]\[Virtuoso Server\]"/>
</dbms>
</root> </root>

View File

@@ -1665,4 +1665,55 @@
<search_table/> <search_table/>
<search_column/> <search_column/>
</dbms> </dbms>
<dbms value="Virtuoso">
<cast query="CAST(%s AS NCHAR)"/>
<length query="LENGTH(%s)"/>
<isnull query="__MAX_NOTNULL(%s,' ')"/>
<delimiter query="||"/>
<limit query="TOP (%d,%d)"/>
<limitregexp query="\s+TOP\s*\(([\d]+)\s*\,\s*([\d]+)\)" query2="\s+TOP\s+([\d]+)"/>
<limitgroupstart query="1"/>
<limitgroupstop query="2"/>
<limitstring query=" TOP "/>
<order query="ORDER BY %s ASC"/>
<count query="COUNT(%s)"/>
<comment query="-- -" query2="/*"/>
<concatenate query="%s||%s"/>
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
<banner query="sys_stat('st_dbms_name')||' - '||sys_stat('st_dbms_ver')"/>
<current_user query="USERNAME()"/>
<current_db query="UPPER(USERNAME())"/>
<hostname query="sys_stat('st_host_name')"/>
<table_comment/>
<column_comment/>
<is_dba query="USERNAME()='dba'"/>
<dbs>
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA"/>
<blind query="SELECT DISTINCT TOP (%d,1) schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY 1" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA"/>
</dbs>
<tables>
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES" condition="table_schema"/>
<blind query="SELECT TOP (%d,1) table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY 1" count="SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'"/>
</tables>
<columns>
<inband query="SELECT column_name,data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
<blind query="SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
<blind query="SELECT TOP (%d,1) %s FROM %s.%s ORDER BY %s" count="SELECT COUNT(*) FROM %s.%s"/>
</dump_table>
<users>
<inband query="SELECT u_name FROM SYS_USERS WHERE U_IS_ROLE=0 ORDER BY 1"/>
<blind query="SELECT TOP (%d,1) u_name FROM SYS_USERS WHERE U_IS_ROLE=0 ORDER BY 1" count="SELECT COUNT(DISTINCT(u_name)) FROM SYS_USERS"/>
</users>
<privileges/>
<roles/>
<statements/>
<search_db/>
<search_table/>
<search_column/>
</dbms>
</root> </root>

View File

@@ -734,6 +734,9 @@ rmillet, <rmillet42(at)gmail.com>
Rub3nCT, <rub3nct(at)gmail.com> Rub3nCT, <rub3nct(at)gmail.com>
* for reporting a minor bug * for reporting a minor bug
sapra, <amanistaken(at)gmail.com>
* for helping out with Python multiprocessing library on MacOS
shiftzwei, <shiftzwei(at)gmail.com> shiftzwei, <shiftzwei(at)gmail.com>
* for reporting a couple of bugs * for reporting a couple of bugs

View File

@@ -2,7 +2,7 @@
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur 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 Tangkapan Layar
---- ----
@@ -14,8 +14,7 @@ Anda dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapprojec
Instalasi Instalasi
---- ----
Anda dapat mengunduh tarball versi terbaru [di sini] 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).
(https://github.com/sqlmapproject/sqlmap/tarball/master) atau zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master).
Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_ repositori [Git](https://github.com/sqlmapproject/sqlmap): Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_ repositori [Git](https://github.com/sqlmapproject/sqlmap):

View File

@@ -0,0 +1,50 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap je alat otvorenog koda namenjen za penetraciono testiranje koji automatizuje proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije i preuzimanje baza podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko uzimanja podataka iz baze, do pristupa zahvaćenom fajl sistemu i izvršavanja komandi na operativnom sistemu korištenjem tzv. "out-of-band" veza.
Slike
----
![Slika](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Možete posetiti [kolekciju slika](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) gde su demonstrirane neke od e se demonstriraju neke od funkcija na wiki stranicama.
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

View File

@@ -3,15 +3,14 @@
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL và tiếp quản các máy chủ cơ sở dữ liệu. Nó đi kèm với sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL 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ữ 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.
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.
Ảnh chụp màn hình Ảnh chụp màn hình
---- ----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png) ![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng trình bày một số tính năng 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 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). 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 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****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****3.x** trên bất kì hệ điều hành nào.
Sử dụng Sử dụng
---- ----
@@ -36,7 +35,7 @@ Sử dụng
python sqlmap.py -hh 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). Để có cái nhìn tổng quan về các khả năng của sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (Tiếng Anh).
Liên kết Liên kết
@@ -44,7 +43,7 @@ Liên kết
* Trang chủ: http://sqlmap.org * 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) * 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 * Theo dõi vấn đề: https://github.com/sqlmapproject/sqlmap/issues
* Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki * Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki
* Các câu hỏi thường gặp (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ * Các câu hỏi thường gặp (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ

View File

@@ -2,7 +2,7 @@
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap) [![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
sqlmap 是一个开源的渗透测试工具可以用来自动化的检测利用SQL注入漏洞获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带数据连接的方式执行操作系统命令。 sqlmap 是一个开源的渗透测试工具可以用来自动化的检测利用SQL注入漏洞获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带数据连接的方式执行操作系统命令。
演示截图 演示截图
---- ----

View File

@@ -21,7 +21,7 @@ if sys.version_info >= (3, 0):
xrange = range xrange = range
ord = lambda _: _ ord = lambda _: _
KEY = b"cwRAopWDYixMeqs3" KEY = b"ENWsCymUeJcXqSbD"
def xor(message, key): def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message))) return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))

Binary file not shown.

Binary file not shown.

View File

@@ -129,7 +129,6 @@ class ReqHandler(BaseHTTPRequestHandler):
self.url, self.params = path, params self.url, self.params = path, params
if self.url == '/': if self.url == '/':
if not any(_ in self.params for _ in ("id", "query")): if not any(_ in self.params for _ in ("id", "query")):
self.send_response(OK) self.send_response(OK)
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING) self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
@@ -140,10 +139,12 @@ class ReqHandler(BaseHTTPRequestHandler):
code, output = OK, "" code, output = OK, ""
try: try:
if self.params.get("echo", ""): if self.params.get("echo", ""):
output += "%s<br>" % self.params["echo"] output += "%s<br>" % self.params["echo"]
if self.params.get("reflect", ""):
output += "%s<br>" % self.params.get("id")
with _lock: with _lock:
if "query" in self.params: if "query" in self.params:
_cursor.execute(self.params["query"]) _cursor.execute(self.params["query"])
@@ -156,18 +157,22 @@ class ReqHandler(BaseHTTPRequestHandler):
output += "<b>SQL results:</b><br>\n" output += "<b>SQL results:</b><br>\n"
if results: if self.params.get("code", ""):
output += "<table border=\"1\">\n" if not results:
code = INTERNAL_SERVER_ERROR
for row in results:
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
else: else:
output += "no results found" if results:
output += "<table border=\"1\">\n"
for row in results:
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
else:
output += "no results found"
output += "</body></html>" output += "</body></html>"
except Exception as ex: except Exception as ex:
@@ -194,7 +199,7 @@ class ReqHandler(BaseHTTPRequestHandler):
self.do_REQUEST() self.do_REQUEST()
def do_PUT(self): def do_PUT(self):
self.do_REQUEST() self.do_POST()
def do_HEAD(self): def do_HEAD(self):
self.do_REQUEST() self.do_REQUEST()

View File

@@ -404,8 +404,8 @@ def checkSqlInjection(place, parameter, value):
continue continue
# Parse boundary's <prefix>, <suffix> and <ptype> # Parse boundary's <prefix>, <suffix> and <ptype>
prefix = boundary.prefix if boundary.prefix else "" prefix = boundary.prefix or ""
suffix = boundary.suffix if boundary.suffix else "" suffix = boundary.suffix or ""
ptype = boundary.ptype ptype = boundary.ptype
# Options --prefix/--suffix have a higher priority (if set by user) # Options --prefix/--suffix have a higher priority (if set by user)
@@ -529,7 +529,7 @@ def checkSqlInjection(place, parameter, value):
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
trueRawResponse = "%s%s" % (trueHeaders, truePage) trueRawResponse = "%s%s" % (trueHeaders, truePage)
if trueResult and not(truePage == falsePage and not kb.nullConnection): if trueResult and not(truePage == falsePage and not any((kb.nullConnection, conf.code))):
# Perform the test's False request # Perform the test's False request
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False) falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
@@ -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) output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output: if output:
result = output == "1" result = output == '1'
if result: if result:
infoMsg = "%sparameter '%s' is '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title) infoMsg = "%sparameter '%s' is '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title)
@@ -991,7 +991,7 @@ def checkSuhosinPatch(injection):
Checks for existence of Suhosin-patch (and alike) protection mechanism(s) 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 = "checking for parameter length "
debugMsg += "constraining mechanisms" debugMsg += "constraining mechanisms"
logger.debug(debugMsg) logger.debug(debugMsg)

View File

@@ -37,6 +37,7 @@ from lib.core.settings import RAIMA_ALIASES
from lib.core.settings import SQLITE_ALIASES from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES from lib.core.settings import VERTICA_ALIASES
from lib.core.settings import VIRTUOSO_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy from lib.utils.sqlalchemy import SQLAlchemy
from plugins.dbms.access.connector import Connector as AccessConn from plugins.dbms.access.connector import Connector as AccessConn
@@ -91,6 +92,8 @@ from plugins.dbms.sybase.connector import Connector as SybaseConn
from plugins.dbms.sybase import SybaseMap from plugins.dbms.sybase import SybaseMap
from plugins.dbms.vertica.connector import Connector as VerticaConn from plugins.dbms.vertica.connector import Connector as VerticaConn
from plugins.dbms.vertica import VerticaMap from plugins.dbms.vertica import VerticaMap
from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn
from plugins.dbms.virtuoso import VirtuosoMap
def setHandler(): def setHandler():
""" """
@@ -125,6 +128,7 @@ def setHandler():
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn), (DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
(DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn), (DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn),
(DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn),
] ]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items) _ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)

View File

@@ -488,7 +488,7 @@ class Agent(object):
if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')): if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')):
nulledCastedField = rootQuery.cast.query % field nulledCastedField = rootQuery.cast.query % field
if re.search("COUNT\(", field) and Backend.getIdentifiedDbms() in (DBMS.RAIMA,): if re.search(r"COUNT\(", field) and Backend.getIdentifiedDbms() in (DBMS.RAIMA,):
pass pass
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI): elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField) nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField)
@@ -699,7 +699,7 @@ class Agent(object):
elif fieldsNoSelect: elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop) concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
if fieldsExists: if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -1021,7 +1021,7 @@ class Agent(object):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
limitedQuery += " %s" % limitStr limitedQuery += " %s" % limitStr
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE,): elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE, DBMS.VIRTUOSO):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1) limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
if query.startswith("SELECT "): if query.startswith("SELECT "):
limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1) limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1)

View File

@@ -22,7 +22,10 @@ from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE from lib.core.settings import BIGARRAY_CHUNK_SIZE
from lib.core.settings import BIGARRAY_COMPRESS_LEVEL 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): def _size_of(instance):
""" """
@@ -56,6 +59,12 @@ class BigArray(list):
>>> _[20] = 0 >>> _[20] = 0
>>> _[99999] >>> _[99999]
99999 99999
>>> _ += [0]
>>> _[100000]
0
>>> _ = _ + [1]
>>> _[-1]
1
""" """
def __init__(self, items=None): def __init__(self, items=None):
@@ -69,6 +78,20 @@ class BigArray(list):
for item in (items or []): for item in (items or []):
self.append(item) 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): def append(self, value):
self.chunks[-1].append(value) self.chunks[-1].append(value)
@@ -145,7 +168,7 @@ class BigArray(list):
self.chunks, self.filenames = state self.chunks, self.filenames = state
def __getitem__(self, y): def __getitem__(self, y):
if y < 0: while y < 0:
y += len(self) y += len(self)
index = y // self.chunk_length index = y // self.chunk_length

View File

@@ -1531,7 +1531,7 @@ def parseTargetDirect():
remote = False remote = False
for dbms in SUPPORTED_DBMS: for dbms in SUPPORTED_DBMS:
details = re.search(r"^(?P<dbms>%s)://(?P<credentials>(?P<user>.*?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>[\w.-]+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\]+?)$" % dbms, conf.direct, re.I) details = re.search(r"^(?P<dbms>%s)://(?P<credentials>(?P<user>.*?)\:(?P<pass>.*)\@)?(?P<remote>(?P<hostname>[\w.-]+?)\:(?P<port>[\d]+)\/)?(?P<db>[\w\d\ \:\.\_\-\/\\]*)$" % dbms, conf.direct, re.I)
if details: if details:
conf.dbms = details.group("dbms") conf.dbms = details.group("dbms")
@@ -2270,6 +2270,7 @@ def isMultiThreadMode():
""" """
Checks if running in multi-thread(ing) mode Checks if running in multi-thread(ing) mode
>>> import time
>>> isMultiThreadMode() >>> isMultiThreadMode()
False False
>>> _ = lambda: time.sleep(0.1) >>> _ = lambda: time.sleep(0.1)
@@ -2707,7 +2708,14 @@ def popValue():
'foobar' 'foobar'
""" """
return getCurrentThreadData().valueStack.pop() retVal = None
try:
retVal = getCurrentThreadData().valueStack.pop()
except IndexError:
pass
return retVal
def wasLastResponseDBMSError(): def wasLastResponseDBMSError():
""" """
@@ -2882,33 +2890,31 @@ def urldecode(value, encoding=None, unsafe="%%?&=;+%s" % CUSTOM_INJECTION_MARK_C
True True
>>> urldecode('AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#' >>> urldecode('AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#'
True True
>>> urldecode(b'AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#'
True
""" """
result = value result = value
if value: if value:
try: value = getUnicode(value)
# for cases like T%C3%BCrk%C3%A7e
value = str(value)
except ValueError:
pass
finally:
if convall:
result = _urllib.parse.unquote_plus(value) if spaceplus else _urllib.parse.unquote(value)
else:
result = value
charset = set(string.printable) - set(unsafe)
def _(match): if convall:
char = decodeHex(match.group(1), binary=False) result = _urllib.parse.unquote_plus(value) if spaceplus else _urllib.parse.unquote(value)
return char if char in charset else match.group(0) else:
result = value
charset = set(string.printable) - set(unsafe)
if spaceplus: def _(match):
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of _urllib.parse.unquote_plus in convall case) char = decodeHex(match.group(1), binary=False)
return char if char in charset else match.group(0)
result = re.sub(r"%([0-9a-fA-F]{2})", _, result) if spaceplus:
result = result.replace('+', ' ') # plus sign has a special meaning in URL encoded data (hence the usage of _urllib.parse.unquote_plus in convall case)
result = getUnicode(result, encoding or UNICODE_ENCODING) result = re.sub(r"%([0-9a-fA-F]{2})", _, result)
result = getUnicode(result, encoding or UNICODE_ENCODING)
return result return result
@@ -3026,6 +3032,8 @@ def getPublicTypeMembers(type_, onlyValues=False):
>>> [_ for _ in getPublicTypeMembers(OS, True)] >>> [_ for _ in getPublicTypeMembers(OS, True)]
['Linux', 'Windows'] ['Linux', 'Windows']
>>> [_ for _ in getPublicTypeMembers(PAYLOAD.TECHNIQUE, True)]
[1, 2, 3, 4, 5, 6]
""" """
retVal = [] retVal = []
@@ -4200,7 +4208,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users) if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
retVal = "`%s`" % retVal retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
retVal = "\"%s\"" % retVal retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper() retVal = "\"%s\"" % retVal.upper()
@@ -4238,7 +4246,7 @@ def unsafeSQLIdentificatorNaming(name):
if isinstance(name, six.string_types): if isinstance(name, six.string_types):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
retVal = name.replace("`", "") retVal = name.replace("`", "")
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA): elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
retVal = name.replace("\"", "") retVal = name.replace("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL): elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = name.replace("\"", "").upper() retVal = name.replace("\"", "").upper()
@@ -5249,8 +5257,9 @@ def parseRequestFile(reqFile, checkParams=True):
if "HTTP/" not in request: if "HTTP/" not in request:
continue 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):
continue if not re.search(r"^[\n]*%s[^\n]*\*[^\n]*\sHTTP\/" % HTTPMETHOD.GET, request, re.I | re.M):
continue
getPostReq = False getPostReq = False
url = None url = None

View File

@@ -25,6 +25,8 @@ def cachedmethod(f):
>>> __ = cachedmethod(lambda _: _) >>> __ = cachedmethod(lambda _: _)
>>> __(1) >>> __(1)
1 1
>>> __(1)
1
>>> __ = cachedmethod(lambda *args, **kwargs: args[0]) >>> __ = cachedmethod(lambda *args, **kwargs: args[0])
>>> __(2) >>> __(2)
2 2

View File

@@ -37,6 +37,7 @@ from lib.core.settings import RAIMA_ALIASES
from lib.core.settings import SQLITE_ALIASES from lib.core.settings import SQLITE_ALIASES
from lib.core.settings import SYBASE_ALIASES from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES from lib.core.settings import VERTICA_ALIASES
from lib.core.settings import VIRTUOSO_ALIASES
FIREBIRD_TYPES = { FIREBIRD_TYPES = {
261: "BLOB", 261: "BLOB",
@@ -222,9 +223,9 @@ DUMP_REPLACEMENTS = {" ": NULL, "": BLANK}
DBMS_DICT = { DBMS_DICT = {
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"), DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"),
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"), DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"),
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"), DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"), DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/2/library/sqlite3.html", "sqlite"), DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/3/library/sqlite3.html", "sqlite"),
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"), DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"), DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"), DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
@@ -246,6 +247,7 @@ DBMS_DICT = {
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None), DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None), DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
DBMS.RAIMA: (RAIMA_ALIASES, None, None, None), DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
DBMS.VIRTUOSO: (VIRTUOSO_ALIASES, None, None, None),
} }
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/ # Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@@ -283,6 +285,7 @@ HEURISTIC_NULL_EVAL = {
DBMS.CACHE: "%SQLUPPER NULL", DBMS.CACHE: "%SQLUPPER NULL",
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))", DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))", DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
DBMS.VIRTUOSO: "__MAX_NOTNULL(NULL)",
} }
SQL_STATEMENTS = { SQL_STATEMENTS = {
@@ -363,13 +366,14 @@ OBSOLETE_OPTIONS = {
"--ignore-401": "use '--ignore-code' instead", "--ignore-401": "use '--ignore-code' instead",
"--second-order": "use '--second-url' instead", "--second-order": "use '--second-url' instead",
"--purge-output": "use '--purge' instead", "--purge-output": "use '--purge' instead",
"--sqlmap-shell": "use '--shell' instead",
"--check-payload": None, "--check-payload": None,
"--check-waf": None, "--check-waf": None,
"--pickled-options": "use '--api -c ...' instead", "--pickled-options": "use '--api -c ...' instead",
"--identify-waf": "functionality being done automatically",
} }
DEPRECATED_OPTIONS = { DEPRECATED_OPTIONS = {
"--identify-waf": "functionality being done automatically",
} }
DUMP_DATA_PREPROCESS = { DUMP_DATA_PREPROCESS = {
@@ -379,7 +383,7 @@ DUMP_DATA_PREPROCESS = {
DEFAULT_DOC_ROOTS = { DEFAULT_DOC_ROOTS = {
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"), OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
} }
PART_RUN_CONTENT_TYPES = { PART_RUN_CONTENT_TYPES = {

View File

@@ -16,14 +16,17 @@ from lib.core.common import Backend
from lib.core.common import checkFile from lib.core.common import checkFile
from lib.core.common import dataToDumpFile from lib.core.common import dataToDumpFile
from lib.core.common import dataToStdout from lib.core.common import dataToStdout
from lib.core.common import filterNone
from lib.core.common import getSafeExString from lib.core.common import getSafeExString
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isMultiThreadMode from lib.core.common import isMultiThreadMode
from lib.core.common import isNoneValue
from lib.core.common import normalizeUnicode from lib.core.common import normalizeUnicode
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import prioritySortColumns from lib.core.common import prioritySortColumns
from lib.core.common import randomInt from lib.core.common import randomInt
from lib.core.common import safeCSValue from lib.core.common import safeCSValue
from lib.core.common import unArrayizeValue
from lib.core.common import unsafeSQLIdentificatorNaming from lib.core.common import unsafeSQLIdentificatorNaming
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.convert import getBytes from lib.core.convert import getBytes
@@ -114,6 +117,9 @@ class Dump(object):
if conf.api: if conf.api:
self._write(data, content_type=content_type) self._write(data, content_type=content_type)
if isListLike(data) and len(data) == 1:
data = unArrayizeValue(data)
if isListLike(data): if isListLike(data):
self.lister(header, data, content_type, sort) self.lister(header, data, content_type, sort)
elif data is not None: elif data is not None:
@@ -166,7 +172,7 @@ class Dump(object):
def currentDb(self, data): def currentDb(self, data):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE): if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB): elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB, DBMS.VIRTUOSO):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else: else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB) self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -200,9 +206,9 @@ class Dump(object):
self._write("%s:" % header) self._write("%s:" % header)
for user in users: for user in users:
settings = userSettings[user] settings = filterNone(userSettings[user])
if settings is None: if isNoneValue(settings):
stringSettings = "" stringSettings = ""
else: else:
stringSettings = " [%d]:" % len(settings) stringSettings = " [%d]:" % len(settings)
@@ -609,7 +615,7 @@ class Dump(object):
_ = safechardecode(value, True) _ = safechardecode(value, True)
f.write(_) f.write(_)
except magic.MagicException as ex: except Exception as ex:
logger.debug(getSafeExString(ex)) logger.debug(getSafeExString(ex))
if conf.dumpFormat == DUMP_FORMAT.CSV: if conf.dumpFormat == DUMP_FORMAT.CSV:

View File

@@ -58,6 +58,7 @@ class DBMS(object):
EXTREMEDB = "eXtremeDB" EXTREMEDB = "eXtremeDB"
FRONTBASE = "FrontBase" FRONTBASE = "FrontBase"
RAIMA = "Raima Database Manager" RAIMA = "Raima Database Manager"
VIRTUOSO = "Virtuoso"
class DBMS_DIRECTORY_NAME(object): class DBMS_DIRECTORY_NAME(object):
ACCESS = "access" ACCESS = "access"
@@ -86,6 +87,7 @@ class DBMS_DIRECTORY_NAME(object):
EXTREMEDB = "extremedb" EXTREMEDB = "extremedb"
FRONTBASE = "frontbase" FRONTBASE = "frontbase"
RAIMA = "raima" RAIMA = "raima"
VIRTUOSO = "virtuoso"
class FORK(object): class FORK(object):
MARIADB = "MariaDB" MARIADB = "MariaDB"
@@ -199,16 +201,16 @@ class HASH(object):
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html # Reference: http://www.zytrax.com/tech/web/mobile_ids.html
class MOBILES(object): class MOBILES(object):
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+") BLACKBERRY = ("BlackBerry Z10", "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)") HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36") HTC = ("HTC 10", "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") 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") 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") 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") 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") 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 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") XIAOMI = ("Xiaomi Mi 8 Pro", "Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36")
class PROXY_TYPE(object): class PROXY_TYPE(object):
HTTP = "HTTP" HTTP = "HTTP"
@@ -400,6 +402,7 @@ class CONTENT_STATUS(object):
class AUTH_TYPE(object): class AUTH_TYPE(object):
BASIC = "basic" BASIC = "basic"
DIGEST = "digest" DIGEST = "digest"
BEARER = "bearer"
NTLM = "ntlm" NTLM = "ntlm"
PKI = "pki" PKI = "pki"
@@ -437,3 +440,58 @@ class FUZZ_UNION_COLUMN:
STRING = "<string>" STRING = "<string>"
INTEGER = "<integer>" INTEGER = "<integer>"
NULL = "NULL" NULL = "NULL"
class COLOR:
BLUE = "\033[34m"
BOLD_MAGENTA = "\033[35;1m"
BOLD_GREEN = "\033[32;1m"
BOLD_LIGHT_MAGENTA = "\033[95;1m"
LIGHT_GRAY = "\033[37m"
BOLD_RED = "\033[31;1m"
BOLD_LIGHT_GRAY = "\033[37;1m"
YELLOW = "\033[33m"
DARK_GRAY = "\033[90m"
BOLD_CYAN = "\033[36;1m"
LIGHT_RED = "\033[91m"
CYAN = "\033[36m"
MAGENTA = "\033[35m"
LIGHT_MAGENTA = "\033[95m"
LIGHT_GREEN = "\033[92m"
RESET = "\033[0m"
BOLD_DARK_GRAY = "\033[90;1m"
BOLD_LIGHT_YELLOW = "\033[93;1m"
BOLD_LIGHT_RED = "\033[91;1m"
BOLD_LIGHT_GREEN = "\033[92;1m"
LIGHT_YELLOW = "\033[93m"
BOLD_LIGHT_BLUE = "\033[94;1m"
BOLD_LIGHT_CYAN = "\033[96;1m"
LIGHT_BLUE = "\033[94m"
BOLD_WHITE = "\033[97;1m"
LIGHT_CYAN = "\033[96m"
BLACK = "\033[30m"
BOLD_YELLOW = "\033[33;1m"
BOLD_BLUE = "\033[34;1m"
GREEN = "\033[32m"
WHITE = "\033[97m"
BOLD_BLACK = "\033[30;1m"
RED = "\033[31m"
UNDERLINE = "\033[4m"
class BACKGROUND:
BLUE = "\033[44m"
LIGHT_GRAY = "\033[47m"
YELLOW = "\033[43m"
DARK_GRAY = "\033[100m"
LIGHT_RED = "\033[101m"
CYAN = "\033[46m"
MAGENTA = "\033[45m"
LIGHT_MAGENTA = "\033[105m"
LIGHT_GREEN = "\033[102m"
RESET = "\033[0m"
LIGHT_YELLOW = "\033[103m"
LIGHT_BLUE = "\033[104m"
LIGHT_CYAN = "\033[106m"
BLACK = "\033[40m"
GREEN = "\033[42m"
WHITE = "\033[107m"
RED = "\033[41m"

View File

@@ -20,6 +20,7 @@ from lib.core.data import paths
from lib.core.defaults import defaults from lib.core.defaults import defaults
from lib.core.enums import MKSTEMP_PREFIX from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapMissingDependence 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 DEV_EMAIL_ADDRESS
from lib.core.settings import IS_WIN from lib.core.settings import IS_WIN
from lib.core.settings import ISSUES_PAGE from lib.core.settings import ISSUES_PAGE
@@ -72,7 +73,12 @@ def runGui(parser):
tab = event.widget.nametowidget(event.widget.select()) tab = event.widget.nametowidget(event.widget.select())
event.widget.configure(height=tab.winfo_reqheight()) 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) window.title(VERSION_STRING)
# Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook # Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook

View File

@@ -23,7 +23,7 @@ try:
class _ColorizingStreamHandler(ColorizingStreamHandler): class _ColorizingStreamHandler(ColorizingStreamHandler):
def colorize(self, message, levelno, force=False): def colorize(self, message, levelno, force=False):
if levelno in self.level_map and self.is_tty or force: if levelno in self.level_map and (self.is_tty or force):
bg, fg, bold = self.level_map[levelno] bg, fg, bold = self.level_map[levelno]
params = [] params = []

View File

@@ -76,6 +76,7 @@ from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE from lib.core.enums import AUTH_TYPE
from lib.core.enums import CUSTOM_LOGGING from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import DUMP_FORMAT 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 HTTP_HEADER
from lib.core.enums import HTTPMETHOD from lib.core.enums import HTTPMETHOD
from lib.core.enums import MKSTEMP_PREFIX from lib.core.enums import MKSTEMP_PREFIX
@@ -727,7 +728,7 @@ def _setDBMS():
if conf.dbms not in SUPPORTED_DBMS: if conf.dbms not in SUPPORTED_DBMS:
errMsg = "you provided an unsupported back-end database management " errMsg = "you provided an unsupported back-end database management "
errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted(_ for _ in 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 += "If you do not know the back-end DBMS, do not provide "
errMsg += "it and sqlmap will fingerprint it for you." errMsg += "it and sqlmap will fingerprint it for you."
raise SqlmapUnsupportedDBMSException(errMsg) raise SqlmapUnsupportedDBMSException(errMsg)
@@ -1310,7 +1311,7 @@ def _setAuthCred():
def _setHTTPAuthentication(): 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 username and password for first three methods, or PEM private key file for
PKI authentication PKI authentication
""" """
@@ -1333,9 +1334,9 @@ def _setHTTPAuthentication():
errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")" errMsg += "but did not provide the type (e.g. --auth-type=\"basic\")"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.NTLM, AUTH_TYPE.PKI): elif (conf.authType or "").lower() not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.BEARER, AUTH_TYPE.NTLM, AUTH_TYPE.PKI):
errMsg = "HTTP authentication type value must be " errMsg = "HTTP authentication type value must be "
errMsg += "Basic, Digest, NTLM or PKI" errMsg += "Basic, Digest, Bearer, NTLM or PKI"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if not conf.authFile: if not conf.authFile:
@@ -1348,6 +1349,9 @@ def _setHTTPAuthentication():
regExp = "^(.*?):(.*?)$" regExp = "^(.*?):(.*?)$"
errMsg = "HTTP %s authentication credentials " % authType errMsg = "HTTP %s authentication credentials " % authType
errMsg += "value must be in format 'username:password'" 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: elif authType == AUTH_TYPE.NTLM:
regExp = "^(.*\\\\.*):(.*?)$" regExp = "^(.*\\\\.*):(.*?)$"
errMsg = "HTTP NTLM authentication credentials value must " errMsg = "HTTP NTLM authentication credentials value must "
@@ -1916,7 +1920,7 @@ def _cleanupOptions():
def _cleanupEnvironment(): def _cleanupEnvironment():
""" """
Cleanup environment (e.g. from leftovers after --sqlmap-shell). Cleanup environment (e.g. from leftovers after --shell).
""" """
if issubclass(_http_client.socket.socket, socks.socksocket): if issubclass(_http_client.socket.socket, socks.socksocket):
@@ -1997,6 +2001,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache = AttribDict() kb.cache = AttribDict()
kb.cache.addrinfo = {} kb.cache.addrinfo = {}
kb.cache.content = {} kb.cache.content = {}
kb.cache.comparison = {}
kb.cache.encoding = {} kb.cache.encoding = {}
kb.cache.alphaBoundaries = None kb.cache.alphaBoundaries = None
kb.cache.hashRegex = None kb.cache.hashRegex = None
@@ -2484,7 +2489,9 @@ def _setHttpChunked():
if header != HTTP_HEADER.CONTENT_LENGTH: if header != HTTP_HEADER.CONTENT_LENGTH:
self._putheader(header, *values) self._putheader(header, *values)
_http_client.HTTPConnection._putheader = _http_client.HTTPConnection.putheader if not hasattr(_http_client.HTTPConnection, "_putheader"):
_http_client.HTTPConnection._putheader = _http_client.HTTPConnection.putheader
_http_client.HTTPConnection.putheader = putheader _http_client.HTTPConnection.putheader = putheader
def _checkWebSocket(): def _checkWebSocket():
@@ -2542,10 +2549,19 @@ def _basicOptionValidation():
errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option" errMsg = "value for option '--first' (firstChar) must be smaller than or equal to value for --last (lastChar) option"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
if conf.proxyFile and not any((conf.randomAgent, conf.mobile, conf.agent, conf.requestFile)):
warnMsg = "usage of switch '--random-agent' is strongly recommended when "
warnMsg += "using option '--proxy-file'"
logger.warn(warnMsg)
if conf.textOnly and conf.nullConnection: if conf.textOnly and conf.nullConnection:
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'" errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
raise SqlmapSyntaxException(errMsg) 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: if conf.eta and conf.verbose > defaults.verbose:
errMsg = "switch '--eta' is incompatible with option '-v'" errMsg = "switch '--eta' is incompatible with option '-v'"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)

View File

@@ -29,7 +29,7 @@ class Replication(object):
self.cursor = self.connection.cursor() self.cursor = self.connection.cursor()
except sqlite3.OperationalError as ex: except sqlite3.OperationalError as ex:
errMsg = "error occurred while opening a replication " errMsg = "error occurred while opening a replication "
errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex)) errMsg += "file '%s' ('%s')" % (dbpath, getSafeExString(ex))
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
class DataType(object): class DataType(object):

View File

@@ -11,14 +11,16 @@ import random
import re import re
import string import string
import sys import sys
import time
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS from lib.core.enums import OS
from thirdparty import six
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.5.2.0" VERSION = "1.5.7.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
@@ -105,7 +107,7 @@ FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|comparable|compatible|conversion|conv
FUZZ_UNION_MAX_COLUMNS = 10 FUZZ_UNION_MAX_COLUMNS = 10
# Regular expression used for recognition of generic maximum connection messages # 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 # Maximum consecutive connection errors before asking the user if he wants to continue
MAX_CONSECUTIVE_CONNECTION_ERRORS = 15 MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
@@ -125,6 +127,9 @@ MAX_MURPHY_SLEEP_TIME = 3
# Regular expression used for extracting results from Google search # Regular expression used for extracting results from Google search
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)" GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
# Google Search consent cookie
GOOGLE_CONSENT_COOKIE = "CONSENT=YES+shp.gws-%s-0-RC1.%s+FX+740" % (time.strftime("%Y%m%d"), "".join(random.sample(string.ascii_lowercase, 2)))
# Regular expression used for extracting results from DuckDuckGo search # Regular expression used for extracting results from DuckDuckGo search
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)' DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'
@@ -283,11 +288,12 @@ CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
EXTREMEDB_SYSTEM_DBS = ("",) EXTREMEDB_SYSTEM_DBS = ("",)
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA") FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
RAIMA_SYSTEM_DBS = ("",) RAIMA_SYSTEM_DBS = ("",)
VIRTUOSO_SYSTEM_DBS = ("",)
# Note: (<regular>) + (<forks>) # Note: (<regular>) + (<forks>)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona") MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona", "drizzle")
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora") PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "amazon redshift", "redshift", "greenplum", "yellowbrick", "enterprisedb", "yugabyte", "yugabytedb")
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or") ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
SQLITE_ALIASES = ("sqlite", "sqlite3") SQLITE_ALIASES = ("sqlite", "sqlite3")
ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet") ACCESS_ALIASES = ("microsoft access", "msaccess", "access", "jet")
@@ -296,7 +302,7 @@ MAXDB_ALIASES = ("max", "maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server") SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2") DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql") HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",) H2_ALIASES = ("h2",) + ("ignite", "apache ignite")
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix") INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
MONETDB_ALIASES = ("monet", "monetdb",) MONETDB_ALIASES = ("monet", "monetdb",)
DERBY_ALIASES = ("derby", "apache derby",) DERBY_ALIASES = ("derby", "apache derby",)
@@ -307,17 +313,18 @@ ALTIBASE_ALIASES = ("altibase",)
MIMERSQL_ALIASES = ("mimersql", "mimer") MIMERSQL_ALIASES = ("mimersql", "mimer")
CRATEDB_ALIASES = ("cratedb", "crate") CRATEDB_ALIASES = ("cratedb", "crate")
CUBRID_ALIASES = ("cubrid",) CUBRID_ALIASES = ("cubrid",)
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache") CACHE_ALIASES = ("intersystems cache", "cachedb", "cache", "iris")
EXTREMEDB_ALIASES = ("extremedb", "extreme") EXTREMEDB_ALIASES = ("extremedb", "extreme")
FRONTBASE_ALIASES = ("frontbase",) FRONTBASE_ALIASES = ("frontbase",)
RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis") RAIMA_ALIASES = ("raima database manager", "raima", "raimadb", "raimadm", "rdm", "rds", "velocis")
VIRTUOSO_ALIASES = ("virtuoso", "openlink virtuoso")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES + RAIMA_ALIASES) SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES + RAIMA_ALIASES + VIRTUOSO_ALIASES)
SUPPORTED_OS = ("linux", "windows") SUPPORTED_OS = ("linux", "windows")
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES)) DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES), (DBMS.RAIMA, RAIMA_ALIASES), (DBMS.VIRTUOSO, VIRTUOSO_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer") REFERER_ALIASES = ("ref", "referer", "referrer")
@@ -503,6 +510,9 @@ REFLECTED_MAX_REGEX_PARTS = 10
# Chars which can be used as a failsafe values in case of too long URL encoding value # Chars which can be used as a failsafe values in case of too long URL encoding value
URLENCODE_FAILSAFE_CHARS = "()|," URLENCODE_FAILSAFE_CHARS = "()|,"
# Factor used for yuge page multiplication
YUGE_FACTOR = 1000
# Maximum length of URL encoded value after which failsafe procedure takes away # Maximum length of URL encoded value after which failsafe procedure takes away
URLENCODE_CHAR_LIMIT = 2000 URLENCODE_CHAR_LIMIT = 2000
@@ -897,6 +907,9 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
# Letters of lower frequency used in kb.chars # Letters of lower frequency used in kb.chars
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp" KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
# Printable bytes
PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable)
# SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk) # SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk)
HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules") HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules")

View File

@@ -40,30 +40,32 @@ def vulnTest():
TESTS = ( TESTS = (
("-h", ("to see full list of options run with '-hh'",)), ("-h", ("to see full list of options run with '-hh'",)),
("--dependencies --deprecations", ("sqlmap requires", "third-party library", "~DeprecationWarning:")), ("--dependencies --deprecations", ("sqlmap requires", "third-party library", "~DeprecationWarning:")),
("-u <url> --flush-session --wizard", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")), ("-u <url> --data='reflect=1' --flush-session --wizard --disable-coloring", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
(u"-c <config> --flush-session --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible")), ("-u <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=\"<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'",)), (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")), ("--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")),
("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)), ("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --text-only --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)),
("--list-tampers", ("between", "MySQL", "xforwardedfor")), ("--list-tampers", ("between", "MySQL", "xforwardedfor")),
("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<config>", ("CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind", "saved command line options to the configuration file")), ("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<config>", ("CloudFlare", "web application technology: Express", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind", "saved command line options to the configuration file")),
("-c <config>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")), ("-c <config>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
("<piped> -r <request> -l <log> --flush-session --banner --technique=B", ("banner: '3.", "STDIN")), ("<piped> -r <request> -l <log> --flush-session --banner --technique=B", ("banner: '3.", "STDIN")),
("-l <log> --flush-session --keep-alive --skip-waf -v 5 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")), ("-l <log> --flush-session --keep-alive --skip-waf -vvvvv --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")), ("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
("-u <url> --flush-session --data='id=1&_=Eewef6oh' --chunked --randomize=_ --random-agent --banner", ("fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")), ("-u <base> --flush-session --data='id=1&_=Eewef6oh' --chunked --randomize=_ --random-agent --banner", ("fetched random HTTP User-Agent header value", "Parameter: id (POST)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --banner --technique=B", ("banner: '3.",)), ("-u <base64> -p id --base64=id --data='base64=true' --flush-session --banner --technique=B", ("banner: '3.",)),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --tables --technique=U", (" users ",)), ("-u <base64> -p id --base64=id --data='base64=true' --flush-session --tables --technique=U", (" users ",)),
("-u <url> --flush-session --banner --technique=B --not-string 'no results'", ("banner: '3.",)), ("-u <url> --flush-session --banner --technique=B --disable-precon --not-string 'no results'", ("banner: '3.",)),
("-u <url> --flush-session --banner --technique=B --first=1 --last=2", ("banner: '3.'",)), ("-u <url> --flush-session --encoding=gbk --banner --technique=B --first=1 --last=2", ("banner: '3.'",)),
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")), ("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
("-u <url> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")), ("-u <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 <url> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")), ("-u <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 <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --har=<tmp> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")), ("-u <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 <tmp>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")), ("-u <url> --flush-session -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 --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 --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner", ("NULL connection is supported with HEAD method", "banner: '3.")), ("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner --count -T users", ("NULL connection is supported with HEAD method", "banner: '3.", "users | 5")),
("-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"", ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")), ("-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"import hashlib; id2=2; id3=hashlib.md5(id.encode()).hexdigest()\" --referer=\"localhost\"", ("might be injectable", ": syntax error", "back-end DBMS: SQLite", "WHERE or HAVING clause (subquery")),
("-u <url> --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")), ("-u <url> --banner --schema --dump -T users --binary-fields=surname --where \"id>3\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "2 entries", "6E616D6569736E756C6C")),
("-u <url> --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3", ("performed 6 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")), ("-u <url> --technique=U --fresh-queries --force-partial --dump -T users --dump-format=HTML --answers=\"crack=n\" -v 3", ("performed 6 queries", "nameisnull", "~using default dictionary", "dumped to HTML file")),
@@ -116,30 +118,37 @@ def vulnTest():
handle, log = tempfile.mkstemp(suffix=".log") handle, log = tempfile.mkstemp(suffix=".log")
os.close(handle) os.close(handle)
handle, multiple = tempfile.mkstemp(suffix=".lst")
os.close(handle)
content = "POST / HTTP/1.0\nUser-agent: foobar\nHost: %s:%s\n\nid=1\n" % (address, port) content = "POST / HTTP/1.0\nUser-agent: foobar\nHost: %s:%s\n\nid=1\n" % (address, port)
open(request, "w+").write(content) open(request, "w+").write(content)
open(log, "w+").write('<port>%d</port><request base64="true"><![CDATA[%s]]></request>' % (port, encodeBase64(content, binary=False))) open(log, "w+").write('<port>%d</port><request base64="true"><![CDATA[%s]]></request>' % (port, encodeBase64(content, binary=False)))
url = "http://%s:%d/?id=1" % (address, port) base = "http://%s:%d/" % (address, port)
url = "%s?id=1" % base
direct = "sqlite3://%s" % database direct = "sqlite3://%s" % database
tmpdir = tempfile.mkdtemp()
content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url) content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url)
open(config, "w+").write(content) open(config, "w+").write(content)
open(multiple, "w+").write("%s?%s=%d\n%s?%s=%d\n%s&%s=1" % (base, randomStr(), randomInt(), base, randomStr(), randomInt(), url, randomStr()))
for options, checks in TESTS: for options, checks in TESTS:
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS))) status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status)) dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
for tag, value in (("<url>", url), ("<direct>", direct), ("<request>", request), ("<log>", log), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))): for tag, value in (("<url>", url), ("<base>", base), ("<direct>", direct), ("<tmpdir>", tmpdir), ("<request>", request), ("<log>", log), ("<multiple>", multiple), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
options = options.replace(tag, value) options = options.replace(tag, value)
cmd = "%s \"%s\" %s --batch --non-interactive --debug" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options) 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() handle, tmp = tempfile.mkstemp()
os.close(handle) os.close(handle)
cmd = cmd.replace("<tmp>", tmp) cmd = cmd.replace("<tmpfile>", tmp)
if "<piped>" in cmd: if "<piped>" in cmd:
cmd = re.sub(r"<piped>\s*", "", cmd) cmd = re.sub(r"<piped>\s*", "", cmd)
@@ -162,107 +171,6 @@ def vulnTest():
return retVal 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(): def fuzzTest():
count = 0 count = 0
address, port = "127.0.0.10", random.randint(1025, 65535) address, port = "127.0.0.10", random.randint(1025, 65535)
@@ -300,11 +208,15 @@ def fuzzTest():
if any(_ in lines[j] for _ in ("googleDork",)): if any(_ in lines[j] for _ in ("googleDork",)):
continue continue
if re.search(r"= (True|False)", lines[j]):
lines[j] = lines[j].replace(" = False", " = True")
continue
if lines[j].strip().endswith('='): if lines[j].strip().endswith('='):
lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0] lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0]
k = random.randint(0, len(lines) - 1) 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)) lines[k] += chr(random.randint(0, 255))
open(config, "w+").write("\n".join(lines)) open(config, "w+").write("\n".join(lines))

View File

@@ -161,7 +161,7 @@ def update():
if IS_WIN: if IS_WIN:
infoMsg = "for Windows platform it's recommended " infoMsg = "for Windows platform it's recommended "
infoMsg += "to use a GitHub for Windows client for updating " infoMsg += "to use a GitHub for Windows client for updating "
infoMsg += "purposes (http://windows.github.com/) or just " infoMsg += "purposes (https://desktop.github.com/) or just "
infoMsg += "download the latest snapshot from " infoMsg += "download the latest snapshot from "
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads" infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
else: else:

View File

@@ -193,7 +193,7 @@ def cmdLineParser(argv=None):
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")") help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
request.add_argument("--auth-type", dest="authType", 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", request.add_argument("--auth-cred", dest="authCred",
help="HTTP authentication credentials (name:password)") help="HTTP authentication credentials (name:password)")
@@ -704,7 +704,7 @@ def cmdLineParser(argv=None):
help="Regexp for filtering targets") help="Regexp for filtering targets")
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true", general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
help="Skip heuristic detection of SQLi/XSS vulnerabilities") help="Skip heuristic detection of vulnerabilities")
general.add_argument("--skip-waf", dest="skipWaf", action="store_true", general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
help="Skip heuristic detection of WAF/IPS protection") 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") help="Run host OS command(s) when SQL injection is found")
miscellaneous.add_argument("--beep", dest="beep", action="store_true", 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", miscellaneous.add_argument("--dependencies", dest="dependencies", action="store_true",
help="Check for missing (optional) sqlmap dependencies") help="Check for missing (optional) sqlmap dependencies")
@@ -751,7 +751,7 @@ def cmdLineParser(argv=None):
miscellaneous.add_argument("--results-file", dest="resultsFile", miscellaneous.add_argument("--results-file", dest="resultsFile",
help="Location of CSV results file in multiple targets mode") help="Location of CSV results file in multiple targets mode")
miscellaneous.add_argument("--sqlmap-shell", dest="sqlmapShell", action="store_true", miscellaneous.add_argument("--shell", dest="shell", action="store_true",
help="Prompt for an interactive sqlmap shell") help="Prompt for an interactive sqlmap shell")
miscellaneous.add_argument("--tmp-dir", dest="tmpDir", miscellaneous.add_argument("--tmp-dir", dest="tmpDir",
@@ -773,6 +773,9 @@ def cmdLineParser(argv=None):
parser.add_argument("--dummy", dest="dummy", action="store_true", parser.add_argument("--dummy", dest="dummy", action="store_true",
help=SUPPRESS) help=SUPPRESS)
parser.add_argument("--yuge", dest="yuge", action="store_true",
help=SUPPRESS)
parser.add_argument("--murphy-rate", dest="murphyRate", type=int, parser.add_argument("--murphy-rate", dest="murphyRate", type=int,
help=SUPPRESS) help=SUPPRESS)
@@ -794,6 +797,9 @@ def cmdLineParser(argv=None):
parser.add_argument("--profile", dest="profile", action="store_true", parser.add_argument("--profile", dest="profile", action="store_true",
help=SUPPRESS) help=SUPPRESS)
parser.add_argument("--localhost", dest="localhost", action="store_true",
help=SUPPRESS)
parser.add_argument("--force-dbms", dest="forceDbms", parser.add_argument("--force-dbms", dest="forceDbms",
help=SUPPRESS) help=SUPPRESS)
@@ -818,9 +824,6 @@ def cmdLineParser(argv=None):
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true", parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
help=SUPPRESS) help=SUPPRESS)
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
help=SUPPRESS)
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true", parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
help=SUPPRESS) help=SUPPRESS)
@@ -894,7 +897,7 @@ def cmdLineParser(argv=None):
raise SqlmapSilentQuitException raise SqlmapSilentQuitException
elif "--sqlmap-shell" in argv: elif "--shell" in argv:
_createHomeDirectories() _createHomeDirectories()
parser.usage = "" parser.usage = ""
@@ -907,14 +910,17 @@ def cmdLineParser(argv=None):
while True: while True:
command = None command = None
prompt = "sqlmap > "
try: try:
# Note: in Python2 command should not be converted to Unicode before passing to shlex (Reference: https://bugs.python.org/issue1170) # Note: in Python2 command should not be converted to Unicode before passing to shlex (Reference: https://bugs.python.org/issue1170)
command = _input("sqlmap-shell> ").strip() command = _input(prompt).strip()
except (KeyboardInterrupt, EOFError): except (KeyboardInterrupt, EOFError):
print() print()
raise SqlmapShellQuitException raise SqlmapShellQuitException
command = re.sub(r"(?i)\Anew\s+", "", command or "")
if not command: if not command:
continue continue
elif command.lower() == "clear": elif command.lower() == "clear":
@@ -924,8 +930,9 @@ def cmdLineParser(argv=None):
elif command.lower() in ("x", "q", "exit", "quit"): elif command.lower() in ("x", "q", "exit", "quit"):
raise SqlmapShellQuitException raise SqlmapShellQuitException
elif command[0] != '-': elif command[0] != '-':
dataToStdout("[!] invalid option(s) provided\n") if not re.search(r"(?i)\A(\?|help)\Z", command):
dataToStdout("[i] proper example: '-u http://www.site.com/vuln.php?id=1 --banner'\n") dataToStdout("[!] invalid option(s) provided\n")
dataToStdout("[i] valid example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
else: else:
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP) saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP) loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
@@ -969,6 +976,8 @@ def cmdLineParser(argv=None):
argv[i] = "" argv[i] = ""
elif argv[i].startswith("--data-raw"): elif argv[i].startswith("--data-raw"):
argv[i] = argv[i].replace("--data-raw", "--data", 1) 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"): elif argv[i].startswith("--drop-cookie"):
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1) argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")): elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")):
@@ -1056,8 +1065,8 @@ def cmdLineParser(argv=None):
else: else:
args.stdinPipe = None 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, --list-tampers, --wizard, --update, --purge or --dependencies). " 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" errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg) parser.error(errMsg)

View File

@@ -48,6 +48,7 @@ from lib.core.settings import IDENTYWAF_PARSE_LIMIT
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
from lib.core.settings import META_CHARSET_REGEX from lib.core.settings import META_CHARSET_REGEX
from lib.core.settings import PARSE_HEADERS_LIMIT from lib.core.settings import PARSE_HEADERS_LIMIT
from lib.core.settings import PRINTABLE_BYTES
from lib.core.settings import SELECT_FROM_TABLE_REGEX from lib.core.settings import SELECT_FROM_TABLE_REGEX
from lib.core.settings import UNICODE_ENCODING from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import VIEWSTATE_REGEX from lib.core.settings import VIEWSTATE_REGEX
@@ -259,7 +260,7 @@ def getHeuristicCharEncoding(page):
""" """
key = hash(page) key = hash(page)
retVal = kb.cache.encoding.get(key) or detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])["encoding"] retVal = kb.cache.encoding[key] if key in kb.cache.encoding else detect(page[:HEURISTIC_PAGE_SIZE_THRESHOLD])["encoding"]
kb.cache.encoding[key] = retVal kb.cache.encoding[key] = retVal
if retVal and retVal.lower().replace('-', "") == UNICODE_ENCODING.lower().replace('-', ""): if retVal and retVal.lower().replace('-', "") == UNICODE_ENCODING.lower().replace('-', ""):
@@ -324,7 +325,7 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page)) metaCharset = checkCharEncoding(extractRegexResult(META_CHARSET_REGEX, page))
if (any((httpCharset, metaCharset)) and not all((httpCharset, metaCharset))) or (httpCharset == metaCharset and all((httpCharset, metaCharset))): if (any((httpCharset, metaCharset)) and (not all((httpCharset, metaCharset)) or isinstance(page, six.binary_type) and all(_ in PRINTABLE_BYTES for _ in page))) or (httpCharset == metaCharset and all((httpCharset, metaCharset))):
kb.pageEncoding = httpCharset or metaCharset # Reference: http://bytes.com/topic/html-css/answers/154758-http-equiv-vs-true-header-has-precedence kb.pageEncoding = httpCharset or metaCharset # Reference: http://bytes.com/topic/html-css/answers/154758-http-equiv-vs-true-header-has-precedence
debugMsg = "declared web page charset '%s'" % kb.pageEncoding debugMsg = "declared web page charset '%s'" % kb.pageEncoding
singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg) singleTimeLogMessage(debugMsg, logging.DEBUG, debugMsg)

View File

@@ -13,6 +13,7 @@ from lib.core.common import extractRegexResult
from lib.core.common import getFilteredPageContent from lib.core.common import getFilteredPageContent
from lib.core.common import listToStrValue from lib.core.common import listToStrValue
from lib.core.common import removeDynamicContent from lib.core.common import removeDynamicContent
from lib.core.common import getLastRequestHTTPError
from lib.core.common import wasLastResponseDBMSError from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError from lib.core.common import wasLastResponseHTTPError
from lib.core.convert import getBytes from lib.core.convert import getBytes
@@ -91,7 +92,8 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
if page: if page:
# In case of an DBMS error page return None # In case of an DBMS error page return None
if kb.errorIsNone and (wasLastResponseDBMSError() or wasLastResponseHTTPError()) and not kb.negativeLogic: 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 # Dynamic content lines to be excluded before comparison
if not kb.nullConnection: if not kb.nullConnection:
@@ -151,10 +153,20 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
seq1 = seq1.split("\n") seq1 = seq1.split("\n")
seq2 = seq2.split("\n") seq2 = seq2.split("\n")
key = None
else:
key = (hash(seq1), hash(seq2))
seqMatcher.set_seq1(seq1) seqMatcher.set_seq1(seq1)
seqMatcher.set_seq2(seq2) 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 # If the url is stable and we did not set yet the match ratio and the
# current injected value changes the url page content # current injected value changes the url page content

View File

@@ -126,6 +126,7 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import URI_HTTP_HEADER from lib.core.settings import URI_HTTP_HEADER
from lib.core.settings import WARN_TIME_STDEV from lib.core.settings import WARN_TIME_STDEV
from lib.core.settings import WEBSOCKET_INITIAL_TIMEOUT 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 decodePage
from lib.request.basic import forgeHeaders from lib.request.basic import forgeHeaders
from lib.request.basic import processResponse from lib.request.basic import processResponse
@@ -252,6 +253,9 @@ class Connect(object):
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
break break
if conf.yuge:
retVal = YUGE_FACTOR * retVal
return retVal return retVal
@staticmethod @staticmethod
@@ -488,6 +492,9 @@ class Connect(object):
header, value = line.split(':', 1) header, value = line.split(':', 1)
headers[header] = value headers[header] = value
if conf.localhost:
headers[HTTP_HEADER.HOST] = "localhost"
for key, value in list(headers.items()): for key, value in list(headers.items()):
del headers[key] del headers[key]
if isinstance(value, six.string_types): if isinstance(value, six.string_types):
@@ -498,8 +505,6 @@ class Connect(object):
if six.PY2: if six.PY2:
url = getBytes(url) # Note: Python3 requires text while Python2 has problems when mixing text with binary POST url = getBytes(url) # Note: Python3 requires text while Python2 has problems when mixing text with binary POST
post = getBytes(post)
if webSocket: if webSocket:
ws = websocket.WebSocket() ws = websocket.WebSocket()
ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout) ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout)
@@ -543,6 +548,8 @@ class Connect(object):
logger.log(CUSTOM_LOGGING.TRAFFIC_OUT, requestMsg) logger.log(CUSTOM_LOGGING.TRAFFIC_OUT, requestMsg)
else: else:
post = getBytes(post)
if target and cmdLineOptions.method or method and method not in (HTTPMETHOD.GET, HTTPMETHOD.POST): if target and cmdLineOptions.method or method and method not in (HTTPMETHOD.GET, HTTPMETHOD.POST):
req = MethodRequest(url, post, headers) req = MethodRequest(url, post, headers)
req.set_method(cmdLineOptions.method or method) req.set_method(cmdLineOptions.method or method)
@@ -619,7 +626,7 @@ class Connect(object):
if conn: if conn:
code = (code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes) code = (code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes)
responseHeaders = conn.info() responseHeaders = conn.info()
responseHeaders[URI_HTTP_HEADER] = conn.geturl() responseHeaders[URI_HTTP_HEADER] = conn.geturl() if hasattr(conn, "geturl") else url
if hasattr(conn, "redurl"): if hasattr(conn, "redurl"):
responseHeaders[HTTP_HEADER.LOCATION] = conn.redurl responseHeaders[HTTP_HEADER.LOCATION] = conn.redurl
@@ -747,7 +754,9 @@ class Connect(object):
if ex.code not in (conf.ignoreCode or []): if ex.code not in (conf.ignoreCode or []):
if ex.code == _http_client.UNAUTHORIZED: if ex.code == _http_client.UNAUTHORIZED:
errMsg = "not authorized, try to provide right HTTP " errMsg = "not authorized, try to provide right HTTP "
errMsg += "authentication type and valid credentials (%d)" % code errMsg += "authentication type and valid credentials (%d). " % code
errMsg += "If this is intended, try to rerun by providing "
errMsg += "a valid value for option '--ignore-code'"
raise SqlmapConnectionException(errMsg) raise SqlmapConnectionException(errMsg)
elif chunked and ex.code in (_http_client.METHOD_NOT_ALLOWED, _http_client.LENGTH_REQUIRED): elif chunked and ex.code in (_http_client.METHOD_NOT_ALLOWED, _http_client.LENGTH_REQUIRED):
warnMsg = "turning off HTTP chunked transfer encoding " warnMsg = "turning off HTTP chunked transfer encoding "
@@ -780,7 +789,7 @@ class Connect(object):
debugMsg = "got HTTP error code: %d ('%s')" % (code, status) debugMsg = "got HTTP error code: %d ('%s')" % (code, status)
logger.debug(debugMsg) logger.debug(debugMsg)
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError): 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() tbMsg = traceback.format_exc()
if conf.debug: if conf.debug:
@@ -788,6 +797,11 @@ class Connect(object):
if checking: if checking:
return None, None, None return None, None, None
elif "AttributeError:" in tbMsg:
if "WSAECONNREFUSED" in tbMsg:
return None, None, None
else:
raise
elif "no host given" in tbMsg: elif "no host given" in tbMsg:
warnMsg = "invalid URL address used (%s)" % repr(url) warnMsg = "invalid URL address used (%s)" % repr(url)
raise SqlmapSyntaxException(warnMsg) raise SqlmapSyntaxException(warnMsg)

View File

@@ -68,8 +68,8 @@ class DNSServer(object):
raw request raw request
Reference(s): Reference(s):
http://code.activestate.com/recipes/491264-mini-fake-dns-server/ https://code.activestate.com/recipes/491264-mini-fake-dns-server/
https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py https://web.archive.org/web/20150418152405/https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py
""" """
def __init__(self): def __init__(self):

View File

@@ -198,7 +198,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
# forge the SQL limiting the query output one entry at a time # forge the SQL limiting the query output one entry at a time
# NOTE: we assume that only queries that get data from a table # NOTE: we assume that only queries that get data from a table
# can return multiple entries # can return multiple entries
if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I): if fromUser and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I) and hasattr(queries[Backend.getIdentifiedDbms()].limitregexp, "query"):
expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression) expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression)
if limitCond: if limitCond:

View File

@@ -130,7 +130,7 @@ class UDF(object):
errMsg = "udfSetLocalPaths() method must be defined within the plugin" errMsg = "udfSetLocalPaths() method must be defined within the plugin"
raise SqlmapUnsupportedFeatureException(errMsg) raise SqlmapUnsupportedFeatureException(errMsg)
def udfCreateFromSharedLib(self, udf=None, inpRet=None): def udfCreateFromSharedLib(self, udf, inpRet):
errMsg = "udfCreateFromSharedLib() method must be defined within the plugin" errMsg = "udfCreateFromSharedLib() method must be defined within the plugin"
raise SqlmapUnsupportedFeatureException(errMsg) raise SqlmapUnsupportedFeatureException(errMsg)

View File

@@ -26,6 +26,7 @@ from lib.core.common import goGoodSamaritan
from lib.core.common import hashDBRetrieve from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite from lib.core.common import hashDBWrite
from lib.core.common import incrementCounter from lib.core.common import incrementCounter
from lib.core.common import isListLike
from lib.core.common import safeStringFormat from lib.core.common import safeStringFormat
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.data import conf 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 markingValue = "'%s'" % CHAR_INFERENCE_MARK
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue)) 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) 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) result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
incrementCounter(getTechnique()) incrementCounter(getTechnique())
@@ -504,6 +505,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else: else:
break break
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4629
if not isListLike(threadData.shared.value):
break
with kb.locks.value: with kb.locks.value:
threadData.shared.value[currentCharIndex - 1 - firstChar] = val threadData.shared.value[currentCharIndex - 1 - firstChar] = val
currentValue = list(threadData.shared.value) currentValue = list(threadData.shared.value)

View File

@@ -104,6 +104,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
if kb.orderByColumns is None and (lowerCount == 1 or conf.uCols): # Note: ORDER BY is not bullet-proof if kb.orderByColumns is None and (lowerCount == 1 or conf.uCols): # Note: ORDER BY is not bullet-proof
found = _orderByTechnique(lowerCount, upperCount) if conf.uCols else _orderByTechnique() found = _orderByTechnique(lowerCount, upperCount) if conf.uCols else _orderByTechnique()
if found: if found:
kb.orderByColumns = found kb.orderByColumns = found
infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "") infoMsg = "target URL appears to have %d column%s in query" % (found, 's' if found > 1 else "")
@@ -122,8 +123,10 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
query = agent.forgeUnionQuery('', -1, count, comment, prefix, suffix, kb.uChar, where) query = agent.forgeUnionQuery('', -1, count, comment, prefix, suffix, kb.uChar, where)
payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where) payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where)
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False) page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
if not isNullValue(kb.uChar): if not isNullValue(kb.uChar):
pages[count] = page pages[count] = page
ratio = comparison(page, headers, code, getRatioValue=True) or MIN_RATIO ratio = comparison(page, headers, code, getRatioValue=True) or MIN_RATIO
ratios.append(ratio) ratios.append(ratio)
min_, max_ = min(min_, ratio), max(max_, ratio) min_, max_ = min(min_, ratio), max(max_, ratio)

View File

@@ -25,6 +25,7 @@ from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite from lib.core.common import hashDBWrite
from lib.core.common import incrementCounter from lib.core.common import incrementCounter
from lib.core.common import initTechnique from lib.core.common import initTechnique
from lib.core.common import isDigit
from lib.core.common import isListLike from lib.core.common import isListLike
from lib.core.common import isNoneValue from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue from lib.core.common import isNumPosStrValue
@@ -186,25 +187,25 @@ def configUnion(char=None, columns=None):
kb.uChar = char kb.uChar = char
if conf.uChar is not None: if conf.uChar is not None:
kb.uChar = char.replace("[CHAR]", conf.uChar if conf.uChar.isdigit() else "'%s'" % conf.uChar.strip("'")) kb.uChar = char.replace("[CHAR]", conf.uChar if isDigit(conf.uChar) else "'%s'" % conf.uChar.strip("'"))
def _configUnionCols(columns): def _configUnionCols(columns):
if not isinstance(columns, six.string_types): if not isinstance(columns, six.string_types):
return return
columns = columns.replace(" ", "") columns = columns.replace(' ', "")
if "-" in columns: if '-' in columns:
colsStart, colsStop = columns.split("-") colsStart, colsStop = columns.split('-')
else: else:
colsStart, colsStop = columns, columns colsStart, colsStop = columns, columns
if not colsStart.isdigit() or not colsStop.isdigit(): if not isDigit(colsStart) or not isDigit(colsStop):
raise SqlmapSyntaxException("--union-cols must be a range of integers") raise SqlmapSyntaxException("--union-cols must be a range of integers")
conf.uColsStart, conf.uColsStop = int(colsStart), int(colsStop) conf.uColsStart, conf.uColsStop = int(colsStart), int(colsStop)
if conf.uColsStart > conf.uColsStop: if conf.uColsStart > conf.uColsStop:
errMsg = "--union-cols range has to be from lower to " errMsg = "--union-cols range has to represent lower to "
errMsg += "higher number of columns" errMsg += "higher number of columns"
raise SqlmapSyntaxException(errMsg) raise SqlmapSyntaxException(errMsg)
@@ -329,8 +330,8 @@ def unionUse(expression, unpack=True, dump=False):
if stopLimit > TURN_OFF_RESUME_INFO_LIMIT: if stopLimit > TURN_OFF_RESUME_INFO_LIMIT:
kb.suppressResumeInfo = True kb.suppressResumeInfo = True
debugMsg = "suppressing possible resume console info because of " debugMsg = "suppressing possible resume console info for "
debugMsg += "large number of rows. It might take too long" debugMsg += "large number of rows as it might take too long"
logger.debug(debugMsg) logger.debug(debugMsg)
try: try:

View File

@@ -165,7 +165,7 @@ class Response(object):
try: try:
content = response.read() content = response.read()
except _http_client.IncompleteRead: except _http_client.IncompleteRead:
content = raw[raw.find("\r\n\r\n") + 4:].rstrip("\r\n") content = raw[raw.find(b"\r\n\r\n") + 4:].rstrip(b"\r\n")
return cls(httpVersion="HTTP/1.1" if response.version == 11 else "HTTP/1.0", return cls(httpVersion="HTTP/1.1" if response.version == 11 else "HTTP/1.0",
status=response.status, status=response.status,

View File

@@ -13,22 +13,6 @@ except: # removed ImportError because of https://github.com/sqlmapproject/sqlma
from thirdparty.fcrypt.fcrypt import crypt from thirdparty.fcrypt.fcrypt import crypt
_multiprocessing = None _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 base64
import binascii import binascii
@@ -367,7 +351,7 @@ def crypt_generic_passwd(password, salt, **kwargs):
'rl.3StKT.4T8M' 'rl.3StKT.4T8M'
""" """
return crypt(password, salt) return getText(crypt(password, salt))
def unix_md5_passwd(password, salt, magic="$1$", **kwargs): def unix_md5_passwd(password, salt, magic="$1$", **kwargs):
""" """
@@ -983,6 +967,24 @@ def dictionaryAttack(attack_dict):
if conf.disableMulti: if conf.disableMulti:
_multiprocessing = None _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 (_, hashes) in attack_dict.items():
for hash_ in hashes: for hash_ in hashes:
@@ -1133,7 +1135,7 @@ def dictionaryAttack(attack_dict):
custom_wordlist.append(normalizeUnicode(user)) custom_wordlist.append(normalizeUnicode(user))
# Algorithms without extra arguments (e.g. salt and/or username) # 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: for suffix in suffix_list:
if not attack_info or processException: if not attack_info or processException:
break break

View File

@@ -28,6 +28,7 @@ from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BING_REGEX from lib.core.settings import BING_REGEX
from lib.core.settings import DUCKDUCKGO_REGEX from lib.core.settings import DUCKDUCKGO_REGEX
from lib.core.settings import DUMMY_SEARCH_USER_AGENT 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 GOOGLE_REGEX
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
from lib.core.settings import UNICODE_ENCODING 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.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.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE
requestHeaders[HTTP_HEADER.COOKIE] = GOOGLE_CONSENT_COOKIE
try: try:
req = _urllib.request.Request("https://www.google.com/ncr", headers=requestHeaders) 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 gpage = conf.googlePage if conf.googlePage > 1 else 1
logger.info("using search result page #%d" % gpage) 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 += "q=%s&" % urlencode(dork, convall=True)
url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search" url += "num=100&hl=en&complete=0&safe=off&filter=0&btnG=Search"
url += "&start=%d" % ((gpage - 1) * 100) url += "&start=%d" % ((gpage - 1) * 100)

View File

@@ -101,13 +101,22 @@ class SQLAlchemy(GenericConnector):
return None return None
def execute(self, query): def execute(self, query):
retVal = False
try: try:
self.cursor = self.connector.execute(query) self.cursor = self.connector.execute(query)
retVal = True
except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError) as ex: except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError) as ex:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex)) logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
except _sqlalchemy.exc.InternalError as ex: except _sqlalchemy.exc.InternalError as ex:
raise SqlmapConnectionException(getSafeExString(ex)) raise SqlmapConnectionException(getSafeExString(ex))
return retVal
def select(self, query): def select(self, query):
self.execute(query) retVal = None
return self.fetchall()
if self.execute(query):
retVal = self.fetchall()
return retVal

View File

@@ -22,9 +22,8 @@ from plugins.generic.connector import Connector as GenericConnector
class Connector(GenericConnector): class Connector(GenericConnector):
""" """
Homepage: http://pyodbc.googlecode.com/ Homepage: https://github.com/mkleehammer/pyodbc
User guide: http://code.google.com/p/pyodbc/wiki/GettingStarted User guide: https://github.com/mkleehammer/pyodbc/wiki
API: http://code.google.com/p/pyodbc/w/list
Debian package: python-pyodbc Debian package: python-pyodbc
License: MIT License: MIT
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -11,7 +11,7 @@ class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): 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 True
""" """

View File

@@ -150,7 +150,8 @@ class Fingerprint(GenericFingerprint):
"Vista or 2008": ("6.0", (2, 1)), "Vista or 2008": ("6.0", (2, 1)),
"7 or 2008 R2": ("6.1", (1, 0)), "7 or 2008 R2": ("6.1", (1, 0)),
"8 or 2012": ("6.2", (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 # Get back-end DBMS underlying operating system version

View File

@@ -21,10 +21,9 @@ from plugins.generic.connector import Connector as GenericConnector
class Connector(GenericConnector): class Connector(GenericConnector):
""" """
Homepage: http://code.google.com/p/pymysql/ Homepage: https://github.com/PyMySQL/PyMySQL
User guide: http://code.google.com/p/pymysql/ User guide: https://pymysql.readthedocs.io/en/latest/
API: http://code.google.com/p/pymysql/ Debian package: python3-pymysql
Debian package: <none>
License: MIT License: MIT
Possible connectors: http://wiki.python.org/moin/MySQL Possible connectors: http://wiki.python.org/moin/MySQL

View File

@@ -45,10 +45,10 @@ class Fingerprint(GenericFingerprint):
# Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/ # Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/
versions = ( versions = (
(80000, 80021), # MySQL 8.0 (80000, 80028), # MySQL 8.0
(60000, 60014), # MySQL 6.0 (60000, 60014), # MySQL 6.0
(50700, 50731), # MySQL 5.7 (50700, 50736), # MySQL 5.7
(50600, 50649), # MySQL 5.6 (50600, 50652), # MySQL 5.6
(50500, 50563), # MySQL 5.5 (50500, 50563), # MySQL 5.5
(50400, 50404), # MySQL 5.4 (50400, 50404), # MySQL 5.4
(50100, 50174), # MySQL 5.1 (50100, 50174), # MySQL 5.1

View File

@@ -105,7 +105,7 @@ class Fingerprint(GenericFingerprint):
logger.info(infoMsg) logger.info(infoMsg)
# Reference: https://en.wikipedia.org/wiki/Oracle_Database # 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)) 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)) output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))

View File

@@ -131,7 +131,9 @@ class Fingerprint(GenericFingerprint):
infoMsg = "actively fingerprinting %s" % DBMS.PGSQL infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
logger.info(infoMsg) 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") Backend.setVersion(">= 12.0")
elif inject.checkBooleanExpression("SHA256(NULL) IS NULL"): elif inject.checkBooleanExpression("SHA256(NULL) IS NULL"):
Backend.setVersion(">= 11.0") Backend.setVersion(">= 11.0")

View File

@@ -5,35 +5,18 @@ Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import binascii from lib.core.convert import getOrds
from lib.core.common import isDBMSVersionAtLeast
from lib.core.convert import getBytes
from lib.core.convert import getUnicode
from plugins.generic.syntax import Syntax as GenericSyntax from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax): class Syntax(GenericSyntax):
@staticmethod @staticmethod
def escape(expression, quote=True): def escape(expression, quote=True):
""" """
>>> from lib.core.common import Backend >>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97,98,99,100,101,102,103,104) FROM foobar"
>>> 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"
True True
""" """
def escaper(value): def escaper(value):
# Reference: http://stackoverflow.com/questions/3444335/how-do-i-quote-a-utf-8-string-literal-in-sqlite3 return "CHAR(%s)" % ','.join("%d" % _ for _ in getOrds(value))
return "CAST(X'%s' AS TEXT)" % getUnicode(binascii.hexlify(getBytes(value)))
retVal = expression return Syntax._escape(expression, quote, escaper)
if isDBMSVersionAtLeast('3'):
retVal = Syntax._escape(expression, quote, escaper)
return retVal

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