Compare commits

..

23 Commits

Author SHA1 Message Date
Miroslav Stampar
60d145ab6b Implementing support for v2.x for H2 2025-12-25 01:04:41 +01:00
Miroslav Stampar
af8742e882 Minor patch for Firebird 2025-12-24 23:13:52 +01:00
Miroslav Stampar
dbf5daf788 Bug fix with special case of reflective values in error-based results 2025-12-24 16:16:51 +01:00
Miroslav Stampar
c62dd8511e Fixes #5995 2025-12-23 00:01:41 +01:00
Miroslav Stampar
d89a0bb9df Patch for #5994 2025-12-22 12:22:46 +01:00
Miroslav Stampar
09dfa568ae Adding support to sort HTML table dumps by columns 2025-12-05 10:30:13 +01:00
Miroslav Stampar
9c78723a63 Minor patch 2025-12-05 09:03:16 +01:00
Miroslav Stampar
801a431a3a Fixes #5983 2025-12-04 11:37:16 +01:00
Miroslav Stampar
f22abb36a3 Fixes #5985 2025-12-02 21:04:05 +01:00
Miroslav Stampar
6d4123c27d Minor update of banner regexes 2025-11-28 13:16:40 +01:00
Miroslav Stampar
f44aef3e41 Fixes #5978 2025-11-10 09:40:19 +01:00
Miroslav Stampar
619d53a9e5 Dump patch for #5975 2025-11-07 16:09:27 +01:00
Miroslav Stampar
77a42b3a6f Minor patches 2025-11-06 11:41:35 +01:00
Miroslav Stampar
0599f7c1b6 Minor bug fix 2025-11-06 11:14:13 +01:00
Miroslav Stampar
03be59042f Fixes #5968 2025-10-19 22:02:15 +02:00
Miroslav Stampar
6d914fefe4 Dummy update 2025-10-19 10:46:41 +02:00
JerryJhird
86e4cd55fa fix logic bug (#5967)
The thread-finalization loop used a reversed comparison, causing the
wait loop to be skipped immediately:

this change reverse the comparison so it will wait while there are
active threads and elapsed time is less than the configured
THREAD_FINALIZATION_TIMEOUT:
2025-10-19 10:46:02 +02:00
Miroslav Stampar
3915f9f702 Minor patch 2025-10-19 10:42:39 +02:00
Miroslav Stampar
9a41707ec7 Another fix for wrong number of params 2025-10-17 20:18:48 +02:00
Miroslav Stampar
bce338bdff Potential fix for wrong number of params 2025-10-17 16:50:15 +02:00
Miroslav Stampar
5df4c29158 Minor update 2025-10-07 10:48:16 +02:00
Miroslav Stampar
71a12bff64 Minor update of the --gui functionality 2025-09-15 00:03:04 +02:00
Miroslav Stampar
f7aa757a9f Minor patch (safer alternative) 2025-09-14 22:23:54 +02:00
22 changed files with 363 additions and 141 deletions

View File

@@ -64,17 +64,17 @@ b427b65cc8b585cd02361f5155ffab2fe52fd5943100382c6b86cd0f52f352d9 data/udf/postg
c444fd667a09927a22c92e855d206249e761c1fbd4f3630f7ee06265eb2576ee data/udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_
c6be099a5dee34f3a7570715428add2e7419f4e73a7ce9913d3fb76eea78d88e data/udf/postgresql/windows/32/9.0/lib_postgresqludf_sys.dll_
0a6d5fc399e9958477c8a71f63b7c7884567204253e0d2389a240d83ed83f241 data/udf/README.txt
4e268596da67fb0b6a10a7cefb38af5de13f67dab760cc0505f8f80484a0fe79 data/xml/banner/generic.xml
288592bbc7115870516865d5a92c2e1d1d54f11a26a86998f8829c13724e2551 data/xml/banner/generic.xml
2adcdd08d2c11a5a23777b10c132164ed9e856f2a4eca2f75e5e9b6615d26a97 data/xml/banner/mssql.xml
14b18da611d4bfad50341df89f893edf47cd09c41c9662e036e817055eaa0cfb data/xml/banner/mysql.xml
6d1ab53eeac4fae6d03b67fb4ada71b915e1446a9c1cc4d82eafc032800a68fd data/xml/banner/oracle.xml
9f4ca1ff145cfbe3c3a903a21bf35f6b06ab8b484dad6b7c09e95262bf6bfa05 data/xml/banner/postgresql.xml
86da6e90d9ccf261568eda26a6455da226c19a42cc7cd211e379cab528ec621e data/xml/banner/server.xml
146887f28e3e19861516bca551e050ce81a1b8d6bb69fd342cc1f19a25849328 data/xml/banner/servlet-engine.xml
e87c062bdf05b27db6c1d7e0d41c25f269cbe66b1f9b8e2d9b3db0d567016c76 data/xml/banner/set-cookie.xml
8af6b979b6e0a01062dc740ae475ba6be90dc10bb3716a45d28ada56e81f9648 data/xml/banner/set-cookie.xml
a7eb4d1bcbdfd155383dcd35396e2d9dd40c2e89ce9d5a02e63a95a94f0ab4ea data/xml/banner/sharepoint.xml
e2febc92f9686eacf17a0054f175917b783cc6638ca570435a5203b03245fc18 data/xml/banner/x-aspnet-version.xml
75672f8faa8053af0df566a48700f2178075f67c593d916313fcff3474da6f82 data/xml/banner/x-powered-by.xml
3a440fbbf8adffbe6f570978e96657da2750c76043f8e88a2c269fe9a190778c data/xml/banner/x-powered-by.xml
1ac399c49ce3cb8c0812bb246e60c8a6718226efe89ccd1f027f49a18dbeb634 data/xml/boundaries.xml
47c444f260fcba24bb1f13e3d4819ed846909f8d2b6e715069d6372ea30f026f data/xml/errors.xml
cfa1f0557fb71be0631796a4848d17be536e38f94571cf6ef911454fbc6b30d1 data/xml/payloads/boolean_blind.xml
@@ -83,7 +83,7 @@ b0f434f64105bd61ab0f6867b3f681b97fa02b4fb809ac538db382d031f0e609 data/xml/paylo
0648264166455010921df1ec431e4c973809f37ef12cbfea75f95029222eb689 data/xml/payloads/stacked_queries.xml
997556b6170964a64474a2e053abe33cf2cf029fb1acec660d4651cc67a3c7e1 data/xml/payloads/time_blind.xml
40a4878669f318568097719d07dc906a19b8520bc742be3583321fc1e8176089 data/xml/payloads/union_query.xml
95b7464b1a7b75e2b462d73c6cca455c13b301f50182a8b2cd6701cdcb80b43e data/xml/queries.xml
dd0ee0fac1a4f7fdbecc8fcceb0a1a4e2d15cec3847198740a1994851c56ad27 data/xml/queries.xml
abb6261b1c531ad2ee3ada8184c76bcdc38732558d11a8e519f36fcc95325f7e doc/AUTHORS
2a0322f121cbda30336ab58382e9860fea8ab28ff4726f6f8abf143ce1657abe doc/CHANGELOG.md
2df1f15110f74ce4e52f0e7e4a605e6c7e08fbda243e444f9b60e26dfc5cf09d doc/THANKS.md
@@ -160,42 +160,42 @@ df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 extra/vulnserver/__init__.py
eed1db5da17eca4c65a8f999166e2246eef84397687ae820bbe4984ef65a09df extra/vulnserver/vulnserver.py
96a39b4e3a9178e4e8285d5acd00115460cc1098ef430ab7573fc8194368da5c lib/controller/action.py
2c8652359d6790755117ec5c68d0ddffacff5f3377ad5004c4fffd29c2446d61 lib/controller/checks.py
16487b3d984b9020cc68c0e4e079759a8990d05173f2496f7de30643ac772fe2 lib/controller/checks.py
34e9cf166e21ce991b61ca7695c43c892e8425f7e1228daec8cadd38f786acc6 lib/controller/controller.py
49bcd74281297c79a6ae5d4b0d1479ddace4476fddaf4383ca682a6977b553e3 lib/controller/handler.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/controller/__init__.py
216c9399853b7454d36dcb552baf9f1169ec7942897ddc46504684325cb6ce00 lib/core/agent.py
fbba89420acafcdb9ba1a95428cf2161b13cfa2d1a7ad7d5e70c14b0e04861f0 lib/core/bigarray.py
e3b8f8cf9607d12f3de5e6bcd5031f21f50d4b331844b8e921493dfde2efe0f7 lib/core/common.py
d81080a7223e3d2ffd2a063f7c5b49ab9f25294ed70a0fbdf42d0c0df3551bb3 lib/core/common.py
d53a8aecab8af8b8da4dc1c74d868f70a38770d34b1fa50cae4532cae7ce1c87 lib/core/compat.py
ebe518089733722879f5a13e73020ebe55d46fb7410cacf292ca4ea1d9d1c56a lib/core/convert.py
463005de14642fef4251c951c9b24ec8d456f67f0cd98a9f4d6add281ccbb775 lib/core/convert.py
ae500647c4074681749735a4f3b17b7eca44868dd3f39f9cab0a575888ba04a1 lib/core/data.py
ffae7cfe9f9afb92e887b9a8dbc1630d0063e865f35984ae417b04a4513e5024 lib/core/datatype.py
8a5a6f5313726d6880aeb1ffca35bc2ff6ecd3709b3e987551189a72fed25bf0 lib/core/decorators.py
1d70d75a1c1a2a0ad295f727ee9f1d90cea851dfc2f8c9a85ef79c7975007ead lib/core/decorators.py
d573a37bb00c8b65f75b275aa92549683180fb209b75fd0ff3870e3848939900 lib/core/defaults.py
ce6e1c1766acd95168f7708ddcacaa4a586c21ffc9e92024c4715611c802b60c lib/core/dicts.py
c9d1f64648062d7962caf02c4e2e7d84e8feb2a14451146f627112aae889afcd lib/core/dump.py
c1f211843ccc93a50639ae6f4a50eb434f334e095d9fea440cebe589004374f3 lib/core/enums.py
4f1b858d433daa6f898d5ded54066cad63fab7ee245ad9eb1613c626448d5a0e lib/core/dump.py
2ca709fb52b4a1bc83cfe2acdad7e7d4dca1fee6a775e9290f0f1f517955d0b9 lib/core/enums.py
00a9b29caa81fe4a5ef145202f9c92e6081f90b2a85cd76c878d520d900ad856 lib/core/exception.py
629c0d06d4f4d093badfc8d1de49432d058f66f3223b08dded012eaf05719de2 lib/core/gui.py
1c48804c10b94da696d3470efbd25d2fff0f0bbf2af0101aaac8f8c097fce02b lib/core/gui.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/core/__init__.py
3d308440fb01d04b5d363bfbe0f337756b098532e5bb7a1c91d5213157ec2c35 lib/core/log.py
2a06dc9b5c17a1efdcdb903545729809399f1ee96f7352cc19b9aaa227394ff3 lib/core/optiondict.py
d33dbc25635e2ae42c70e5997f28097143966279adfbf98e95b0d09ad4976e88 lib/core/option.py
c53862358795097a59aa4eacc4d90815afb7e0540899b8885b586e43267be225 lib/core/option.py
fd449fe2c707ce06c929fc164cbabb3342f3e4e2b86c06f3efc1fc09ac98a25a lib/core/patch.py
85f10c6195a3a675892d914328173a6fb6a8393120417a2f10071c6e77bfa47d lib/core/profiling.py
c4bfb493a03caf84dd362aec7c248097841de804b7413d0e1ecb8a90c8550bc0 lib/core/readlineng.py
d1bd70c1a55858495c727fbec91e30af267459c8f64d50fabf9e4ee2c007e920 lib/core/replication.py
1d0f80b0193ac5204527bfab4bde1a7aee0f693fd008e86b4b29f606d1ef94f3 lib/core/revision.py
d2eb8e4b05ac93551272b3d4abfaf5b9f2d3ac92499a7704c16ed0b4f200db38 lib/core/session.py
671255b7fd3714ef4315b8ff6f73e09496170d21796dd5e73062654be4ed615e lib/core/settings.py
b1b416ae195be51eadd8f31be271f5774eed1dc8d90cb5e7421d2f60ca9ff26f lib/core/settings.py
1c5eab9494eb969bc9ce118a2ea6954690c6851cbe54c18373c723b99734bf09 lib/core/shell.py
4eea6dcf023e41e3c64b210cb5c2efc7ca893b727f5e49d9c924f076bb224053 lib/core/subprocessng.py
cdd352e1331c6b535e780f6edea79465cb55af53aa2114dcea0e8bf382e56d1a lib/core/target.py
6cf11d8b00fa761046686437fe90565e708809f793e88a3f02527d0e49c4d2a8 lib/core/testing.py
2a179b7601026a8da092271b30ad353cdb6decd658e2614fa51983aaf6dd80e7 lib/core/threads.py
6f61e7946e368ee1450c301aaf5a26381a8ae31fc8bffa28afc9383e8b1fbc3f lib/core/unescaper.py
f7245b99c17ef88cd9a626ca09c0882a5e172bb10a38a5dec9d08da6c8e2d076 lib/core/update.py
8919863be7a86f46d2c41bd30c0114a55a55c5931be48e3cfc66dfa96b7109c8 lib/core/update.py
cba481f8c79f4a75bd147b9eb5a1e6e61d70422fceadd12494b1dbaa4f1d27f4 lib/core/wordlist.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/__init__.py
7d1d3e07a1f088428d155c0e1b28e67ecbf5f62775bdeeeb11b4388369dce0f7 lib/parse/banner.py
@@ -220,7 +220,7 @@ fcab35db1da4ac11d8c5b8291f9c87b8d7bb073c460c438374bc5a71ce5c65a6 lib/request/in
03490bed87a54bf6c42a33ac1a66f7f8504c2398534a211e7e9306f408cd506a lib/request/methodrequest.py
eba8b1638c0c19d497dcbab86c9508b2ce870551b16a40db752a13c697d7d267 lib/request/pkihandler.py
6336a6aba124905dab3e5ff67f76cf9b735c2a2879cc3bc8951cb06bea125895 lib/request/rangehandler.py
14b402c3a927b7fb251622c9f4faf507993e033bd3b1cc281fe2873b9a382a51 lib/request/redirecthandler.py
d6ab6436d7330278081ed21433ab18e5ef74b4d7af7ccb175ae956c245c13ce1 lib/request/redirecthandler.py
3157d66bb021b71b2e71e355b209578d15f83000f0655bcf0cd7c7eed5d4669b lib/request/templates.py
5f5680c5b1db48ed2a13f47ba9de8b816d9d4f7f4c7abd07a48eb7ecbe9cf3ca lib/takeover/abstraction.py
250782249ee5afbcf3f398c596edbc3a9a1b35b3e11ac182678f6e22c1449852 lib/takeover/icmpsh.py
@@ -230,7 +230,7 @@ eba8b1638c0c19d497dcbab86c9508b2ce870551b16a40db752a13c697d7d267 lib/request/pk
479cf4a9c0733ba62bfa764e465a59277d21661647304fa10f6f80bf6ecc518b lib/takeover/udf.py
08270a96d51339f628683bce58ee53c209d3c88a64be39444be5e2f9d98c0944 lib/takeover/web.py
d40d5d1596d975b4ff258a70ad084accfcf445421b08dcf010d36986895e56cb lib/takeover/xp_cmdshell.py
9b3ccafc39f24000a148484a005226b8ba5ac142f141a8bd52160dfc56941538 lib/techniques/blind/inference.py
3a355d277fa558c90fa040b3a02b99690671bf99a7a4ffb20a9a45878b09ab5e lib/techniques/blind/inference.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/techniques/blind/__init__.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/techniques/dns/__init__.py
d20798551d141b3eb0b1c789ee595f776386469ac3f9aeee612fd7a5607b98cd lib/techniques/dns/test.py
@@ -240,7 +240,7 @@ d20798551d141b3eb0b1c789ee595f776386469ac3f9aeee612fd7a5607b98cd lib/techniques
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/techniques/__init__.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 lib/techniques/union/__init__.py
dca6a14d7e30f8d320cc972620402798b493528a0ad7bd98a7f38327cea04e20 lib/techniques/union/test.py
4a866eefe165a541218eb71926a49f65ac13505b88857624b3759970c5069451 lib/techniques/union/use.py
9c57e5467c295e10356f457d7a95a652602e6ef09566ab1346fa23519fdf1b3b lib/techniques/union/use.py
e41d96b1520e30bd4ce13adfcf52e11d3a5ea75c0b2d7612958d0054be889763 lib/utils/api.py
af67d25e8c16b429a5b471d3c629dc1da262262320bf7cd68465d151c02def16 lib/utils/brute.py
828940a8eefda29c9eb271c21f29e2c4d1d428ccf0dcc6380e7ee6740300ec55 lib/utils/crawler.py
@@ -342,7 +342,7 @@ fd9d9030d054b9b74cf6973902ca38b0a6cad5898b828366162df6bdc8ea10d2 plugins/dbms/f
ed39a02193934768cf65d86f9424005f60e0ef03052b5fea1103c78818c19d45 plugins/dbms/h2/connector.py
8556f37d4739f8eafcde253b2053d1af41959f6ec09af531304d0e695e3eed6b plugins/dbms/h2/enumeration.py
080b0c1173ffe7511dc6990b6de8385b5e63a5c19b8d5e2d04de23ac9513a45c plugins/dbms/h2/filesystem.py
d08c1a912f8334c3e706b598db2869edbb1a291a2ccb00c9523ee371de9db0d0 plugins/dbms/h2/fingerprint.py
355f941c74cbd0d43726408970aab9518f50f588e780aa764ed237e4bc0c3316 plugins/dbms/h2/fingerprint.py
94ee6a0f41bb17b863a0425f95c0dcf90963a7f0ed92f5a2b53659c33b5910b8 plugins/dbms/h2/__init__.py
9899a908eb064888d0e385156395d0436801027b2f4a9846b588211dc4b61f83 plugins/dbms/h2/syntax.py
53951b2ba616262df5a24aa53e83c1e401d7829bd4b7386dd07704fd05811de2 plugins/dbms/h2/takeover.py
@@ -464,20 +464,20 @@ b333c73c6a490b5930a09c6c09951af1044eb97076446b2f1475c7cfdfc838a6 plugins/generi
4a923f52e8d2dfa6b55c16e08fd5f64eeb292b99573030c0397c7292a4032dd3 plugins/generic/databases.py
9b0dbf8f77f190ca92cc58e9c5f784d0b30276ee7d99906f6d9c826c23b6d2e1 plugins/generic/entries.py
783a17bb5188b6b9f4a73dbf10d5cf5c073144d5c1970a9d4aec27cb828e2356 plugins/generic/enumeration.py
5dbcb646c03b43d1f26c0dbd17ae8fb537fdc526ca9984e1cc3e9eae12c38e6e plugins/generic/filesystem.py
8bf9cefa645a2e639861faf3c64ccc82a7bdc0fdc330a70138ddb8b280bef020 plugins/generic/filesystem.py
ab661b605012168d72f84a92ff7e233542df3825c66714c99073e56acea37e2e plugins/generic/fingerprint.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 plugins/generic/__init__.py
9ec577d8ccf4698d4e7834bf1e97aea58fba9d2609714b7139c747bcc4f59a30 plugins/generic/misc.py
546486bd4221729d7d85b6ce3dbc263c818d091c67774bd781d7d72896eb733b plugins/generic/search.py
9be0e2f931b559052518b68511117d6d6e926e69e463ddfa6dc8e9717c0ca677 plugins/generic/syntax.py
7bb6403d83cc9fd880180e3ad36dca0cc8268f05f9d7e6f6dba6d405eea48c3a plugins/generic/takeover.py
115ee30c77698bb041351686a3f191a3aa247adb2e0da9844f1ad048d0e002cd plugins/generic/users.py
cbc7684de872fac4baeabd1fce3938bc771316c36e54d69ac6a301e8a99f07b2 plugins/generic/users.py
4608f21a4333c162ab3c266c903fda4793cc5834de30d06affe9b7566dd09811 plugins/__init__.py
f5cad477023c8145c4db7aa530976fc75b098cf59a49905f28d02f6771fd9697 README.md
535ab6ac8b8441a3758cee86df3e68abec8b43eee54e32777967252057915acc sqlmapapi.py
168309215af7dd5b0b71070e1770e72f1cbb29a3d8025143fb8aa0b88cd56b62 sqlmapapi.yaml
a40607ce164eb2d21865288d24b863edb1c734b56db857e130ac1aef961c80b9 sqlmap.conf
822b706e791eba9b994b08e7600a3adfc3843d360437edfa0bfd588a1f58a13c sqlmap.py
d305f00a68898314242e7cfc19daf367c8f97e5f1da40100390b635b73b80722 sqlmap.py
82caac95182ac5cae02eb7d8a2dc07e71389aeae6b838d3d3f402c9597eb086a tamper/0eunion.py
bc8f5e638578919e4e75a5b01a84b47456bac0fd540e600975a52408a3433460 tamper/apostrophemask.py
c9c3d71f11de0140906d7b4f24fadb9926dc8eaf5adab864f8106275f05526ce tamper/apostrophenullencode.py

View File

@@ -3,7 +3,7 @@
<root>
<!-- Windows -->
<regexp value="(Microsoft|Windows|Win32)">
<regexp value="(Microsoft|Windows|Win32|Win64|WOW64|Cygwin|MinGW)">
<info type="Windows"/>
</regexp>
@@ -151,6 +151,34 @@
<info type="Linux" distrib="Ubuntu"/>
</regexp>
<regexp value="\bAlpine\b">
<info type="Linux" distrib="Alpine"/>
</regexp>
<regexp value="Oracle ?Linux">
<info type="Linux" distrib="Oracle"/>
</regexp>
<regexp value="\bRHEL\b">
<info type="Linux" distrib="Red Hat"/>
</regexp>
<regexp value="Amazon Linux">
<info type="Linux" distrib="Amazon"/>
</regexp>
<regexp value="Raspbian">
<info type="Linux" distrib="Raspbian"/>
</regexp>
<regexp value="\bKali\b">
<info type="Linux" distrib="Kali"/>
</regexp>
<regexp value="Rocky Linux">
<info type="Linux" distrib="Rocky"/>
</regexp>
<!-- BSD -->
<regexp value="FreeBSD">
@@ -167,11 +195,22 @@
<!-- Mac OSX -->
<regexp value="Mac[\-\_\ ]?OSX">
<regexp value="Mac[\-\_\ ]?OS ?X|macOS|Darwin">
<info type="Mac OSX"/>
</regexp>
<regexp value="Darwin">
<info type="Mac OSX"/>
<!-- *nix -->
<regexp value="SunOS|Solaris">
<info type="SunOS"/>
</regexp>
<regexp value="\bAIX\b">
<info type="AIX"/>
</regexp>
<regexp value="HP-UX|HPUX">
<info type="HP-UX"/>
</regexp>
</root>

View File

@@ -76,7 +76,7 @@
</regexp>
<regexp value="laravel_session">
<info technology="Laravel (PHP)"/>
<info technology="Laravel"/>
</regexp>
<regexp value="SESS[a-f0-9]{32}">

View File

@@ -62,4 +62,8 @@
<regexp value="Servlet[\-\_\/\ ]?([\d\.]+)">
<info technology="Servlet" tech_version="1"/>
</regexp>
<regexp value="Laravel">
<info technology="Laravel"/>
</regexp>
</root>

View File

@@ -417,7 +417,8 @@
</dbms>
<dbms value="Firebird">
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
<!--Firebird doesn't like big VARCHARs-->
<cast query="TRIM(CAST(%s AS VARCHAR(8000)))"/>
<length query="CHAR_LENGTH(TRIM(%s))"/>
<delimiter query="||"/>
<limit query="ROWS %d TO %d"/>
@@ -769,8 +770,8 @@
<is_dba query="SELECT CURRENT_USER='SA'"/>
<check_udf/>
<users>
<inband query="SELECT NAME FROM INFORMATION_SCHEMA.USERS"/>
<blind query="SELECT NAME FROM INFORMATION_SCHEMA.USERS LIMIT 1 OFFSET %d" count="SELECT COUNT(NAME) FROM INFORMATION_SCHEMA.USERS"/>
<inband query="SELECT USER_NAME FROM INFORMATION_SCHEMA.USERS" query2="SELECT NAME FROM INFORMATION_SCHEMA.USERS"/>
<blind query="SELECT USER_NAME FROM INFORMATION_SCHEMA.USERS LIMIT 1 OFFSET %d" count="SELECT COUNT(USER_NAME) FROM INFORMATION_SCHEMA.USERS" query2="SELECT NAME FROM INFORMATION_SCHEMA.USERS LIMIT 1 OFFSET %d" count2="SELECT COUNT(NAME) FROM INFORMATION_SCHEMA.USERS"/>
</users>
<passwords/>
<privileges/>
@@ -785,8 +786,8 @@
<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>
<blind query="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='%s' AND TABLE_SCHEMA='%s' ORDER BY COLUMN_NAME" query2="SELECT TYPE_NAME 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"/>
<inband query="SELECT COLUMN_NAME,TYPE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='%s' AND TABLE_SCHEMA='%s' ORDER BY COLUMN_NAME" 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"/>
<inband query="SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='%s' AND TABLE_SCHEMA='%s' ORDER BY COLUMN_NAME" condition="COLUMN_NAME" query2="SELECT COLUMN_NAME,TYPE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='%s' AND TABLE_SCHEMA='%s' ORDER BY COLUMN_NAME" condition2="COLUMN_NAME"/>
</columns>
<dump_table>
<blind query="SELECT %s FROM %s.%s ORDER BY %s LIMIT 1 OFFSET %d" count="SELECT COUNT(*) FROM %s.%s"/>

View File

@@ -521,7 +521,7 @@ def checkSqlInjection(place, parameter, value):
if ratio == 1.0:
continue
except (MemoryError, OverflowError):
except:
pass
# Perform the test's True request
@@ -1134,15 +1134,18 @@ def heuristicCheckSqlInjection(place, parameter):
if conf.beep:
beep()
for match in re.finditer(FI_ERROR_REGEX, page or ""):
if randStr1.lower() in match.group(0).lower():
infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % ("%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg)
try:
for match in re.finditer(FI_ERROR_REGEX, page or ""):
if randStr1.lower() in match.group(0).lower():
infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % ("%s " % paramType if paramType != parameter else "", parameter)
logger.info(infoMsg)
if conf.beep:
beep()
if conf.beep:
beep()
break
break
except (SystemError, RuntimeError) as ex:
logger.debug("Skipping FI heuristic due to regex failure: %s", getSafeExString(ex))
kb.disableHtmlDecoding = False
kb.heuristicMode = False

View File

@@ -170,6 +170,7 @@ from lib.core.settings import REFLECTED_REPLACEMENT_REGEX
from lib.core.settings import REFLECTED_REPLACEMENT_TIMEOUT
from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import REFLECTIVE_MISS_THRESHOLD
from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SENSITIVE_DATA_REGEX
from lib.core.settings import SENSITIVE_OPTIONS
from lib.core.settings import STDIN_PIPE_DASH
@@ -2204,19 +2205,19 @@ def safeStringFormat(format_, params):
while True:
match = re.search(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", retVal)
if match:
if count >= len(params):
warnMsg = "wrong number of parameters during string formatting. "
warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
raise SqlmapValueException(warnMsg)
else:
try:
retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count], retVal, 1)
except re.error:
retVal = retVal.replace(match.group(0), match.group(0) % params[count], 1)
count += 1
try:
retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count % len(params)], retVal, 1)
except re.error:
retVal = retVal.replace(match.group(0), match.group(0) % params[count % len(params)], 1)
count += 1
else:
break
if count > len(params) and count % len(params):
warnMsg = "wrong number of parameters during string formatting. "
warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
raise SqlmapValueException(warnMsg)
retVal = getText(retVal).replace(PARAMETER_PERCENTAGE_MARKER, '%')
return retVal
@@ -4149,6 +4150,11 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", encodeStringEscape(REFLECTED_REPLACEMENT_REGEX)))
# NOTE: special case when part of the result shares the same output as the payload (e.g. ?id=1... and "sqlmap/1.0-dev (http://sqlmap.org)")
preserve = extractRegexResult(r"%s(?P<result>.+?)%s" % (kb.chars.start, kb.chars.stop), content)
if preserve:
content = content.replace(preserve, REPLACEMENT_MARKER)
if regex != payload:
if all(part.lower() in content.lower() for part in filterNone(regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check
parts = regex.split(REFLECTED_REPLACEMENT_REGEX)
@@ -4219,6 +4225,9 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
debugMsg = "turning off reflection removal mechanism (for optimization purposes)"
logger.debug(debugMsg)
if preserve and retVal:
retVal = retVal.replace(REPLACEMENT_MARKER, preserve)
except (MemoryError, SystemError):
kb.reflectiveMechanism = False
if not suppressWarning:
@@ -5317,7 +5326,7 @@ def parseRequestFile(reqFile, checkParams=True):
_ = re.search(r"%s:.+" % re.escape(HTTP_HEADER.HOST), request)
if _:
host = _.group(0).strip()
if not re.search(r":\d+\Z", host):
if not re.search(r":\d+\Z", host) and int(port) != 80:
request = request.replace(host, "%s:%d" % (host, int(port)))
reqResList.append(request)
else:

View File

@@ -154,7 +154,7 @@ def rot13(data):
def decodeHex(value, binary=True):
"""
Returns a decoded representation of provided hexadecimal value
Returns a decoded representation of the provided hexadecimal value
>>> decodeHex("313233") == b"123"
True
@@ -182,7 +182,7 @@ def decodeHex(value, binary=True):
def encodeHex(value, binary=True):
"""
Returns a encoded representation of provided string value
Returns an encoded representation of the provided value
>>> encodeHex(b"123") == b"313233"
True
@@ -251,7 +251,7 @@ def decodeBase64(value, binary=True, encoding=None):
def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
"""
Returns a decoded representation of provided Base64 value
Returns a Base64 encoded representation of the provided value
>>> encodeBase64(b"123") == b"MTIz"
True
@@ -316,7 +316,7 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
retVal = value.encode(encoding, errors)
if unsafe:
retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal)
retVal = re.sub((r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER).encode(), lambda _: decodeHex(_.group(1)), retVal)
else:
try:
retVal = value.encode(encoding, errors)

View File

@@ -43,11 +43,11 @@ def cachedmethod(f):
def _f(*args, **kwargs):
parts = (
f.__module__ + "." + f.__name__,
"|".join(repr(a) for a in args),
"|".join("%s=%r" % (k, kwargs[k]) for k in sorted(kwargs))
"^".join(repr(a) for a in args),
"^".join("%s=%r" % (k, kwargs[k]) for k in sorted(kwargs))
)
try:
key = int(hashlib.md5("|".join(parts).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
key = int(hashlib.md5("`".join(parts).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
except ValueError: # https://github.com/sqlmapproject/sqlmap/issues/4281 (NOTE: non-standard Python behavior where hexdigest returns binary value)
result = f(*args, **kwargs)
else:

View File

@@ -567,7 +567,7 @@ class Dump(object):
else:
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<th>%s</th>" % getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace")))
dataToDumpFile(dumpFP, "<th onclick=\"sortTable(%d,this)\">%s</th>" % (field - 1, getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace"))))
field += 1
@@ -663,7 +663,7 @@ class Dump(object):
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
if conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "</tbody>\n</table>\n</body>\n</html>")
dataToDumpFile(dumpFP, "</tbody>\n</table>\n<script>let lc=-1,ld=1;function sortTable(n,h){var t=document.querySelector(\"table\"),r=Array.from(t.tBodies[0].rows);ld=(lc==n?-ld:1);lc=n;r.sort((a,b)=>{var x=a.cells[n].innerText.trim(),y=b.cells[n].innerText.trim(),nx=parseFloat(x),ny=parseFloat(y);return(!isNaN(nx)&&!isNaN(ny)?(nx-ny)*ld:x.localeCompare(y)*ld)});r.forEach(e=>t.tBodies[0].appendChild(e));Array.from(t.tHead.rows[0].cells).forEach(c=>{c.innerText=c.innerText.replace(/[\u2191\u2193]/g,\"\")});h.innerText=h.innerText+ (ld==1?\"\u2191\":\"\u2193\");}</script>\n</body>\n</html>")
else:
dataToDumpFile(dumpFP, "\n")
dumpFP.close()

View File

@@ -205,19 +205,19 @@ class HASH(object):
SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z'
SHA512_BASE64 = r'\A[a-zA-Z0-9+/]{86}==\Z'
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
# Reference: https://whatmyuseragent.com/brand/
class MOBILES(object):
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+")
GALAXY = ("Samsung Galaxy S8", "Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.0.0.50263AP")
GALAXY = ("Samsung Galaxy A54", "Mozilla/5.0 (Linux; Android 15; SM-A546B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.7339.155 Mobile Safari/537.36 AirWatchBrowser/25.08.0.2131")
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36")
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36")
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15063")
HTC = ("HTC One X2", "Mozilla/5.0 (Linux; Android 14; X2-HT) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.46 Mobile Safari/537.36")
HUAWEI = ("Huawei Honor 90 Pro", "Mozilla/5.0 (Linux; Android 15; REP-AN00 Build/HONORREP-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/133.0.6943.137 Mobile Safari/537.36")
IPHONE = ("Apple iPhone 15 Pro Max", "Mozilla/7.0 (iPhone; CPU iPhone OS 18_7; iPhone 15 Pro Max) AppleWebKit/533.2 (KHTML, like Gecko) CriOS/126.0.6478.35 Mobile/15E148 Safari/804.17")
LUMIA = ("Microsoft Lumia 950 XL", "Mozilla/5.0 (Windows Mobile 10; Android 10.0;Microsoft;Lumia 950XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Mobile Safari/537.36 Edge/40.15254.603")
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 10; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.117 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Mi 8 Pro", "Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36")
PIXEL = ("Google Pixel 9", "Mozilla/5.0 (Linux; Android 14; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/24.0 Chrome/139.0.0.0 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Redmi 15C", "Mozilla/5.0 (Linux; Android 15; REDMI 15C Build/AP3A.240905.015.A2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.118 Mobile Safari/537.36 XiaoMi/MiuiBrowser/14.43.0-gn")
class PROXY_TYPE(object):
HTTP = "HTTP"

View File

@@ -61,18 +61,6 @@ def runGui(parser):
else:
self.set(self.old_value)
# Reference: https://code.activestate.com/recipes/580726-tkinter-notebook-that-fits-to-the-height-of-every-/
class AutoresizableNotebook(_tkinter_ttk.Notebook):
def __init__(self, master=None, **kw):
_tkinter_ttk.Notebook.__init__(self, master, **kw)
self.bind("<<NotebookTabChanged>>", self._on_tab_changed)
def _on_tab_changed(self, event):
event.widget.update_idletasks()
tab = event.widget.nametowidget(event.widget.select())
event.widget.configure(height=tab.winfo_reqheight())
try:
window = _tkinter.Tk()
except Exception as ex:
@@ -81,11 +69,41 @@ def runGui(parser):
window.title(VERSION_STRING)
# Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
# Set theme and colors
bg_color = "#f5f5f5"
fg_color = "#333333"
accent_color = "#2c7fb8"
window.configure(background=bg_color)
# Configure styles
style = _tkinter_ttk.Style()
settings = {"TNotebook.Tab": {"configure": {"padding": [5, 1], "background": "#fdd57e"}, "map": {"background": [("selected", "#C70039"), ("active", "#fc9292")], "foreground": [("selected", "#ffffff"), ("active", "#000000")]}}}
style.theme_create("custom", parent="alt", settings=settings)
style.theme_use("custom")
# Try to use a more modern theme if available
available_themes = style.theme_names()
if 'clam' in available_themes:
style.theme_use('clam')
elif 'alt' in available_themes:
style.theme_use('alt')
# Configure notebook style
style.configure("TNotebook", background=bg_color)
style.configure("TNotebook.Tab",
padding=[10, 4],
background="#e1e1e1",
font=('Helvetica', 9))
style.map("TNotebook.Tab",
background=[("selected", accent_color), ("active", "#7fcdbb")],
foreground=[("selected", "white"), ("active", "white")])
# Configure button style
style.configure("TButton",
padding=4,
relief="flat",
background=accent_color,
foreground="white",
font=('Helvetica', 9))
style.map("TButton",
background=[('active', '#41b6c4')])
# Reference: https://stackoverflow.com/a/10018670
def center(window):
@@ -138,16 +156,16 @@ def runGui(parser):
config = {}
for key in window._widgets:
dest, type = key
dest, widget_type = key
widget = window._widgets[key]
if hasattr(widget, "get") and not widget.get():
value = None
elif type == "string":
elif widget_type == "string":
value = widget.get()
elif type == "float":
elif widget_type == "float":
value = float(widget.get())
elif type == "int":
elif widget_type == "int":
value = int(widget.get())
else:
value = bool(widget.var.get())
@@ -155,7 +173,9 @@ def runGui(parser):
config[dest] = value
for option in parser.option_list:
config[option.dest] = defaults.get(option.dest, None)
# Only set default if not already set by the user
if option.dest not in config or config[option.dest] is None:
config[option.dest] = defaults.get(option.dest, None)
handle, configFile = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.CONFIG, text=True)
os.close(handle)
@@ -183,12 +203,20 @@ def runGui(parser):
top = _tkinter.Toplevel()
top.title("Console")
top.configure(background=bg_color)
# Create a frame for the console
console_frame = _tkinter.Frame(top, bg=bg_color)
console_frame.pack(fill=_tkinter.BOTH, expand=True, padx=10, pady=10)
# Reference: https://stackoverflow.com/a/13833338
text = _tkinter_scrolledtext.ScrolledText(top, undo=True)
text = _tkinter_scrolledtext.ScrolledText(console_frame, undo=True, wrap=_tkinter.WORD,
bg="#2c3e50", fg="#ecf0f1",
insertbackground="white",
font=('Consolas', 10))
text.bind("<Key>", onKeyPress)
text.bind("<Return>", onReturnPress)
text.pack()
text.pack(fill=_tkinter.BOTH, expand=True)
text.focus()
center(top)
@@ -196,7 +224,6 @@ def runGui(parser):
while True:
line = ""
try:
# line = queue.get_nowait()
line = queue.get(timeout=.1)
text.insert(_tkinter.END, line)
except _queue.Empty:
@@ -206,9 +233,10 @@ def runGui(parser):
if not alive:
break
menubar = _tkinter.Menu(window)
# Create a menu bar
menubar = _tkinter.Menu(window, bg=bg_color, fg=fg_color)
filemenu = _tkinter.Menu(menubar, tearoff=0)
filemenu = _tkinter.Menu(menubar, tearoff=0, bg=bg_color, fg=fg_color)
filemenu.add_command(label="Open", state=_tkinter.DISABLED)
filemenu.add_command(label="Save", state=_tkinter.DISABLED)
filemenu.add_separator()
@@ -217,7 +245,7 @@ def runGui(parser):
menubar.add_command(label="Run", command=run)
helpmenu = _tkinter.Menu(menubar, tearoff=0)
helpmenu = _tkinter.Menu(menubar, tearoff=0, bg=bg_color, fg=fg_color)
helpmenu.add_command(label="Official site", command=lambda: webbrowser.open(SITE))
helpmenu.add_command(label="Github pages", command=lambda: webbrowser.open(GIT_PAGE))
helpmenu.add_command(label="Wiki pages", command=lambda: webbrowser.open(WIKI_PAGE))
@@ -226,59 +254,173 @@ def runGui(parser):
helpmenu.add_command(label="About", command=lambda: _tkinter_messagebox.showinfo("About", "Copyright (c) 2006-2025\n\n (%s)" % DEV_EMAIL_ADDRESS))
menubar.add_cascade(label="Help", menu=helpmenu)
window.config(menu=menubar)
window.config(menu=menubar, bg=bg_color)
window._widgets = {}
notebook = AutoresizableNotebook(window)
# Create header frame
header_frame = _tkinter.Frame(window, bg=bg_color, height=60)
header_frame.pack(fill=_tkinter.X, pady=(0, 5))
header_frame.pack_propagate(0)
first = None
frames = {}
# Add header label
title_label = _tkinter.Label(header_frame, text="Configuration",
font=('Helvetica', 14),
fg=accent_color, bg=bg_color)
title_label.pack(side=_tkinter.LEFT, padx=15)
# Add run button in header
run_button = _tkinter_ttk.Button(header_frame, text="Run", command=run, width=12)
run_button.pack(side=_tkinter.RIGHT, padx=15)
# Create notebook
notebook = _tkinter_ttk.Notebook(window)
notebook.pack(expand=1, fill="both", padx=5, pady=(0, 5))
# Store tab information for background loading
tab_frames = {}
tab_canvases = {}
tab_scrollable_frames = {}
tab_groups = {}
# Create empty tabs with scrollable areas first (fast)
for group in parser.option_groups:
frame = frames[group.title] = _tkinter.Frame(notebook, width=200, height=200)
notebook.add(frames[group.title], text=group.title)
# Create a frame with scrollbar for the tab
tab_frame = _tkinter.Frame(notebook, bg=bg_color)
tab_frames[group.title] = tab_frame
_tkinter.Label(frame).grid(column=0, row=0, sticky=_tkinter.W)
# Create a canvas with scrollbar
canvas = _tkinter.Canvas(tab_frame, bg=bg_color, highlightthickness=0)
scrollbar = _tkinter_ttk.Scrollbar(tab_frame, orient="vertical", command=canvas.yview)
scrollable_frame = _tkinter.Frame(canvas, bg=bg_color)
# Store references
tab_canvases[group.title] = canvas
tab_scrollable_frames[group.title] = scrollable_frame
tab_groups[group.title] = group
# Configure the canvas scrolling
scrollable_frame.bind(
"<Configure>",
lambda e, canvas=canvas: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
# Pack the canvas and scrollbar
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# Add the tab to the notebook
notebook.add(tab_frame, text=group.title)
# Add a loading indicator
loading_label = _tkinter.Label(scrollable_frame, text="Loading options...",
font=('Helvetica', 12),
fg=accent_color, bg=bg_color)
loading_label.pack(expand=True)
# Function to populate a tab in the background
def populate_tab(tab_name):
group = tab_groups[tab_name]
scrollable_frame = tab_scrollable_frames[tab_name]
canvas = tab_canvases[tab_name]
# Remove loading indicator
for child in scrollable_frame.winfo_children():
child.destroy()
# Add content to the scrollable frame
row = 0
row = 1
if group.get_description():
_tkinter.Label(frame, text="%s:" % group.get_description()).grid(column=0, row=1, columnspan=3, sticky=_tkinter.W)
_tkinter.Label(frame).grid(column=0, row=2, sticky=_tkinter.W)
row += 2
desc_label = _tkinter.Label(scrollable_frame, text=group.get_description(),
wraplength=600, justify="left",
font=('Helvetica', 9),
fg="#555555", bg=bg_color)
desc_label.grid(row=row, column=0, columnspan=3, sticky="w", padx=10, pady=(10, 5))
row += 1
for option in group.option_list:
_tkinter.Label(frame, text="%s " % parser.formatter._format_option_strings(option)).grid(column=0, row=row, sticky=_tkinter.W)
# Option label
option_label = _tkinter.Label(scrollable_frame,
text=parser.formatter._format_option_strings(option) + ":",
font=('Helvetica', 9),
fg=fg_color, bg=bg_color,
anchor="w")
option_label.grid(row=row, column=0, sticky="w", padx=10, pady=2)
# Input widget
if option.type == "string":
widget = _tkinter.Entry(frame)
widget = _tkinter.Entry(scrollable_frame, font=('Helvetica', 9),
relief="sunken", bd=1, width=20)
widget.grid(row=row, column=1, sticky="w", padx=5, pady=2)
elif option.type == "float":
widget = ConstrainedEntry(frame, regex=r"\A\d*\.?\d*\Z")
widget = ConstrainedEntry(scrollable_frame, regex=r"\A\d*\.?\d*\Z",
font=('Helvetica', 9),
relief="sunken", bd=1, width=10)
widget.grid(row=row, column=1, sticky="w", padx=5, pady=2)
elif option.type == "int":
widget = ConstrainedEntry(frame, regex=r"\A\d*\Z")
widget = ConstrainedEntry(scrollable_frame, regex=r"\A\d*\Z",
font=('Helvetica', 9),
relief="sunken", bd=1, width=10)
widget.grid(row=row, column=1, sticky="w", padx=5, pady=2)
else:
var = _tkinter.IntVar()
widget = _tkinter.Checkbutton(frame, variable=var)
widget = _tkinter.Checkbutton(scrollable_frame, variable=var,
bg=bg_color, activebackground=bg_color)
widget.var = var
widget.grid(row=row, column=1, sticky="w", padx=5, pady=2)
first = first or widget
widget.grid(column=1, row=row, sticky=_tkinter.W)
# Help text (truncated to improve performance)
help_text = option.help
if len(help_text) > 100:
help_text = help_text[:100] + "..."
help_label = _tkinter.Label(scrollable_frame, text=help_text,
font=('Helvetica', 8),
fg="#666666", bg=bg_color,
wraplength=400, justify="left")
help_label.grid(row=row, column=2, sticky="w", padx=5, pady=2)
# Store widget reference
window._widgets[(option.dest, option.type)] = widget
# Set default value
default = defaults.get(option.dest)
if default:
if hasattr(widget, "insert"):
widget.insert(0, default)
_tkinter.Label(frame, text=" %s" % option.help).grid(column=2, row=row, sticky=_tkinter.W)
elif hasattr(widget, "var"):
widget.var.set(1 if default else 0)
row += 1
_tkinter.Label(frame).grid(column=0, row=row, sticky=_tkinter.W)
# Add some padding at the bottom
_tkinter.Label(scrollable_frame, bg=bg_color, height=1).grid(row=row, column=0)
notebook.pack(expand=1, fill="both")
notebook.enable_traversal()
# Update the scroll region after adding all widgets
canvas.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
first.focus()
# Update the UI to show the tab is fully loaded
window.update_idletasks()
# Function to populate tabs in the background
def populate_tabs_background():
for tab_name in tab_groups.keys():
# Schedule each tab to be populated with a small delay between them
window.after(100, lambda name=tab_name: populate_tab(name))
# Start populating tabs in the background after a short delay
window.after(500, populate_tabs_background)
# Set minimum window size
window.update()
window.minsize(800, 500)
# Center the window on screen
center(window)
# Start the GUI
window.mainloop()

View File

@@ -939,8 +939,8 @@ def _setPreprocessFunctions():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle)
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(req):\n pass\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
openFile(filename, "w+").write("#!/usr/bin/env\n\ndef preprocess(req):\n pass\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+").write("pass")
errMsg = "function 'preprocess(req)' "
errMsg += "in preprocess script '%s' " % script

View File

@@ -19,7 +19,7 @@ from lib.core.enums import OS
from thirdparty import six
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.9.9.2"
VERSION = "1.9.12.8"
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)
@@ -61,7 +61,7 @@ LOWER_RATIO_BOUND = 0.02
UPPER_RATIO_BOUND = 0.98
# For filling in case of dumb push updates
DUMMY_JUNK = "ahy9Ouge"
DUMMY_JUNK = "Aich8ooT"
# Markers for special cases when parameter values contain html encoded characters
PARAMETER_AMP_MARKER = "__PARAMETER_AMP__"
@@ -941,6 +941,7 @@ td{
}
th{
font-size:12px;
cursor:pointer;
}
</style>"""

View File

@@ -110,7 +110,7 @@ def update():
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "core", "settings.py")
if os.path.isfile(filepath):
with openFile(filepath, "rb") as f:
with openFile(filepath, "r") as f:
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
logger.info("updated to the latest version '%s#dev'" % version)
success = True

View File

@@ -76,16 +76,10 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
redurl = self._get_header_redirect(headers) if not conf.ignoreRedirects else None
try:
content = fp.read(MAX_CONNECTION_TOTAL_SIZE)
content = fp.fp.read(MAX_CONNECTION_TOTAL_SIZE)
fp.fp = io.BytesIO(content)
except: # e.g. IncompleteRead
content = b""
finally:
if content:
try: # try to write it back to the read buffer so we could reuse it in further steps
fp.fp._rbuf.truncate(0)
fp.fp._rbuf.write(content)
except:
pass
content = decodePage(content, headers.get(HTTP_HEADER.CONTENT_ENCODING), headers.get(HTTP_HEADER.CONTENT_TYPE))
@@ -194,7 +188,7 @@ class SmartRedirectHandler(_urllib.request.HTTPRedirectHandler):
result.redurl = getUnicode(redurl) if six.PY3 else redurl
return result
http_error_301 = http_error_303 = http_error_307 = http_error_302
http_error_301 = http_error_303 = http_error_307 = http_error_308 = http_error_302
def _infinite_loop_check(self, req):
if hasattr(req, 'redirect_dict') and (req.redirect_dict.get(req.get_full_url(), 0) >= MAX_SINGLE_URL_REDIRECTIONS or len(req.redirect_dict) >= MAX_TOTAL_REDIRECTIONS):

View File

@@ -221,7 +221,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
markingValue = "'%s'" % CHAR_INFERENCE_MARK
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
forgedPayload = agent.extractPayload(payload) or ""
forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue)).replace(markingValue, unescapedCharValue)
forgedPayload = forgedPayload.replace(markingValue, unescapedCharValue)
forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue))
result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
incrementCounter(getTechnique())
@@ -246,7 +247,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# e.g.: ... > '%c' -> ... > ORD(..)
markingValue = "'%s'" % CHAR_INFERENCE_MARK
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(value))
forgedPayload = safeStringFormat(validationPayload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
forgedPayload = validationPayload.replace(markingValue, unescapedCharValue)
forgedPayload = safeStringFormat(forgedPayload, (expressionUnescaped, idx))
result = not Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
@@ -352,7 +354,8 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
# e.g.: ... > '%c' -> ... > ORD(..)
markingValue = "'%s'" % CHAR_INFERENCE_MARK
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
forgedPayload = payload.replace(markingValue, unescapedCharValue)
forgedPayload = safeStringFormat(forgedPayload, (expressionUnescaped, idx))
falsePayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, NULL)
if timeBasedCompare:

View File

@@ -107,12 +107,23 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
for _page in (page or "", (page or "").replace('\\"', '"')):
if Backend.isDbms(DBMS.MSSQL):
output = extractRegexResult(r"%s(?P<result>.*)%s" % (kb.chars.start, kb.chars.stop), removeReflectiveValues(_page, payload))
if output:
try:
retVal = ""
fields = re.findall(r'"([^"]+)":', extractRegexResult(r"{(?P<result>[^}]+)}", output))
for row in json.loads(output):
retVal += "%s%s%s" % (kb.chars.start, kb.chars.delimiter.join(getUnicode(row[field] or NULL) for field in fields), kb.chars.stop)
retVal = None
output_decoded = htmlUnescape(output)
json_data = json.loads(output_decoded, object_pairs_hook=OrderedDict)
if not isinstance(json_data, list):
json_data = [json_data]
if json_data and isinstance(json_data[0], dict):
fields = list(json_data[0].keys())
if fields:
retVal = ""
for row in json_data:
retVal += "%s%s%s" % (kb.chars.start, kb.chars.delimiter.join(getUnicode(row.get(field) or NULL) for field in fields), kb.chars.stop)
except:
retVal = None
else:

View File

@@ -103,6 +103,10 @@ class Fingerprint(GenericFingerprint):
else:
setDbms(DBMS.H2)
result = inject.checkBooleanExpression("JSON_OBJECT() IS NOT NULL")
version = '2' if result else '1'
Backend.setVersion(version)
self.getBanner()
return True

View File

@@ -16,6 +16,8 @@ from lib.core.common import dataToOutFile
from lib.core.common import decloakToTemp
from lib.core.common import decodeDbmsHexValue
from lib.core.common import isListLike
from lib.core.common import isNoneValue
from lib.core.common import isNullValue
from lib.core.common import isNumPosStrValue
from lib.core.common import isStackingAvailable
from lib.core.common import isTechniqueAvailable
@@ -243,8 +245,9 @@ class Filesystem(object):
kb.fileReadMode = False
if fileContent in (None, "") and not Backend.isDbms(DBMS.PGSQL):
if (isNoneValue(fileContent) or isNullValue(fileContent)) and not Backend.isDbms(DBMS.PGSQL):
self.cleanup(onlyFileTbl=True)
fileContent = None
elif isListLike(fileContent):
newFileContent = ""

View File

@@ -13,6 +13,7 @@ from lib.core.common import Backend
from lib.core.common import filterPairValues
from lib.core.common import getLimitRange
from lib.core.common import isAdminFromPrivileges
from lib.core.common import isDBMSVersionAtLeast
from lib.core.common import isInferenceAvailable
from lib.core.common import isNoneValue
from lib.core.common import isNullValue
@@ -104,6 +105,7 @@ class Users(object):
condition = (Backend.isDbms(DBMS.MSSQL) and Backend.isVersionWithin(("2005", "2008")))
condition |= (Backend.isDbms(DBMS.MYSQL) and not kb.data.has_information_schema)
condition |= (Backend.isDbms(DBMS.H2) and not isDBMSVersionAtLeast("2"))
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
if Backend.isDbms(DBMS.MYSQL) and Backend.isFork(FORK.DRIZZLE):

View File

@@ -347,6 +347,12 @@ def main():
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("httpcore", "typing.", "AttributeError")):
errMsg = "please update the 'httpcore' package (>= 1.0.8) "
errMsg += "(Reference: 'https://github.com/encode/httpcore/discussions/995')"
logger.critical(errMsg)
raise SystemExit
elif "invalid maximum character passed to PyUnicode_New" in excMsg and re.search(r"\A3\.[34]", sys.version) is not None:
errMsg = "please upgrade the Python version (>= 3.5) "
errMsg += "(Reference: 'https://bugs.python.org/issue18183')"
@@ -601,7 +607,7 @@ def main():
# short delay for thread finalization
_ = time.time()
while threading.active_count() > 1 and (time.time() - _) > THREAD_FINALIZATION_TIMEOUT:
while threading.active_count() > 1 and (time.time() - _) < THREAD_FINALIZATION_TIMEOUT:
time.sleep(0.01)
if cmdLineOptions.get("sqlmapShell"):