mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 17:46:37 +03:00
Minor style update (for the sake of consistency over the code and our PEP8 adaptation)
This commit is contained in:
parent
bdd2592848
commit
25f01a419f
|
@ -113,7 +113,7 @@ def _selectInjection():
|
||||||
|
|
||||||
if select.isdigit() and int(select) < len(kb.injections) and int(select) >= 0:
|
if select.isdigit() and int(select) < len(kb.injections) and int(select) >= 0:
|
||||||
index = int(select)
|
index = int(select)
|
||||||
elif select[0] in ( "Q", "q" ):
|
elif select[0] in ("Q", "q"):
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapUserQuitException
|
||||||
else:
|
else:
|
||||||
errMsg = "invalid choice"
|
errMsg = "invalid choice"
|
||||||
|
|
|
@ -855,13 +855,13 @@ class Agent(object):
|
||||||
else:
|
else:
|
||||||
query = expression
|
query = expression
|
||||||
|
|
||||||
if ( select and re.search("\A(COUNT|LTRIM)\(", query, re.I) ) or len(query) <= 1:
|
if (select and re.search("\A(COUNT|LTRIM)\(", query, re.I)) or len(query) <= 1:
|
||||||
return query
|
return query
|
||||||
|
|
||||||
if selectDistinctExpr:
|
if selectDistinctExpr:
|
||||||
lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % query, expression)
|
lengthExpr = "SELECT %s FROM (%s)" % (lengthQuery % query, expression)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
lengthExpr += " AS %s" % randomStr(lowercase=True)
|
lengthExpr += " AS %s" % randomStr(lowercase=True)
|
||||||
elif select:
|
elif select:
|
||||||
lengthExpr = expression.replace(query, lengthQuery % query, 1)
|
lengthExpr = expression.replace(query, lengthQuery % query, 1)
|
||||||
|
|
|
@ -307,7 +307,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
params = True
|
params = True
|
||||||
|
|
||||||
# Avoid proxy and connection type related headers
|
# Avoid proxy and connection type related headers
|
||||||
elif key not in ( HTTPHEADER.PROXY_CONNECTION, HTTPHEADER.CONNECTION ):
|
elif key not in (HTTPHEADER.PROXY_CONNECTION, HTTPHEADER.CONNECTION):
|
||||||
conf.httpHeaders.append((getUnicode(key), getUnicode(value)))
|
conf.httpHeaders.append((getUnicode(key), getUnicode(value)))
|
||||||
|
|
||||||
if getPostReq and (params or cookie):
|
if getPostReq and (params or cookie):
|
||||||
|
@ -1050,11 +1050,11 @@ def _setHTTPAuthentication():
|
||||||
|
|
||||||
aTypeLower = conf.aType.lower()
|
aTypeLower = conf.aType.lower()
|
||||||
|
|
||||||
if aTypeLower not in ( "basic", "digest", "ntlm" ):
|
if aTypeLower not in ("basic", "digest", "ntlm"):
|
||||||
errMsg = "HTTP authentication type value must be "
|
errMsg = "HTTP authentication type value must be "
|
||||||
errMsg += "Basic, Digest or NTLM"
|
errMsg += "Basic, Digest or NTLM"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
elif aTypeLower in ( "basic", "digest" ):
|
elif aTypeLower in ("basic", "digest"):
|
||||||
regExp = "^(.*?):(.*?)$"
|
regExp = "^(.*?):(.*?)$"
|
||||||
errMsg = "HTTP %s authentication credentials " % aTypeLower
|
errMsg = "HTTP %s authentication credentials " % aTypeLower
|
||||||
errMsg += "value must be in format username:password"
|
errMsg += "value must be in format username:password"
|
||||||
|
@ -1715,8 +1715,8 @@ def _saveCmdline():
|
||||||
if value is None:
|
if value is None:
|
||||||
if datatype == "boolean":
|
if datatype == "boolean":
|
||||||
value = "False"
|
value = "False"
|
||||||
elif datatype in ( "integer", "float" ):
|
elif datatype in ("integer", "float"):
|
||||||
if option in ( "threads", "verbose" ):
|
if option in ("threads", "verbose"):
|
||||||
value = "1"
|
value = "1"
|
||||||
elif option == "timeout":
|
elif option == "timeout":
|
||||||
value = "10"
|
value = "10"
|
||||||
|
@ -1839,7 +1839,7 @@ def _setTorHttpProxySettings():
|
||||||
|
|
||||||
found = None
|
found = None
|
||||||
|
|
||||||
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort, )):
|
for port in (DEFAULT_TOR_HTTP_PORTS if not conf.torPort else (conf.torPort,)):
|
||||||
try:
|
try:
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
s.connect((LOCALHOST, port))
|
s.connect((LOCALHOST, port))
|
||||||
|
|
|
@ -38,7 +38,7 @@ uses_libedit = False
|
||||||
if PLATFORM == 'mac' and _readline:
|
if PLATFORM == 'mac' and _readline:
|
||||||
import commands
|
import commands
|
||||||
|
|
||||||
(status, result) = commands.getstatusoutput( "otool -L %s | grep libedit" % _readline.__file__ )
|
(status, result) = commands.getstatusoutput("otool -L %s | grep libedit" % _readline.__file__)
|
||||||
|
|
||||||
if status == 0 and len(result) > 0:
|
if status == 0 and len(result) > 0:
|
||||||
# We are bound to libedit - new in Leopard
|
# We are bound to libedit - new in Leopard
|
||||||
|
|
|
@ -131,43 +131,43 @@ PLATFORM = os.name
|
||||||
PYVERSION = sys.version.split()[0]
|
PYVERSION = sys.version.split()[0]
|
||||||
|
|
||||||
# Database management system specific variables
|
# Database management system specific variables
|
||||||
MSSQL_SYSTEM_DBS = ( "Northwind", "master", "model", "msdb", "pubs", "tempdb" )
|
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
|
||||||
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
|
MYSQL_SYSTEM_DBS = ("information_schema", "mysql") # Before MySQL 5.0 only "mysql"
|
||||||
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
|
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast")
|
||||||
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX", "SYS" ) # These are TABLESPACE_NAME
|
ORACLE_SYSTEM_DBS = ("SYSTEM", "SYSAUX", "SYS") # These are TABLESPACE_NAME
|
||||||
SQLITE_SYSTEM_DBS = ( "sqlite_master", "sqlite_temp_master" )
|
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
|
||||||
ACCESS_SYSTEM_DBS = ( "MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
|
ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage",\
|
||||||
"MSysAccessXML", "MSysModules", "MSysModules2" )
|
"MSysAccessXML", "MSysModules", "MSysModules2")
|
||||||
FIREBIRD_SYSTEM_DBS = ( "RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
|
FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE",\
|
||||||
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
|
"RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS",\
|
||||||
"RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\
|
"RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES",\
|
||||||
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
|
"RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS",\
|
||||||
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
|
"RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS",\
|
||||||
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS" )
|
"RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS")
|
||||||
MAXDB_SYSTEM_DBS = ( "SYSINFO", "DOMAIN" )
|
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",\
|
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS",\
|
||||||
"SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS" )
|
"SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||||
|
|
||||||
MSSQL_ALIASES = ( "microsoft sql server", "mssqlserver", "mssql", "ms" )
|
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||||
MYSQL_ALIASES = ( "mysql", "my" )
|
MYSQL_ALIASES = ("mysql", "my")
|
||||||
PGSQL_ALIASES = ( "postgresql", "postgres", "pgsql", "psql", "pg" )
|
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg")
|
||||||
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 = ("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")
|
||||||
|
|
||||||
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
|
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES
|
||||||
SUPPORTED_OS = ( "linux", "windows" )
|
SUPPORTED_OS = ("linux", "windows")
|
||||||
|
|
||||||
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",)
|
||||||
|
|
||||||
# Items displayed in basic help (-h) output
|
# Items displayed in basic help (-h) output
|
||||||
BASIC_HELP_ITEMS = (
|
BASIC_HELP_ITEMS = (
|
||||||
|
|
|
@ -39,7 +39,7 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
def _feedInfo(self, key, value):
|
def _feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
|
||||||
if value in ( None, "None" ):
|
if value in (None, "None"):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._info[key] = value
|
self._info[key] = value
|
||||||
|
|
|
@ -29,7 +29,7 @@ class FingerprintHandler(ContentHandler):
|
||||||
def _feedInfo(self, key, value):
|
def _feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
|
||||||
if value in ( None, "None" ):
|
if value in (None, "None"):
|
||||||
return
|
return
|
||||||
|
|
||||||
if key == "dbmsVersion":
|
if key == "dbmsVersion":
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
self.webBackdoorRunCmd(cmd)
|
self.webBackdoorRunCmd(cmd)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
self.udfExecCmd(cmd, silent=silent)
|
self.udfExecCmd(cmd, silent=silent)
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
|
@ -57,7 +57,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
|
||||||
retVal = self.webBackdoorRunCmd(cmd)
|
retVal = self.webBackdoorRunCmd(cmd)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
retVal = self.udfEvalCmd(cmd, first, last)
|
retVal = self.udfEvalCmd(cmd, first, last)
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
|
@ -97,7 +97,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
infoMsg = "going to use injected sys_eval and sys_exec "
|
infoMsg = "going to use injected sys_eval and sys_exec "
|
||||||
infoMsg += "user-defined functions for operating system "
|
infoMsg += "user-defined functions for operating system "
|
||||||
infoMsg += "command execution"
|
infoMsg += "command execution"
|
||||||
|
@ -136,7 +136,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
if not command:
|
if not command:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if command.lower() in ( "x", "q", "exit", "quit" ):
|
if command.lower() in ("x", "q", "exit", "quit"):
|
||||||
break
|
break
|
||||||
|
|
||||||
self.runCmd(command)
|
self.runCmd(command)
|
||||||
|
@ -186,7 +186,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
warnMsg = "functionality requested probably does not work because "
|
warnMsg = "functionality requested probably does not work because "
|
||||||
warnMsg += "the curent session user is not a database administrator"
|
warnMsg += "the curent session user is not a database administrator"
|
||||||
|
|
||||||
if not conf.dbmsCred and Backend.getIdentifiedDbms() in ( DBMS.MSSQL, DBMS.PGSQL ):
|
if not conf.dbmsCred and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.PGSQL):
|
||||||
warnMsg += ". You can try to use option '--dbms-cred' "
|
warnMsg += ". You can try to use option '--dbms-cred' "
|
||||||
warnMsg += "to execute statements as a DBA user if you "
|
warnMsg += "to execute statements as a DBA user if you "
|
||||||
warnMsg += "were able to extract and crack a DBA "
|
warnMsg += "were able to extract and crack a DBA "
|
||||||
|
@ -194,7 +194,7 @@ class Abstraction(Web, UDF, Xp_cmdshell):
|
||||||
|
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
self.udfInjectSys()
|
self.udfInjectSys()
|
||||||
elif Backend.isDbms(DBMS.MSSQL):
|
elif Backend.isDbms(DBMS.MSSQL):
|
||||||
if mandatory:
|
if mandatory:
|
||||||
|
|
|
@ -66,52 +66,52 @@ class Metasploit:
|
||||||
|
|
||||||
self._msfPayloadsList = {
|
self._msfPayloadsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "Meterpreter (default)", "windows/meterpreter" ),
|
1: ("Meterpreter (default)", "windows/meterpreter"),
|
||||||
2: ( "Shell", "windows/shell" ),
|
2: ("Shell", "windows/shell"),
|
||||||
3: ( "VNC", "windows/vncinject" ),
|
3: ("VNC", "windows/vncinject"),
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
1: ( "Shell (default)", "linux/x86/shell" ),
|
1: ("Shell (default)", "linux/x86/shell"),
|
||||||
2: ( "Meterpreter (beta)", "linux/x86/meterpreter" ),
|
2: ("Meterpreter (beta)", "linux/x86/meterpreter"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfConnectionsList = {
|
self._msfConnectionsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp" ),
|
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
|
||||||
2: ( "Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535", "reverse_tcp_allports" ),
|
2: ("Reverse TCP: Try to connect back from the database host to this machine, on all ports between the specified and 65535", "reverse_tcp_allports"),
|
||||||
3: ( "Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP", "reverse_http" ),
|
3: ("Reverse HTTP: Connect back from the database host to this machine tunnelling traffic over HTTP", "reverse_http"),
|
||||||
4: ( "Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS", "reverse_https" ),
|
4: ("Reverse HTTPS: Connect back from the database host to this machine tunnelling traffic over HTTPS", "reverse_https"),
|
||||||
5: ( "Bind TCP: Listen on the database host for a connection", "bind_tcp" )
|
5: ("Bind TCP: Listen on the database host for a connection", "bind_tcp")
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
1: ( "Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp" ),
|
1: ("Reverse TCP: Connect back from the database host to this machine (default)", "reverse_tcp"),
|
||||||
2: ( "Bind TCP: Listen on the database host for a connection", "bind_tcp" ),
|
2: ("Bind TCP: Listen on the database host for a connection", "bind_tcp"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfEncodersList = {
|
self._msfEncodersList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "No Encoder", "generic/none" ),
|
1: ("No Encoder", "generic/none"),
|
||||||
2: ( "Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed" ),
|
2: ("Alpha2 Alphanumeric Mixedcase Encoder", "x86/alpha_mixed"),
|
||||||
3: ( "Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper" ),
|
3: ("Alpha2 Alphanumeric Uppercase Encoder", "x86/alpha_upper"),
|
||||||
4: ( "Avoid UTF8/tolower", "x86/avoid_utf8_tolower" ),
|
4: ("Avoid UTF8/tolower", "x86/avoid_utf8_tolower"),
|
||||||
5: ( "Call+4 Dword XOR Encoder", "x86/call4_dword_xor" ),
|
5: ("Call+4 Dword XOR Encoder", "x86/call4_dword_xor"),
|
||||||
6: ( "Single-byte XOR Countdown Encoder", "x86/countdown" ),
|
6: ("Single-byte XOR Countdown Encoder", "x86/countdown"),
|
||||||
7: ( "Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov" ),
|
7: ("Variable-length Fnstenv/mov Dword XOR Encoder", "x86/fnstenv_mov"),
|
||||||
8: ( "Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive" ),
|
8: ("Polymorphic Jump/Call XOR Additive Feedback Encoder", "x86/jmp_call_additive"),
|
||||||
9: ( "Non-Alpha Encoder", "x86/nonalpha" ),
|
9: ("Non-Alpha Encoder", "x86/nonalpha"),
|
||||||
10: ( "Non-Upper Encoder", "x86/nonupper" ),
|
10: ("Non-Upper Encoder", "x86/nonupper"),
|
||||||
11: ( "Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai" ),
|
11: ("Polymorphic XOR Additive Feedback Encoder (default)", "x86/shikata_ga_nai"),
|
||||||
12: ( "Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed" ),
|
12: ("Alpha2 Alphanumeric Unicode Mixedcase Encoder", "x86/unicode_mixed"),
|
||||||
13: ( "Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper" ),
|
13: ("Alpha2 Alphanumeric Unicode Uppercase Encoder", "x86/unicode_upper"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._msfSMBPortsList = {
|
self._msfSMBPortsList = {
|
||||||
"windows": {
|
"windows": {
|
||||||
1: ( "139/TCP", "139" ),
|
1: ("139/TCP", "139"),
|
||||||
2: ( "445/TCP (default)", "445" ),
|
2: ("445/TCP (default)", "445"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ class Metasploit:
|
||||||
|
|
||||||
self._runMsfCliSmbrelay()
|
self._runMsfCliSmbrelay()
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self._randFile)
|
self.uncPath = "\\\\\\\\%s\\\\%s" % (self.lhostStr, self._randFile)
|
||||||
else:
|
else:
|
||||||
self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self._randFile)
|
self.uncPath = "\\\\%s\\%s" % (self.lhostStr, self._randFile)
|
||||||
|
|
|
@ -112,7 +112,7 @@ class UDF:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def udfCheckNeeded(self):
|
def udfCheckNeeded(self):
|
||||||
if ( not conf.rFile or ( conf.rFile and not Backend.isDbms(DBMS.PGSQL) ) ) and "sys_fileread" in self.sysUdfs:
|
if (not conf.rFile or (conf.rFile and not Backend.isDbms(DBMS.PGSQL))) and "sys_fileread" in self.sysUdfs:
|
||||||
self.sysUdfs.pop("sys_fileread")
|
self.sysUdfs.pop("sys_fileread")
|
||||||
|
|
||||||
if not conf.osPwn:
|
if not conf.osPwn:
|
||||||
|
@ -164,7 +164,7 @@ class UDF:
|
||||||
self.udfInjectCore(self.sysUdfs)
|
self.udfInjectCore(self.sysUdfs)
|
||||||
|
|
||||||
def udfInjectCustom(self):
|
def udfInjectCustom(self):
|
||||||
if Backend.getIdentifiedDbms() not in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() not in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
errMsg = "UDF injection feature is not yet implemented on %s" % Backend.getIdentifiedDbms()
|
errMsg = "UDF injection feature is not yet implemented on %s" % Backend.getIdentifiedDbms()
|
||||||
raise SqlmapUnsupportedFeatureException(errMsg)
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
@ -300,10 +300,10 @@ class UDF:
|
||||||
msg += "functions now? [Y/n/q] "
|
msg += "functions now? [Y/n/q] "
|
||||||
choice = readInput(msg, default="Y")
|
choice = readInput(msg, default="Y")
|
||||||
|
|
||||||
if choice[0] in ( "n", "N" ):
|
if choice[0] in ("n", "N"):
|
||||||
self.cleanup(udfDict=self.udfs)
|
self.cleanup(udfDict=self.udfs)
|
||||||
return
|
return
|
||||||
elif choice[0] in ( "q", "Q" ):
|
elif choice[0] in ("q", "Q"):
|
||||||
self.cleanup(udfDict=self.udfs)
|
self.cleanup(udfDict=self.udfs)
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapUserQuitException
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ class UDF:
|
||||||
while True:
|
while True:
|
||||||
choice = readInput(msg)
|
choice = readInput(msg)
|
||||||
|
|
||||||
if choice and choice[0] in ( "q", "Q" ):
|
if choice and choice[0] in ("q", "Q"):
|
||||||
break
|
break
|
||||||
elif isinstance(choice, basestring) and choice.isdigit() and int(choice) > 0 and int(choice) <= len(udfList):
|
elif isinstance(choice, basestring) and choice.isdigit() and int(choice) > 0 and int(choice) <= len(udfList):
|
||||||
choice = int(choice)
|
choice = int(choice)
|
||||||
|
|
|
@ -86,20 +86,20 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
firstChar = len(partialValue)
|
firstChar = len(partialValue)
|
||||||
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
|
elif "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
|
||||||
firstChar = 0
|
firstChar = 0
|
||||||
elif dump and conf.firstChar is not None and ( isinstance(conf.firstChar, int) or ( isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit() ) ):
|
elif dump and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (isinstance(conf.firstChar, basestring) and conf.firstChar.isdigit())):
|
||||||
firstChar = int(conf.firstChar) - 1
|
firstChar = int(conf.firstChar) - 1
|
||||||
elif firstChar is None:
|
elif firstChar is None:
|
||||||
firstChar = 0
|
firstChar = 0
|
||||||
elif ( isinstance(firstChar, basestring) and firstChar.isdigit() ) or isinstance(firstChar, int):
|
elif (isinstance(firstChar, basestring) and firstChar.isdigit()) or isinstance(firstChar, int):
|
||||||
firstChar = int(firstChar) - 1
|
firstChar = int(firstChar) - 1
|
||||||
|
|
||||||
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
|
if "LENGTH(" in expression.upper() or "LEN(" in expression.upper():
|
||||||
lastChar = 0
|
lastChar = 0
|
||||||
elif dump and conf.lastChar is not None and ( isinstance(conf.lastChar, int) or ( isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit() ) ):
|
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (isinstance(conf.lastChar, basestring) and conf.lastChar.isdigit())):
|
||||||
lastChar = int(conf.lastChar)
|
lastChar = int(conf.lastChar)
|
||||||
elif lastChar in ( None, "0" ):
|
elif lastChar in (None, "0"):
|
||||||
lastChar = 0
|
lastChar = 0
|
||||||
elif ( isinstance(lastChar, basestring) and lastChar.isdigit() ) or isinstance(lastChar, int):
|
elif (isinstance(lastChar, basestring) and lastChar.isdigit()) or isinstance(lastChar, int):
|
||||||
lastChar = int(lastChar)
|
lastChar = int(lastChar)
|
||||||
|
|
||||||
if Backend.getDbms():
|
if Backend.getDbms():
|
||||||
|
@ -332,7 +332,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def etaProgressUpdate(charTime, index):
|
def etaProgressUpdate(charTime, index):
|
||||||
if len(progressTime) <= ( (length * 3) / 100 ):
|
if len(progressTime) <= ((length * 3) / 100):
|
||||||
eta = 0
|
eta = 0
|
||||||
else:
|
else:
|
||||||
midTime = sum(progressTime) / len(progressTime)
|
midTime = sum(progressTime) / len(progressTime)
|
||||||
|
@ -507,7 +507,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
else:
|
else:
|
||||||
val = getChar(index, asciiTbl)
|
val = getChar(index, asciiTbl)
|
||||||
|
|
||||||
if val is None or ( lastChar > 0 and index > lastChar ):
|
if val is None or (lastChar > 0 and index > lastChar):
|
||||||
finalValue = partialValue
|
finalValue = partialValue
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
if conf.verbose in (1, 2) or showEta:
|
if conf.verbose in (1, 2) or showEta:
|
||||||
dataToStdout("\n")
|
dataToStdout("\n")
|
||||||
|
|
||||||
if ( conf.verbose in ( 1, 2 ) and showEta ) or conf.verbose >= 3:
|
if (conf.verbose in (1, 2) and showEta) or conf.verbose >= 3:
|
||||||
infoMsg = "retrieved: %s" % filterControlChars(finalValue)
|
infoMsg = "retrieved: %s" % filterControlChars(finalValue)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ def _oneShotErrorUse(expression, field=None):
|
||||||
|
|
||||||
# Parse the returned page to get the exact error-based
|
# Parse the returned page to get the exact error-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
output = reduce(lambda x, y: x if x is not None else y, ( \
|
output = reduce(lambda x, y: x if x is not None else y, (\
|
||||||
extractRegexResult(check, page, re.DOTALL | re.IGNORECASE), \
|
extractRegexResult(check, page, re.DOTALL | re.IGNORECASE), \
|
||||||
extractRegexResult(check, listToStrValue(headers.headers \
|
extractRegexResult(check, listToStrValue(headers.headers \
|
||||||
if headers else None), re.DOTALL | re.IGNORECASE), \
|
if headers else None), re.DOTALL | re.IGNORECASE), \
|
||||||
|
|
|
@ -76,7 +76,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
# Parse the returned page to get the exact union-based
|
# Parse the returned page to get the exact union-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
def _(regex):
|
def _(regex):
|
||||||
return reduce(lambda x, y: x if x is not None else y, ( \
|
return reduce(lambda x, y: x if x is not None else y, (\
|
||||||
extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), \
|
extractRegexResult(regex, removeReflectiveValues(page, payload), re.DOTALL | re.IGNORECASE), \
|
||||||
extractRegexResult(regex, removeReflectiveValues(listToStrValue(headers.headers \
|
extractRegexResult(regex, removeReflectiveValues(listToStrValue(headers.headers \
|
||||||
if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), \
|
if headers else None), payload, True), re.DOTALL | re.IGNORECASE)), \
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
kb.data.cachedUsersPrivileges[user] = None
|
kb.data.cachedUsersPrivileges[user] = None
|
||||||
|
|
||||||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
return (kb.data.cachedUsersPrivileges, areAdmins)
|
||||||
|
|
||||||
def getTables(self):
|
def getTables(self):
|
||||||
if len(kb.data.cachedTables) > 0:
|
if len(kb.data.cachedTables) > 0:
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr))
|
logger.debug("generating chunk file %s\%s from debug script %s" % (tmpPath, chunkName, randScr))
|
||||||
|
|
||||||
commands = ( "cd %s" % tmpPath, "debug < %s" % randScr, "del /F /Q %s" % randScr )
|
commands = ("cd %s" % tmpPath, "debug < %s" % randScr, "del /F /Q %s" % randScr)
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(complComm)
|
||||||
|
@ -183,9 +183,9 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
logger.debug("converting the file utilizing PowerShell EncodedCommand")
|
logger.debug("converting the file utilizing PowerShell EncodedCommand")
|
||||||
|
|
||||||
commands = ( "cd %s" % tmpPath,
|
commands = ("cd %s" % tmpPath,
|
||||||
"powershell -EncodedCommand %s" % psString,
|
"powershell -EncodedCommand %s" % psString,
|
||||||
"del /F /Q %s" % randFilePath )
|
"del /F /Q %s" % randFilePath)
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(complComm)
|
||||||
|
@ -319,9 +319,9 @@ class Filesystem(GenericFilesystem):
|
||||||
|
|
||||||
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
|
self.xpCmdshellWriteFile(vbs, tmpPath, randVbs)
|
||||||
|
|
||||||
commands = ( "cd %s" % tmpPath, "cscript //nologo %s" % randVbs,
|
commands = ("cd %s" % tmpPath, "cscript //nologo %s" % randVbs,
|
||||||
"del /F /Q %s" % randVbs,
|
"del /F /Q %s" % randVbs,
|
||||||
"del /F /Q %s" % randFile )
|
"del /F /Q %s" % randFile)
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
|
|
||||||
self.execCmd(complComm)
|
self.execCmd(complComm)
|
||||||
|
|
|
@ -92,9 +92,9 @@ class Fingerprint(GenericFingerprint):
|
||||||
infoMsg = "confirming %s" % DBMS.MSSQL
|
infoMsg = "confirming %s" % DBMS.MSSQL
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
for version, check in ( ("2000", "HOST_NAME()=HOST_NAME()"), \
|
for version, check in (("2000", "HOST_NAME()=HOST_NAME()"), \
|
||||||
("2005", "XACT_STATE()=XACT_STATE()"), \
|
("2005", "XACT_STATE()=XACT_STATE()"), \
|
||||||
("2008", "SYSDATETIME()=SYSDATETIME()") ):
|
("2008", "SYSDATETIME()=SYSDATETIME()")):
|
||||||
result = inject.checkBooleanExpression(check)
|
result = inject.checkBooleanExpression(check)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
|
|
|
@ -155,7 +155,7 @@ class Fingerprint(GenericFingerprint):
|
||||||
|
|
||||||
# Windows executables should always have ' Visual C++' or ' mingw'
|
# Windows executables should always have ' Visual C++' or ' mingw'
|
||||||
# patterns within the banner
|
# patterns within the banner
|
||||||
osWindows = ( " Visual C++", "mingw" )
|
osWindows = (" Visual C++", "mingw")
|
||||||
|
|
||||||
for osPattern in osWindows:
|
for osPattern in osWindows:
|
||||||
query = "(SELECT LENGTH(%s) FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField)
|
query = "(SELECT LENGTH(%s) FROM %s WHERE %s " % (self.tblField, self.fileTblName, self.tblField)
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Enumeration(GenericEnumeration):
|
||||||
|
|
||||||
kb.data.cachedUsersPrivileges[user] = None
|
kb.data.cachedUsersPrivileges[user] = None
|
||||||
|
|
||||||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
return (kb.data.cachedUsersPrivileges, areAdmins)
|
||||||
|
|
||||||
def getDbs(self):
|
def getDbs(self):
|
||||||
if len(kb.data.cachedDbs) > 0:
|
if len(kb.data.cachedDbs) > 0:
|
||||||
|
|
|
@ -94,7 +94,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
msg = "how do you want to establish the tunnel?"
|
msg = "how do you want to establish the tunnel?"
|
||||||
msg += "\n[1] TCP: Metasploit Framework (default)"
|
msg += "\n[1] TCP: Metasploit Framework (default)"
|
||||||
msg += "\n[2] ICMP: icmpsh - ICMP tunneling"
|
msg += "\n[2] ICMP: icmpsh - ICMP tunneling"
|
||||||
valids = ( 1, 2 )
|
valids = (1, 2)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
tunnel = readInput(msg, default=1)
|
tunnel = readInput(msg, default=1)
|
||||||
|
@ -150,7 +150,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
errMsg += "is unlikely to receive commands sent from you"
|
errMsg += "is unlikely to receive commands sent from you"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
self.sysUdfs.pop("sys_bineval")
|
self.sysUdfs.pop("sys_bineval")
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
|
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) or conf.direct:
|
||||||
|
@ -160,7 +160,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
self.initEnv(web=web)
|
self.initEnv(web=web)
|
||||||
|
|
||||||
if tunnel == 1:
|
if tunnel == 1:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.MYSQL, DBMS.PGSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
|
||||||
msg = "how do you want to execute the Metasploit shellcode "
|
msg = "how do you want to execute the Metasploit shellcode "
|
||||||
msg += "on the back-end database underlying operating system?"
|
msg += "on the back-end database underlying operating system?"
|
||||||
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
|
||||||
|
@ -169,11 +169,11 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
while True:
|
while True:
|
||||||
choice = readInput(msg, default=1)
|
choice = readInput(msg, default=1)
|
||||||
|
|
||||||
if isinstance(choice, basestring) and choice.isdigit() and int(choice) in ( 1, 2 ):
|
if isinstance(choice, basestring) and choice.isdigit() and int(choice) in (1, 2):
|
||||||
choice = int(choice)
|
choice = int(choice)
|
||||||
break
|
break
|
||||||
|
|
||||||
elif isinstance(choice, int) and choice in ( 1, 2 ):
|
elif isinstance(choice, int) and choice in (1, 2):
|
||||||
break
|
break
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -251,7 +251,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
raise SqlmapUnsupportedDBMSException(errMsg)
|
raise SqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
if not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED) and not conf.direct:
|
||||||
if Backend.getIdentifiedDbms() in ( DBMS.PGSQL, DBMS.MSSQL ):
|
if Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.MSSQL):
|
||||||
errMsg = "on this back-end DBMS it is only possible to "
|
errMsg = "on this back-end DBMS it is only possible to "
|
||||||
errMsg += "perform the SMB relay attack if stacked "
|
errMsg += "perform the SMB relay attack if stacked "
|
||||||
errMsg += "queries are supported"
|
errMsg += "queries are supported"
|
||||||
|
@ -438,7 +438,7 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
|
||||||
message += "registry path '%s\%s? [y/N] " % (regKey, regVal)
|
message += "registry path '%s\%s? [y/N] " % (regKey, regVal)
|
||||||
output = readInput(message, default="N")
|
output = readInput(message, default="N")
|
||||||
|
|
||||||
if output and output[0] not in ( "Y", "y" ):
|
if output and output[0] not in ("Y", "y"):
|
||||||
return
|
return
|
||||||
|
|
||||||
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal)
|
infoMsg = "deleting Windows registry path '%s\%s'. " % (regKey, regVal)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user