From a3defc175dcdfb115e8085d25192e6294e0c79f6 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Wed, 11 Sep 2013 23:17:18 +0200 Subject: [PATCH] Fix (we are not using certificate but PEM private key file in this particular authentication; also, auxiliary cert_file is holding certificate chain that is ignored by python itself) --- extra/shutils/_sqlmap.py | 177 ------------------ lib/core/enums.py | 2 +- lib/core/option.py | 47 ++--- lib/core/optiondict.py | 2 +- lib/parse/cmdline.py | 7 +- lib/request/{certhandler.py => pkihandler.py} | 7 +- sqlmap.conf | 10 +- 7 files changed, 30 insertions(+), 222 deletions(-) delete mode 100644 extra/shutils/_sqlmap.py rename lib/request/{certhandler.py => pkihandler.py} (72%) diff --git a/extra/shutils/_sqlmap.py b/extra/shutils/_sqlmap.py deleted file mode 100644 index 44c33bfb1..000000000 --- a/extra/shutils/_sqlmap.py +++ /dev/null @@ -1,177 +0,0 @@ -#compdef sqlmap.py - -# sqlmap completion commands. written by kost -# put this file in your zsh completion dir and restart your shell. Zsh completion dir is usually -# located somewhere in /usr/share/zsh/ or /usr/local/share/zsh - -local curcontext="$curcontext" state line - -_arguments -C -s \ - '(- *)'{--help,-h}'[Show basic help message and exit]' \ - '(- *)'-hh'[Show advanced help message and exit]' \ - '(-v)'-v+'[Verbosity level: 0-6 (default 1)]:Verbosity level (0-6) - default 1' \ - '(-d)'-d+'[Direct connection to the database]' \ - '(-u,--url)'{-u+,--url=-}'[Target url]' \ - '(-g)'-g+'[Process Google dork results as target urls]' \ - '(--data)'--data=-'[Data string to be sent through POST]' \ - '(-l)'-l+'[Parse targets from Burp or WebScarab proxy logs]:LOGFILE:_files' \ - '(-m)'-m+'[Scan multiple targets enlisted in a given textual file]:BULKFILE:_files' \ - '(-r)'-r+'[Load HTTP request from a file]:REQUESTFILE:_files' \ - '(-s)'-s+'[Load session from a stored (.sqlite) file]:SESSIONFILE:_files' \ - '(-c)'-c+'[Load options from a configuration INI file]:CONFIGFILE:_files' \ - '(--param-del)'--param-del=-'[Character used for splitting parameter values]:PDEL' \ - '(--cookie)'--cookie=-'[HTTP Cookie header]:COOKIE' \ - '(--load-cookies)'--load-cookies=-'[File containing cookies in Netscape/wget format]:COOKIEFILE:_files' \ - '(--drop-set-cookie)'--drop-set-cookie'[Ignore Set-Cookie header from response]' \ - '(--user-agent)'--user-agent=-'[HTTP User-Agent header]:HTTP User Agent' \ - '(--random-agent)'--random-agent'[Use randomly selected HTTP User-Agent header]' \ - '(--randomize)'--randomize=-'[Randomly change value for given parameter(s)]:RPARAM' \ - '(--force-ssl)'--force-ssl'[Force usage of SSL/HTTPS requests]' \ - '(--host)'--host=-'[HTTP Host header]:Host Header' \ - '(--referer)'--referer=-'[HTTP Referer header]:REFERER' \ - '(--headers)'--headers=-'[Extra headers (e.g. Accept-Language: fr\nETag: 123)]:HEADERS' \ - '(--auth-type)'--auth-type=-'[HTTP authentication type (Basic, Digest or NTLM)]:ATYPE' \ - '(--auth-cred)'--auth-cred=-'[HTTP authentication credentials (name:password)]:ACRED' \ - '(--auth-cert)'--auth-cert=-'[HTTP authentication certificate (key_file,cert_file)]:ACERT:_files' \ - '(--proxy)'--proxy=-'[Use a HTTP proxy to connect to the target url]:PROXY' \ - '(--proxy-cred)'--proxy-cred=-'[HTTP proxy authentication credentials (name:password)]:PCRED' \ - '(--ignore-proxy)'--ignore-proxy'[Ignore system default HTTP proxy]' \ - '(--delay)'--delay=-'[Delay in seconds between each HTTP request]:DELAY' \ - '(--timeout)'--timeout=-'[Seconds to wait before timeout connection (default 30)]:TIMEOUT' \ - '(--retries)'--retries=-'[Retries when the connection timeouts (default 3)]:RETRIES' \ - '(--scope)'--scope=-'[Regexp to filter targets from provided proxy log]:SCOPE' \ - '(--safe-url)'--safe-url=-'[Url address to visit frequently during testing]:SAFURL' \ - '(--safe-freq)'--safe-freq=-'[Test requests between two visits to a given safe url]:SAFREQ' \ - '(--skip-urlencode)'--skip-urlencode'[Skip URL encoding of payload data]' \ - '(--eval)'--eval=-'[Evaluate provided Python code before the request (e.g.]:EVALCODE' \ - '(-o)'-o'[Turn on all optimization switches]' \ - '(--predict-output)'--predict-output'[Predict common queries output]' \ - '(--keep-alive)'--keep-alive'[Use persistent HTTP(s) connections]' \ - '(--null-connection)'--null-connection'[Retrieve page length without actual HTTP response body]' \ - '(--threads)'--threads=-'[Max number of concurrent HTTP(s) requests (default 1)]:THREADS' \ - '(-p)'-p+'[Testable parameter(s)]:TESTPARAMETER' \ - '(--dbms)'--dbms=-'[Force back-end DBMS to this value]:DBMS:->list-dbms' \ - '(--os)'--os=-'[Force back-end DBMS operating system to this value]:OS:->list-os' \ - '(--invalid-bignum)'--invalid-bignum'[Use big numbers for invalidating values]' \ - '(--invalid-logical)'--invalid-logical'[Use logical operations for invalidating values]' \ - '(--no-cast)'--no-cast'[Turn off payload casting mechanism]' \ - '(--no-escape)'--no-unescape'[Turn off string escaping mechanism]' \ - '(--prefix)'--prefix=-'[Injection payload prefix string]:PREFIX' \ - '(--suffix)'--suffix=-'[Injection payload suffix string]:SUFFIX' \ - '(--skip)'--skip=-'[Skip testing for given parameter(s)]:SKIP' \ - '(--tamper)'--tamper=-'[Use given script(s) for tampering injection data]:TAMPER' \ - '(--level)'--level=-'[Level of tests to perform (1-5, default 1)]:LEVEL (1-5), default 1' \ - '(--risk)'--risk=-'[Risk of tests to perform (0-3, default 1)]:RISK (0-3), default 1' \ - '(--string)'--string=-'[String to match when query is evaluated to True]:STRING' \ - '(--not-string)'--not-string=-'[String to match when query is evaluated to False]:NOTSTRING' \ - '(--regexp)'--regexp=-'[Regexp to match when query is evaluated to True]:REGEXP' \ - '(--code)'--code=-'[HTTP code to match when query is evaluated to True]' \ - '(--text-only)'--text-only'[Compare pages based only on the textual content]' \ - '(--titles)'--titles'[Compare pages based only on their titles]' \ - '(--technique)'--technique=-'[SQL injection techniques to test for (default "BEUSTQ")]:TECH:->list-techniques' \ - '(--time-sec)'--time-sec=-'[Seconds to delay the DBMS response (default 5)]:TIMESEC' \ - '(--union-cols)'--union-cols=-'[Range of columns to test for UNION query SQL injection]:UCOLS' \ - '(--union-char)'--union-char=-'[Character to use for bruteforcing number of columns]:UCHAR' \ - '(--dns-domain)'--dns-domain=-'[Domain name used for DNS exfiltration attack]:DNSDOMAIN' \ - '(--second-order)'--second-order=-'[Resulting page url searched for second-order response]:SECONDORDER' \ - '(-f,--fingerprint)'{-f,--fingerprint}'[Perform an extensive DBMS version fingerprint]' \ - '(-a,--all)'{-a,--all}'[Retrieve everything]' \ - '(-b,--banner)'{-b,--banner}'[Retrieve DBMS banner]' \ - '(--current-user)'--current-user'[Retrieve DBMS current user]' \ - '(--current-db)'--current-db'[Retrieve DBMS current database]' \ - '(--hostname)'--hostname'[Retrieve DBMS server hostname]' \ - '(--is-dba)'--is-dba'[Detect if the DBMS current user is DBA]' \ - '(--users)'--users'[Enumerate DBMS users]' \ - '(--passwords)'--passwords'[Enumerate DBMS users password hashes]' \ - '(--privileges)'--privileges'[Enumerate DBMS users privileges]' \ - '(--roles)'--roles'[Enumerate DBMS users roles]' \ - '(--dbs)'--dbs'[Enumerate DBMS databases]' \ - '(--tables)'--tables'[Enumerate DBMS database tables]' \ - '(--columns)'--columns'[Enumerate DBMS database table columns]' \ - '(--schema)'--schema'[Enumerate DBMS schema]' \ - '(--count)'--count'[Retrieve number of entries for table(s)]' \ - '(--dump)'--dump'[Dump DBMS database table entries]' \ - '(--dump-all)'--dump-all'[Dump all DBMS databases tables entries]' \ - '(--search)'--search'[Search column(s), table(s) and/or database name(s)]' \ - '(-D)'-D+'[DBMS database to enumerate]:DB' \ - '(-T)'-T+'[DBMS database table to enumerate]:TBL' \ - '(-C)'-C+'[DBMS database table column to enumerate]:COL' \ - '(-U)'-U+'[DBMS user to enumerate]:USER' \ - '(--exclude-sysdbs)'--exclude-sysdbs'[Exclude DBMS system databases when enumerating tables]' \ - '(--start)'--start=-'[First query output entry to retrieve]:LIMITSTART' \ - '(--stop)'--stop=-'[Last query output entry to retrieve]:LIMITSTOP' \ - '(--first)'--first=-'[First query output word character to retrieve]:FIRSTCHAR' \ - '(--last)'--last=-'[Last query output word character to retrieve]:LASTCHAR' \ - '(--sql-query)'--sql-query=-'[SQL statement to be executed]:QUERY' \ - '(--sql-shell)'--sql-shell'[Prompt for an interactive SQL shell]' \ - '(--sql-file)'--sql-file=-'[Execute SQL statements from given file(s)]:SQLFILE:_files' \ - '(--common-tables)'--common-tables'[Check existence of common tables]' \ - '(--common-columns)'--common-columns'[Check existence of common columns]' \ - '(--udf-inject)'--udf-inject'[Inject custom user-defined functions]' \ - '(--shared-lib)'--shared-lib=-'[Local path of the shared library]:SHLIB' \ - '(--file-read)'--file-read=-'[Read a file from the back-end DBMS file system]:RFILE' \ - '(--file-write)'--file-write=-'[Write a local file on the back-end DBMS file system]:WFILE' \ - '(--file-dest)'--file-dest=-'[Back-end DBMS absolute filepath to write to]:DFILE' \ - '(--os-cmd)'--os-cmd=-'[Execute an operating system command]:OSCMD' \ - '(--os-shell)'--os-shell'[Prompt for an interactive operating system shell]' \ - '(--os-pwn)'--os-pwn'[Prompt for an out-of-band shell, meterpreter or VNC]' \ - '(--os-smbrelay)'--os-smbrelay'[One click prompt for an OOB shell, meterpreter or VNC]' \ - '(--os-bof)'--os-bof'[Stored procedure buffer overflow exploitation]' \ - '(--priv-esc)'--priv-esc'[Database process user privilege escalation]' \ - '(--msf-path)'--msf-path=-'[Local path where Metasploit Framework is installed]:MSFPATH' \ - '(--tmp-path)'--tmp-path=-'[Remote absolute path of temporary files directory]:TMPPATH' \ - '(--reg-read)'--reg-read'[Read a Windows registry key value]' \ - '(--reg-add)'--reg-add'[Write a Windows registry key value data]' \ - '(--reg-del)'--reg-del'[Delete a Windows registry key value]' \ - '(--reg-key)'--reg-key=-'[Windows registry key]:REGKEY' \ - '(--reg-value)'--reg-value=-'[Windows registry key value]:REGVAL' \ - '(--reg-data)'--reg-data=-'[Windows registry key value data]:REGDATA' \ - '(--reg-type)'--reg-type=-'[Windows registry key value type]:REGTYPE' \ - '(-t)'-t+'[Log all HTTP traffic into a textual file]:TRAFFICFILE' \ - '(--batch)'--batch'[Never ask for user input, use the default behaviour]' \ - '(--charset)'--charset=-'[Force character encoding used for data retrieval]:CHARSET' \ - '(--check-tor)'--check-tor'[Check to see if Tor is used properly]' \ - '(--crawl)'--crawl=-'[Crawl the website starting from the target url]:CRAWLDEPTH' \ - '(--csv-del)'--csv-del=-'[Delimiting character used in CSV output (default is ,)]:CSVDEL' \ - '(--dbms-cred)'--dbms-cred=-'[DBMS authentication credentials (user:password)]:DBMS authentication credentials' \ - '(--eta)'--eta'[Display for each output the estimated time of arrival]' \ - '(--flush-session)'--flush-session'[Flush session files for current target]' \ - '(--forms)'--forms'[Parse and test forms on target url]' \ - '(--fresh-queries)'--fresh-queries'[Ignores query results stored in session file]' \ - '(--hex)'--hex'[Uses DBMS hex function(s) for data retrieval]' \ - '(--output-dir)'--output-dir=-'[Custom output directory path]:ODIR' \ - '(--parse-errors)'--parse-errors'[Parse and display DBMS error messages from responses]' \ - '(--save)'--save'[Save options to a configuration INI file]' \ - '(--tor)'--tor'[Use Tor anonymity network]' \ - '(--tor-port)'--tor-port=-'[Set Tor proxy port other than default]:TORPORT' \ - '(--tor-type)'--tor-type=-'[Set Tor proxy type (HTTP - default, SOCKS4 or SOCKS5)]:TORTYPE' \ - '(--update)'--update'[Update sqlmap]' \ - '(-z)'-z+'[Use short mnemonics (e.g. flu,bat,ban,tec=EU)]:MNEMONICS' \ - '(--check-payload)'--check-payload'[Offline WAF/IPS/IDS payload detection testing]' \ - '(--check-waf)'--check-waf'[Check for existence of WAF/IPS/IDS protection]' \ - '(--cleanup)'--cleanup'[Clean up the DBMS by sqlmap specific UDF and tables]' \ - '(--dependencies)'--dependencies'[Check for missing (non-core) sqlmap dependencies]' \ - '(--disable-coloring)'--disable-coloring'[Disable console output coloring]' \ - '(--gpage)'--gpage=-'[Use Google dork results from specified page number]:GOOGLEPAGE' \ - '(--mobile)'--mobile'[Imitate smartphone through HTTP User-Agent header]' \ - '(--page-rank)'--page-rank'[Display page rank (PR) for Google dork results]' \ - '(--purge-output)'--purge-output'[Safely remove all content from output directory]' \ - '(--smart)'--smart'[Conduct through tests only if positive heuristic(s)]' \ - '(--test-filter)'--test-filter=-'[Select tests by payloads and/or titles (e.g. ROW)]:test-filter' \ - '(--wizard)'--wizard'[Simple wizard interface for beginner users]' && return 0 - -case "$state" in - list-dbms) - _values -S : 'DBMS' 'access' 'db2' 'firebird' 'maxdb' 'mssqlserver' 'mysql' 'oracle' 'postgresql' \ - 'sqlite' 'sybase' - ;; - list-os) - _values -S : 'os' 'Linux' 'Windows' - ;; - list-techniques) - _values -S : 'technique' \ - 'B[Boolean]' 'E[Error]' 'U[Union]' 'S[Stacked]' 'T[Time]' - ;; -esac - -return 0 diff --git a/lib/core/enums.py b/lib/core/enums.py index ad4ad1ea6..325643b9e 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -323,4 +323,4 @@ class AUTH_TYPE: BASIC = "basic" DIGEST = "digest" NTLM = "ntlm" - CERT = "cert" + PKI = "pki" diff --git a/lib/core/option.py b/lib/core/option.py index e56e50cb0..0f535e216 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -27,6 +27,7 @@ import lib.request.connect from lib.controller.checks import checkConnection from lib.core.common import Backend from lib.core.common import boldifyMessage +from lib.core.common import checkFile from lib.core.common import dataToStdout from lib.core.common import getPublicTypeMembers from lib.core.common import extractRegexResult @@ -133,8 +134,8 @@ from lib.request.basic import checkCharEncoding from lib.request.connect import Connect as Request from lib.request.dns import DNSServer from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler -from lib.request.certhandler import HTTPSCertAuthHandler from lib.request.httpshandler import HTTPSHandler +from lib.request.pkihandler import HTTPSPKIAuthHandler from lib.request.rangehandler import HTTPRangeHandler from lib.request.redirecthandler import SmartRedirectHandler from lib.request.templates import getPageTemplate @@ -1102,17 +1103,17 @@ def _setAuthCred(): def _setHTTPAuthentication(): """ - Check and set the HTTP(s) authentication method (Basic, Digest, NTLM or Certificate), - username and password for first three methods, or key file and certification file for - certificate authentication + Check and set the HTTP(s) authentication method (Basic, Digest, NTLM or PKI), + username and password for first three methods, or PEM private key file for + PKI authentication """ global authHandler - if not conf.authType and not conf.authCred and not conf.authCert: + if not conf.authType and not conf.authCred and not conf.authPrivate: return - elif conf.authType and not conf.authCred and not conf.authCert: + elif conf.authType and not conf.authCred and not conf.authPrivate: errMsg = "you specified the HTTP authentication type, but " errMsg += "did not provide the credentials" raise SqlmapSyntaxException(errMsg) @@ -1122,15 +1123,15 @@ def _setHTTPAuthentication(): errMsg += "but did not provide the type" raise SqlmapSyntaxException(errMsg) - if not conf.authCert: + if not conf.authPrivate: debugMsg = "setting the HTTP authentication type and credentials" logger.debug(debugMsg) aTypeLower = conf.authType.lower() - if aTypeLower not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.NTLM, AUTH_TYPE.CERT): + if aTypeLower not in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST, AUTH_TYPE.NTLM, AUTH_TYPE.PKI): errMsg = "HTTP authentication type value must be " - errMsg += "Basic, Digest, NTLM or Cert" + errMsg += "Basic, Digest, NTLM or PKI" raise SqlmapSyntaxException(errMsg) elif aTypeLower in (AUTH_TYPE.BASIC, AUTH_TYPE.DIGEST): regExp = "^(.*?):(.*?)$" @@ -1140,9 +1141,9 @@ def _setHTTPAuthentication(): regExp = "^(.*\\\\.*):(.*?)$" errMsg = "HTTP NTLM authentication credentials value must " errMsg += "be in format 'DOMAIN\username:password'" - elif aTypeLower == AUTH_TYPE.CERT: - errMsg = "HTTP Cert authentication require " - errMsg += "usage of option `--auth-cert`" + elif aTypeLower == AUTH_TYPE.PKI: + errMsg = "HTTP PKI authentication require " + errMsg += "usage of option `--auth-pki`" raise SqlmapSyntaxException(errMsg) aCredRegExp = re.search(regExp, conf.authCred) @@ -1174,26 +1175,12 @@ def _setHTTPAuthentication(): authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(kb.passwordMgr) else: - debugMsg = "setting the HTTP(s) authentication certificate" + debugMsg = "setting the HTTP(s) authentication PEM private key" logger.debug(debugMsg) - aCertRegExp = re.search("^(.+?),\s*(.+?)$", conf.authCert) - - if not aCertRegExp: - errMsg = "HTTP authentication certificate option " - errMsg += "must be in format 'key_file,cert_file'" - raise SqlmapSyntaxException(errMsg) - - # os.path.expanduser for support of paths with ~ - key_file = os.path.expanduser(aCertRegExp.group(1)) - cert_file = os.path.expanduser(aCertRegExp.group(2)) - - for ifile in (key_file, cert_file): - if not os.path.exists(ifile): - errMsg = "file '%s' does not exist" % ifile - raise SqlmapSyntaxException(errMsg) - - authHandler = HTTPSCertAuthHandler(key_file, cert_file) + key_file = os.path.expanduser(conf.authPrivate) + checkFile(key_file) + authHandler = HTTPSPKIAuthHandler(key_file) def _setHTTPMethod(): """ diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 055fab75d..86a222219 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -35,7 +35,7 @@ optDict = { "headers": "string", "authType": "string", "authCred": "string", - "authCert": "string", + "authPrivate": "string", "proxy": "string", "proxyCred": "string", "proxyFile": "string", diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index b8a78fb24..e86620f47 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -117,15 +117,14 @@ def cmdLineParser(): request.add_option("--auth-type", dest="authType", help="HTTP authentication type " - "(Basic, Digest, NTLM or Cert)") + "(Basic, Digest, NTLM or PKI)") request.add_option("--auth-cred", dest="authCred", help="HTTP authentication credentials " "(name:password)") - request.add_option("--auth-cert", dest="authCert", - help="HTTP authentication certificate (" - "key_file,cert_file)") + request.add_option("--auth-private", dest="authPrivate", + help="HTTP authentication PEM private key file") request.add_option("--proxy", dest="proxy", help="Use a proxy to connect to the target URL") diff --git a/lib/request/certhandler.py b/lib/request/pkihandler.py similarity index 72% rename from lib/request/certhandler.py rename to lib/request/pkihandler.py index 57dae6b23..79adbc55c 100644 --- a/lib/request/certhandler.py +++ b/lib/request/pkihandler.py @@ -10,14 +10,13 @@ import urllib2 from lib.core.data import conf -class HTTPSCertAuthHandler(urllib2.HTTPSHandler): - def __init__(self, key_file, cert_file): +class HTTPSPKIAuthHandler(urllib2.HTTPSHandler): + def __init__(self, key_file): urllib2.HTTPSHandler.__init__(self) self.key_file = key_file - self.cert_file = cert_file def https_open(self, req): return self.do_open(self.getConnection, req) def getConnection(self, host, timeout=None): - return httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file, timeout=conf.timeout) + return httplib.HTTPSConnection(host, key_file=self.key_file, timeout=conf.timeout) diff --git a/sqlmap.conf b/sqlmap.conf index 194046da2..049650ba1 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -78,7 +78,7 @@ headers = Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9 # HTTP Authentication type. Useful only if the target URL requires # HTTP Basic, Digest or NTLM authentication and you have such data. -# Valid: Basic, Digest, NTLM or Cert +# Valid: Basic, Digest, NTLM or PKI authType = # HTTP authentication credentials. Useful only if the target URL requires @@ -86,10 +86,10 @@ authType = # Syntax: username:password authCred = -# HTTP Authentication certificate. Useful only if the target URL requires -# logon certificate and you have such data. -# Syntax: key_file,cert_file -authCert = +# HTTP Authentication PEM private key. Useful only if the target URL requires +# PKI authentication and you have such data. +# Syntax: key_file +authPrivate = # Use a proxy to connect to the target URL. # Syntax: http://address:port