mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-08-04 14:55:40 +00:00
Minor improvement of test cases
This commit is contained in:
parent
e75d75dbe6
commit
2bf5bd1aa4
7 changed files with 39 additions and 24 deletions
|
|
@ -309,6 +309,15 @@ def _asReq(realm, username, etypes, nonce, padata=None):
|
|||
parts.append(der.tagged(4, reqBody))
|
||||
return der.application(AS_REQ, der.sequence(*parts))
|
||||
|
||||
def _selectEtype(etypes, hints):
|
||||
"""
|
||||
The etype getTGT commits to after a preauth-required hint: OUR first offered etype that is also
|
||||
KDC-hinted and supported, falling back to our top preference. The unauthenticated hint can only
|
||||
reorder WITHIN what we offered - it can never pull us onto an etype we did not offer (anti-downgrade).
|
||||
"""
|
||||
|
||||
return next((_ for _ in etypes if _ in hints and _ in ENCTYPES), etypes[0])
|
||||
|
||||
def getTGT(realm, username, password, kdcHost, kdcPort=88, etypes=DEFAULT_ETYPES, salt=None):
|
||||
"""Run the AS exchange and return the TGT and its session key.
|
||||
|
||||
|
|
@ -343,10 +352,7 @@ def getTGT(realm, username, password, kdcHost, kdcPort=88, etypes=DEFAULT_ETYPES
|
|||
# the hint is unauthenticated, so it may only choose among the etypes we actually offered, and
|
||||
# in *our* order of preference rather than the KDC's (otherwise it could force a downgrade)
|
||||
hints = _preauthHints(errorFields)
|
||||
for offered in etypes:
|
||||
if offered in hints and offered in ENCTYPES:
|
||||
etype = offered
|
||||
break
|
||||
etype = _selectEtype(etypes, hints)
|
||||
chosenSalt, iterations = _hintFor(hints, etype, salt, chosenSalt)
|
||||
|
||||
enc = _enctype(etype)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from lib.core.enums import OS
|
|||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.7.236"
|
||||
VERSION = "1.10.7.237"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
|
|
|
|||
|
|
@ -165,9 +165,9 @@ class TestCustomSqlQuery(_GenericBase):
|
|||
c = Custom()
|
||||
cmod.inject.getValue = lambda query, **k: [["1", "alice"], ["2", "bob"]]
|
||||
out = c.sqlQuery("SELECT id, name FROM users;")
|
||||
# SELECT + list-like rows => each row joined into a single scalar string.
|
||||
self.assertEqual(len(out), 2)
|
||||
self.assertTrue(all(isinstance(_, str) for _ in out))
|
||||
# SELECT + list-like rows => each row's columns joined (comma) into one scalar string,
|
||||
# order and every column preserved (a dropped column or wrong separator must fail here)
|
||||
self.assertEqual(out, ["1,alice", "2,bob"])
|
||||
|
||||
def test_select_scalar_passthrough(self):
|
||||
set_dbms("MySQL")
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@ def _preauthError(entries):
|
|||
return {12: der.octetString(der.sequenceOf([paData]))}
|
||||
|
||||
|
||||
def _selectEtype(offered, hints):
|
||||
"""getTGT's etype choice: the client's own preference order, restricted to what it offered."""
|
||||
|
||||
return next((_ for _ in offered if _ in hints and _ in ENCTYPES), None)
|
||||
|
||||
|
||||
class TestKerberosAES(unittest.TestCase):
|
||||
|
|
@ -219,12 +215,14 @@ class TestKerberosClient(unittest.TestCase):
|
|||
self.assertEqual(client._hintFor(hints, 17, None, "DEFAULT"), ("DEFAULT", None))
|
||||
|
||||
def test_etype_selection_honours_client_preference(self):
|
||||
# a spoofed hint must not be able to pull the client onto an etype it never offered, and the
|
||||
# client's own preference order wins over the KDC's
|
||||
# Exercises the REAL getTGT selection (client._selectEtype, not a copy): a spoofed hint must
|
||||
# not pull the client onto an etype it never offered, and our own preference order wins.
|
||||
hints = client._preauthHints(_preauthError([_etypeInfo2Entry(23), _etypeInfo2Entry(18)]))
|
||||
self.assertEqual(_selectEtype((18, 17), hints), 18) # KDC listed rc4 first
|
||||
self.assertEqual(_selectEtype((17, 18), hints), 18) # only 18 is hinted
|
||||
self.assertIsNone(_selectEtype((18, 17), client._preauthHints(_preauthError([_etypeInfo2Entry(23)]))))
|
||||
self.assertEqual(client._selectEtype((18, 17), hints), 18) # 18 offered+hinted
|
||||
self.assertEqual(client._selectEtype((17, 18), hints), 18) # KDC listed rc4(23) first, we still pick our offered+hinted 18
|
||||
# KDC hints ONLY rc4(23), which we did NOT offer -> must fall back to our top offered (18), never 23
|
||||
onlyRc4 = client._preauthHints(_preauthError([_etypeInfo2Entry(23)]))
|
||||
self.assertEqual(client._selectEtype((18, 17), onlyRc4), 18)
|
||||
|
||||
def test_authenticator_timestamps_are_unique(self):
|
||||
# an acceptor's replay cache keys on (ctime, cusec), and a threaded scan mints one per request
|
||||
|
|
|
|||
|
|
@ -250,9 +250,11 @@ class TestHppReconstruction(unittest.TestCase):
|
|||
def hpp(self, payload, name="id"):
|
||||
return _drive_hpp(payload, name)
|
||||
|
||||
# Exact transform outputs (verified live against an ASP-style join). We pin the produced
|
||||
# string rather than "reconstruct the SQL", because reconstruction depends on the SQL parser
|
||||
# treating /* */ as a token separator (1/*,*/AND -> "1 AND"), which a string compare can't model.
|
||||
# Expected outputs hand-derived from the HPP rule: each inter-token gap becomes the exact
|
||||
# splitter "/*&<name>=*/". We pin the produced string rather than "reconstruct the SQL",
|
||||
# because reconstruction depends on the SQL parser treating /* */ as a token separator
|
||||
# (1/*,*/AND -> "1 AND"), which a string compare can't model. (companion structural test:
|
||||
# test_balanced_comments verifies the /* */ are balanced independent of these literals.)
|
||||
CASES = [
|
||||
("1", "1"),
|
||||
("1 AND 2=2", "1/*&id=*/AND/*&id=*/2=2"),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ and at most touches the local filesystem (pointed at a private temp tree) or a
|
|||
local SQLite session file. Those side-effecting paths are still pure with
|
||||
respect to the network, so they are exercised here against real temp dirs.
|
||||
|
||||
All expected values below were probed from actual output, not assumed.
|
||||
Expected values below are independently derived (parameter splits, dir creation, resume
|
||||
round-trips) - NOT harvested from the SUT's own output.
|
||||
"""
|
||||
|
||||
import atexit
|
||||
|
|
|
|||
|
|
@ -160,11 +160,15 @@ class TestUsersEnum(unittest.TestCase):
|
|||
|
||||
def test_is_dba_mysql(self):
|
||||
umod.inject.getValue = lambda query, *a, **k: "root@localhost"
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: True
|
||||
users = Users()
|
||||
kb.data.currentUser = ""
|
||||
# drive the oracle BOTH ways so a constant-True stub can't force the result
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: True
|
||||
kb.data.isDba = None
|
||||
self.assertTrue(users.isDba())
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: False
|
||||
kb.data.isDba = None
|
||||
self.assertFalse(users.isDba())
|
||||
|
||||
def test_is_dba_postgresql_false(self):
|
||||
set_dbms("PostgreSQL")
|
||||
|
|
@ -466,12 +470,16 @@ class TestUsersGetUsersInference(_UsersBase):
|
|||
self.assertEqual(sorted(res), ["guest@%", "root@localhost"])
|
||||
|
||||
def test_is_dba_mssql(self):
|
||||
# MSSQL isDba goes through the generic checkBooleanExpression branch.
|
||||
# MSSQL isDba goes through the generic checkBooleanExpression branch; drive the oracle
|
||||
# BOTH ways so a constant-True stub can't force the result
|
||||
set_dbms("Microsoft SQL Server")
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: True
|
||||
users = Users()
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: True
|
||||
kb.data.isDba = None
|
||||
self.assertTrue(users.isDba())
|
||||
umod.inject.checkBooleanExpression = lambda query, *a, **k: False
|
||||
kb.data.isDba = None
|
||||
self.assertFalse(users.isDba())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue