Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ jobs:
runs-on: ${{ matrix.os }}
timeout-minutes: 30

env:
# deterministic dict/set iteration order run-to-run (guards against hash-order flakiness in CI)
PYTHONHASHSEED: "0"

strategy:
matrix:
include:
Expand Down
110 changes: 110 additions & 0 deletions data/txt/common-outputs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1364,3 +1364,113 @@ username
visible
zip
zip_code

# --- real-world application / CMS / framework values (repeated section headers are merged on load) ---
[Databases]
wordpress
wp
drupal
joomla
magento
prestashop
opencart
moodle
mediawiki
phpbb
typo3
laravel
symfony
django
app
application
webapp
web
website
main
backend
api
cms
shop
store
ecommerce
blog
forum
wiki
crm
erp
billing
sales
accounts
inventory
catalog
orders
payments
customers
members
users
data
db
mydb
appdb
prod
production
dev
staging
qa
demo
sample
employees
sakila
world
classicmodels
dvwa
bwapp
mutillidae
dashboard
defaultdb

[Users]
admin
administrator
root
sa
postgres
oracle
system
dbadmin
dba
dbo
webadmin
web
www
www-data
apache
nginx
app
appuser
application
service
svc
user
dbuser
guest
test
demo
backup
replication
monitor
readonly
superuser
wordpress
drupal
joomla
magento
laravel
django
symfony
'admin'@'localhost'
'admin'@'%'
'app'@'localhost'
'app'@'%'
'web'@'%'
'wordpress'@'localhost'
141 changes: 72 additions & 69 deletions data/txt/sha256sums.txt

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions data/xml/queries.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
<!-- https://stackoverflow.com/a/31122246 -->
<passwords>
<inband query="SELECT user,authentication_string FROM mysql.user" condition="user"/>
<blind query="SELECT DISTINCT(authentication_string) FROM mysql.user WHERE user='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(authentication_string)) FROM mysql.user WHERE user='%s'"/>
<inband query="SELECT user,IF(LEFT(authentication_string,3)=0x244124,CONCAT(0x246d7973716c,LEFT(authentication_string,6),0x2a,INSERT(HEX(SUBSTR(authentication_string,8)),41,0,0x2a)),authentication_string) FROM mysql.user" condition="user"/>
<blind query="SELECT DISTINCT(IF(LEFT(authentication_string,3)=0x244124,CONCAT(0x246d7973716c,LEFT(authentication_string,6),0x2a,INSERT(HEX(SUBSTR(authentication_string,8)),41,0,0x2a)),authentication_string)) FROM mysql.user WHERE user='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(authentication_string)) FROM mysql.user WHERE user='%s'"/>
</passwords>
<privileges>
<inband query="SELECT grantee,privilege_type FROM INFORMATION_SCHEMA.USER_PRIVILEGES" condition="grantee" query2="SELECT user,select_priv,insert_priv,update_priv,delete_priv,create_priv,drop_priv,reload_priv,shutdown_priv,process_priv,file_priv,grant_priv,references_priv,index_priv,alter_priv,show_db_priv,super_priv,create_tmp_table_priv,lock_tables_priv,execute_priv,repl_slave_priv,repl_client_priv,create_view_priv,show_view_priv,create_routine_priv,alter_routine_priv,create_user_priv FROM mysql.user" condition2="user"/>
Expand Down
2 changes: 0 additions & 2 deletions doc/THIRD-PARTY.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ be bound by the terms and conditions of this License Agreement.
Copyright (C) 2024, Marcel Hellkamp.
* The `identYwaf` library located under `thirdparty/identywaf/`.
Copyright (C) 2019-2021, Miroslav Stampar.
* The `ordereddict` library located under `thirdparty/odict/`.
Copyright (C) 2009, Raymond Hettinger.
* The `six` Python 2 and 3 compatibility library located under `thirdparty/six/`.
Copyright (C) 2010-2024, Benjamin Peterson.
* The `Termcolor` library located under `thirdparty/termcolor/`.
Expand Down
7 changes: 4 additions & 3 deletions lib/controller/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,10 @@ def start():
checkNullConnection()

if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) and (kb.injection.place is None or kb.injection.parameter is None):
if not any((conf.string, conf.notString, conf.regexp)) and PAYLOAD.TECHNIQUE.BOOLEAN in conf.technique:
# NOTE: this is not needed anymore, leaving only to display
# a warning message to the user in case the page is not stable
if not any((conf.string, conf.notString, conf.regexp)) and any(_ in conf.technique for _ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.UNION)):
# NOTE: besides the not-stable warning, this marks dynamic content for removal, which
# UNION column-count detection relies on too (it compares pages) - so it must run when
# UNION is tested even if BOOLEAN is excluded (e.g. '--technique=U' on a dynamic page)
checkStability()

# Do a little prioritization reorder of a testable parameter list
Expand Down
11 changes: 10 additions & 1 deletion lib/core/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -958,12 +958,19 @@ def _collate(value):
if not infoFile:
query = _collate(query)

# A fuzzy-discovered per-column type template (kb.unionTemplate, e.g. ['1234', '%s', '5678'])
# forces type-compatible fillers on strict DBMSes (e.g. Apache Derby, which rejects bare NULL
# and demands UNION column-type parity); '%s' marks the slot carrying the injected expression.
template = kb.unionTemplate if isinstance(kb.unionTemplate, (list, tuple)) and len(kb.unionTemplate) == count else None

for element in xrange(0, count):
if element > 0:
unionQuery += ','

if conf.uValues and conf.uValues.count(',') + 1 == count:
unionQuery += conf.uValues.split(',')[element]
elif template is not None:
unionQuery += query if template[element] == "%s" else template[element]
elif element == position:
unionQuery += query
else:
Expand All @@ -985,7 +992,9 @@ def _collate(value):
if element > 0:
unionQuery += ','

if element == position:
if template is not None:
unionQuery += _collate(multipleUnions) if template[element] == "%s" else template[element]
elif element == position:
unionQuery += _collate(multipleUnions)
else:
unionQuery += char
Expand Down
17 changes: 15 additions & 2 deletions lib/core/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
from thirdparty.clientform.clientform import ParseError
from thirdparty.colorama.initialise import init as coloramainit
from thirdparty.magic import magic
from thirdparty.odict import OrderedDict
from collections import OrderedDict
from thirdparty.six import unichr as _unichr
from thirdparty.six.moves import collections_abc as _collections
from thirdparty.six.moves import configparser as _configparser
Expand Down Expand Up @@ -2099,7 +2099,9 @@ def getFileType(filePath):
desc = getText(desc)

if desc == getText(magic.MAGIC_UNKNOWN_FILETYPE):
content = openFile(filePath, "rb", encoding=None).read()
_ = openFile(filePath, "rb", encoding=None)
content = _.read()
_.close()

try:
content.decode()
Expand Down Expand Up @@ -2624,6 +2626,17 @@ def initCommonOutputs():
if line not in kb.commonOutputs[key]:
kb.commonOutputs[key].add(line)

# The curated '--common-tables'/'--common-columns' brute-force wordlists are far larger and much
# more app-focused than the built-in [Tables]/[Columns] prediction sections (which are mostly
# system objects), so fold them into the good-samaritan prediction to raise its real-world hit rate.
# The mechanism only reorders the charset, so extra coverage never penalizes a miss.
for _key, _path in (("Tables", paths.COMMON_TABLES), ("Columns", paths.COMMON_COLUMNS)):
try:
for _ in getFileItems(_path):
kb.commonOutputs.setdefault(_key, set()).add(_)
except SqlmapSystemException:
pass

def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
"""
Returns newline delimited items contained inside file
Expand Down
2 changes: 1 addition & 1 deletion lib/core/datatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import copy
import threading

from thirdparty.odict import OrderedDict
from collections import OrderedDict
from thirdparty.six.moves import collections_abc as _collections

class AttribDict(dict):
Expand Down
2 changes: 1 addition & 1 deletion lib/core/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
from lib.utils.safe2bin import safechardecode
from thirdparty import six
from thirdparty.magic import magic
from thirdparty.odict import OrderedDict
from collections import OrderedDict

class Dump(object):
"""
Expand Down
11 changes: 11 additions & 0 deletions lib/core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ class HASH(object):
MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z'
MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z'
POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z'
POSTGRES_SCRAM = r'\ASCRAM-SHA-256\$\d+:[A-Za-z0-9+/]+={0,2}\$[A-Za-z0-9+/]+={0,2}:[A-Za-z0-9+/]+={0,2}\Z'
MYSQL_SHA2 = r'\A\$mysql\$A\$[0-9A-Fa-f]{3}\*[0-9A-Fa-f]{40}\*[0-9A-Fa-f]{86}\Z'
MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z'
MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z'
MSSQL_NEW = r'(?i)\A0x0200[0-9a-f]{8}[0-9a-f]{128}\Z'
Expand All @@ -192,6 +194,8 @@ class HASH(object):
SHA384_GENERIC = r'(?i)\A[0-9a-f]{96}\Z'
SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z'
CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z'
SHA256_UNIX_CRYPT = r'\A\$5\$(?:rounds=\d+\$)?[./0-9A-Za-z]{1,16}\$[./0-9A-Za-z]{43}\Z'
SHA512_UNIX_CRYPT = r'\A\$6\$(?:rounds=\d+\$)?[./0-9A-Za-z]{1,16}\$[./0-9A-Za-z]{86}\Z'
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z'
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
Expand All @@ -205,6 +209,13 @@ class HASH(object):
SSHA512 = r'\A\{SSHA512\}[a-zA-Z0-9+/]+={0,2}\Z'
DJANGO_MD5 = r'\Amd5\$[^$]*\$[0-9a-f]{32}\Z'
DJANGO_SHA1 = r'\Asha1\$[^$]*\$[0-9a-f]{40}\Z'
DJANGO_PBKDF2_SHA256 = r'\Apbkdf2_sha256\$\d+\$[^$]+\$[A-Za-z0-9+/]+={0,2}\Z'
WERKZEUG_PBKDF2 = r'\Apbkdf2:(?:sha1|sha256|sha512):\d+\$[^$]+\$[0-9a-f]+\Z'
WERKZEUG_SCRYPT = r'\Ascrypt:\d+:\d+:\d+\$[^$]+\$[0-9a-f]+\Z'
BCRYPT = r'\A\$2[abxy]\$\d{2}\$[./A-Za-z0-9]{53}\Z'
WORDPRESS_BCRYPT = r'\A\$wp\$2[abxy]\$\d{2}\$[./A-Za-z0-9]{53}\Z'
ARGON2 = r'\A\$argon2(?:id|i|d)\$v=\d+\$m=\d+,t=\d+,p=\d+\$[A-Za-z0-9+/]+={0,2}\$[A-Za-z0-9+/]+={0,2}\Z'
ASPNET_IDENTITY = r'\AAQAAAA[A-Za-z0-9+/]{76}==\Z'
MD5_BASE64 = r'\A[a-zA-Z0-9+/]{22}==\Z'
SHA1_BASE64 = r'\A[a-zA-Z0-9+/]{27}=\Z'
SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z'
Expand Down
Loading