Compare commits

...
509 Commits
Author SHA1 Message Date
Miroslav Stampar 6b5db1f959 Fixes #3560 2019-04-01 09:47:36 +02:00
Miroslav Stampar d3959e926e Trivial update 2019-03-29 16:23:39 +01:00
Miroslav Stampar 23ff1cadab Adding SQLi vulnserver (for testing purposes) 2019-03-29 11:04:58 +01:00
Miroslav Stampar dbd93e2670 Minor refactoring (drei stuff) 2019-03-29 02:28:16 +01:00
Miroslav Stampar 89d13aaee4 Minor update 2019-03-29 01:25:34 +01:00
Miroslav Stampar 09be7cb361 Patch for Python 2.6 2019-03-28 22:54:05 +01:00
Miroslav Stampar f8eed1f365 Minor update 2019-03-28 22:45:44 +01:00
Miroslav Stampar f82f1f912d Bug fix 2019-03-28 16:32:46 +01:00
Miroslav Stampar 015984a7f2 Minor patch (drei) 2019-03-28 16:06:34 +01:00
Miroslav Stampar 9b72545d09 Some more DREI stuff 2019-03-28 16:04:38 +01:00
Miroslav Stampar 4b020c4257 Some more drei stuff 2019-03-28 15:14:16 +01:00
Miroslav Stampar 49586ad6dd Fixes #3557 2019-03-28 14:13:52 +01:00
Miroslav Stampar 83d79692ac Couple of patches 2019-03-28 14:12:11 +01:00
Miroslav Stampar afe497a954 Dealing with basesting (one baby step closer to Py3 salvation) 2019-03-28 13:53:54 +01:00
Miroslav Stampar 915bc1fc99 Fixes #3556 2019-03-28 11:22:38 +01:00
Miroslav Stampar e56c422a8c Python3 is a game-changer and I won't loose my mind 2019-03-27 17:56:37 +01:00
Miroslav Stampar 41c3139c01 Trivial update 2019-03-27 17:39:21 +01:00
Miroslav Stampar b036fcc876 Junk removal (in preparing for py3) 2019-03-27 17:37:57 +01:00
Miroslav Stampar 7356293007 Minor update 2019-03-27 17:19:16 +01:00
Miroslav Stampar c27820dc0e Some more updates 2019-03-27 16:36:32 +01:00
Miroslav Stampar fbd42228f8 Foo and fo 2019-03-27 15:48:51 +01:00
Miroslav Stampar b278ee83c5 Minor update of aux script 2019-03-27 15:32:49 +01:00
Miroslav Stampar ffad7ed5fc Fixes #3555 2019-03-27 15:17:11 +01:00
Miroslav Stampar 557da5dee4 Bug fix (SOCKS4 patch) 2019-03-27 15:16:23 +01:00
Miroslav Stampar 2f53014685 God help us all with this Python3 non-sense 2019-03-27 13:33:46 +01:00
Miroslav Stampar 2dbd0267a1 Minor update 2019-03-27 03:05:53 +01:00
Miroslav Stampar b5c82c4685 Another 'six' update 2019-03-27 02:55:44 +01:00
Miroslav Stampar df5a5c6fe8 First official usage of 'six' 2019-03-27 02:46:59 +01:00
Miroslav Stampar 95a28f2701 Adding new 3rd party library 2019-03-27 02:08:43 +01:00
Miroslav Stampar dc20c4f058 Minor refactoring 2019-03-27 01:28:34 +01:00
Miroslav Stampar a21cbcb665 Some minor stuff for Py3 2019-03-27 00:58:12 +01:00
Miroslav Stampar 8d89389c36 StringIO is bad m'kay (python3 this and that) 2019-03-26 14:37:01 +01:00
Miroslav Stampar 4b75ca15e8 Fixes #3551 2019-03-26 12:57:11 +01:00
Miroslav Stampar 5037e43c99 Fixes #3550 2019-03-26 12:52:19 +01:00
Miroslav Stampar e64cc86fc4 Patch related to the #3524 2019-03-25 11:42:16 +01:00
Miroslav Stampar 9387a005e3 Fixes #3548 2019-03-25 11:17:25 +01:00
Miroslav Stampar 9dcd18e41c Fixes #3546 2019-03-25 11:12:18 +01:00
Miroslav Stampar 2d129f3e58 Finalizing #3545 2019-03-22 13:49:52 +01:00
Miroslav Stampar 5ced273b8a Minor cleanup 2019-03-21 16:40:20 +01:00
Miroslav Stampar 7d807bfdee Minor update for #3540 2019-03-21 16:35:48 +01:00
Miroslav Stampar 5a71210c8a Update regarding #2940 (PEP 394) 2019-03-21 14:00:09 +01:00
Miroslav Stampar ef5cb9a460 In preparation for #3545 2019-03-21 13:57:17 +01:00
Miroslav Stampar 14186d3150 Dumping checksum.md5 (The king is dead, long live the king) 2019-03-20 13:26:53 +01:00
Miroslav Stampar 8de2700edc Fixes #3543 2019-03-20 12:01:24 +01:00
Miroslav Stampar bf3edcfc1c Fixes #3542 2019-03-20 11:33:10 +01:00
Miroslav Stampar aa1020a3d1 Minor update 2019-03-19 15:23:11 +01:00
Miroslav Stampar e4d4861232 Minor update 2019-03-19 15:11:38 +01:00
Miroslav Stampar 46ee69023e Minor updates (#3536) 2019-03-19 14:48:12 +01:00
Miroslav Stampar 12602b8a51 doctest compatibility patch (#3536) 2019-03-19 14:23:28 +01:00
Miroslav Stampar 87237c82d3 Revamp of #3536 2019-03-19 14:07:39 +01:00
boyhack 340e250fb1 Support for chunked requests (#3536)
*  Add the `--chunk` option to send requests in chunks

* solve the httplib&urllib2 content-legnth

* remove info

* Solve the error caused by the mix of get mode and chunk

* add CHUNKED_KEYWORDS `union`
2019-03-19 13:26:29 +01:00
Miroslav Stampar 3b3774abaa Fixes #3538 2019-03-18 00:46:56 +01:00
Miroslav Stampar e7ffc8f9b1 Adding support for STDIN pipe (e.g. '... -r - ...') 2019-03-15 15:36:13 +01:00
Miroslav Stampar bf83a4d1f8 Fixes #3532 2019-03-15 11:14:06 +01:00
Miroslav Stampar 8ed5e88be6 Minor adjustments 2019-03-13 17:20:14 +01:00
Miroslav Stampar da1982c4af Das heuristiche abomination 2019-03-13 17:14:37 +01:00
Miroslav Stampar 196ac25284 Fixes #3534 2019-03-13 16:49:41 +01:00
Miroslav Stampar aecaa27839 Minor refactoring 2019-03-13 16:40:22 +01:00
Miroslav Stampar eb62397c92 Minor update of Oracle fingerprinting 2019-03-12 14:12:23 +01:00
Miroslav Stampar 136342231e Minor update of fingerprints 2019-03-12 14:10:34 +01:00
Miroslav Stampar 77e1383855 Minor patch 2019-03-12 12:26:38 +01:00
Miroslav Stampar 384f0b69ec Going to try updates to pypi push procedure 2019-03-12 12:24:11 +01:00
Miroslav Stampar 49c1816f02 Trivial update 2019-03-12 11:45:48 +01:00
Miroslav Stampar 9da489a7de Minor naming update 2019-03-12 11:05:27 +01:00
Miroslav Stampar 662a3c3d6f Minor update 2019-03-11 15:25:16 +01:00
Miroslav Stampar c7bb44b0a2 Switching from old odict (non-concise ordering compared to collections) to ordereddict 2019-03-11 14:36:01 +01:00
Miroslav Stampar f4338952ac Minor update of #3527 2019-03-11 11:38:16 +01:00
tothi a3fe4be6c5 add new tamper script substring2leftright.py (#3527) 2019-03-11 11:17:29 +01:00
Miroslav Stampar 729247fd95 Fixes #3525 2019-03-10 14:49:22 +01:00
Miroslav Stampar 2647ac9abb Bug fix (less queries to make - patching the patch 3544793) 2019-03-08 15:49:56 +01:00
Miroslav Stampar 9b9902bc6a Fixes #3522 2019-03-07 14:58:55 +01:00
Miroslav Stampar 6666188857 To prevent ugly unhandled cases like #3523 2019-03-07 14:55:25 +01:00
Miroslav Stampar 09e8c26f8a Fixes #3519 2019-03-06 17:35:19 +01:00
Miroslav Stampar 91348b28b4 Patch for #3519 2019-03-06 16:39:09 +01:00
Miroslav Stampar 663c15a1bf Minor patch related to the #3518 2019-03-06 12:31:06 +01:00
Miroslav Stampar 8189a10a5c Fixes #3517 2019-03-06 11:20:57 +01:00
Miroslav Stampar f81e427353 Minor patch of links 2019-03-05 15:34:09 +01:00
Miroslav Stampar 3f6b53f5f3 Fixes #3515 (and reimplements #1062) 2019-03-05 12:24:41 +01:00
Miroslav Stampar 59d97968a7 Fixes #3514 2019-03-04 16:36:19 +01:00
Miroslav Stampar b1ef5d520c Minor update 2019-03-04 15:58:24 +01:00
Miroslav Stampar 8cd257c893 Implementation for #3505 2019-03-04 15:24:12 +01:00
Miroslav Stampar 10977ca530 Fixes #3510 2019-03-04 13:21:57 +01:00
Miroslav Stampar cdd4007f11 Fixes #3502 2019-03-02 01:28:58 +01:00
Miroslav Stampar c89c1e7abf Fallback for --randomize in case of empty value 2019-02-28 02:29:13 +01:00
Miroslav Stampar 9ba4da8820 Implements #3500 2019-02-28 02:23:14 +01:00
Miroslav Stampar 58acc4a0bc Fixes #3503 2019-02-28 01:05:23 +01:00
Miroslav Stampar 034bac2a11 Fixes #3498 2019-02-26 01:36:56 +01:00
Miroslav Stampar 581e4103c0 Minor patch 2019-02-25 17:19:42 +01:00
Miroslav Stampar eb862d03eb Fixes #3496 2019-02-25 17:18:38 +01:00
Miroslav Stampar 1248fe5eee Bug fix (CFM tends to HTML encode non-alphanumeric chars in error reports - paths weren't recognized) 2019-02-21 02:50:11 +01:00
Miroslav Stampar daeb281e91 Minor update 2019-02-21 02:05:00 +01:00
Miroslav Stampar 514ab3cc30 Trivial update 2019-02-21 01:37:58 +01:00
Miroslav Stampar dc95558187 Fixes #373 2019-02-21 01:10:43 +01:00
Miroslav Stampar af890d639d Implementing switch --repair (Issue #2888) 2019-02-19 00:21:37 +01:00
Miroslav Stampar 8fe37f3564 Update for #3486 2019-02-15 17:08:55 +01:00
Miroslav Stampar 9789d65c19 Fixes #3487 2019-02-15 16:54:43 +01:00
Miroslav Stampar dfe6fe6060 Fixes #3489 2019-02-12 10:49:47 +01:00
Miroslav Stampar ba883b77df Better exception messages (including types) 2019-02-12 10:42:32 +01:00
Miroslav Stampar 27265f56ba Update for #3488 (found samples with Server: wts) 2019-02-11 15:58:25 +01:00
Miroslav Stampar ced9657d95 Patch for #3488 2019-02-11 10:53:04 +01:00
Infected Drake 47edf134a2 Create new detection script for WTS Firewall. (#3488) 2019-02-11 10:51:27 +01:00
Miroslav Stampar 8d46f67898 Fixes #3483 2019-02-09 23:27:55 +01:00
Miroslav Stampar 4d87b0ff67 Fixes #3467 and #3463 2019-02-09 23:18:08 +01:00
Miroslav Stampar 6f750f9529 Patch for --os-pwn on newer versions of Metasploit 2019-02-09 16:15:09 +01:00
Miroslav Stampar 9562502744 Potential patch for #3470 2019-02-09 15:49:52 +01:00
Miroslav Stampar b42c081c0e Fixes #3475 2019-02-09 15:11:06 +01:00
Miroslav Stampar 441a40e6e1 Couple of patches for #3479 2019-02-09 14:49:20 +01:00
Dhiraj Mishra 489390c3f8 ibm_webseal.py (#3479) 2019-02-09 14:44:04 +01:00
Miroslav Stampar 5b382adc15 Trivial PEP update 2019-02-07 17:34:51 +01:00
Miroslav Stampar ab32ad4f48 Fixes #3471 2019-02-07 17:33:16 +01:00
Miroslav Stampar 0a42d91934 Patch related to the last commit 2019-02-07 16:49:58 +01:00
Miroslav Stampar 5eb9f5729c Couple of patches related to the #3473 2019-02-07 16:45:16 +01:00
Miroslav Stampar 5b0d25ff25 Fixes #3469 2019-02-06 07:35:05 +01:00
Miroslav Stampar 4b00924826 Couple of updates regarding readline capabilities 2019-02-05 16:58:18 +01:00
Miroslav Stampar f9ee0f4c0a Trivial update 2019-02-05 14:02:52 +01:00
Miroslav Stampar 5077844dd9 Fixes #3468 2019-02-05 13:42:44 +01:00
Miroslav Stampar 6fe827f0a4 Fixes #3465 2019-02-04 16:05:16 +01:00
Miroslav Stampar 683b587fa5 Minor update 2019-02-04 15:54:57 +01:00
Miroslav Stampar bd74a201d5 Update regarding #3466 2019-02-04 15:49:13 +01:00
Miroslav Stampar 82aa481e06 Patch for IPv6 addresses (proper Host header) 2019-01-30 01:30:30 +01:00
Miroslav Stampar 1f375e418a Fixing unhandled exception message and removing sticky level logic 2019-01-30 00:45:38 +01:00
Miroslav Stampar ed26dc0235 Important patch for #3459 2019-01-29 23:44:58 +01:00
Miroslav Stampar e8f505b701 First memory leak patched (related to the #3459) 2019-01-29 17:40:06 +01:00
Miroslav Stampar dddff45adb Patch for --update progress 2019-01-29 14:59:31 +01:00
Miroslav Stampar b3777995b2 Minor patch for progress dots 2019-01-29 14:55:38 +01:00
Miroslav Stampar a52328bfba Adding new WAF script (Bekchy) 2019-01-29 14:29:58 +01:00
Miroslav Stampar a303d6712e Patch related to the #3455 2019-01-29 12:30:51 +01:00
Miroslav Stampar e01a7908aa Trivial renaming update 2019-01-26 12:36:03 +01:00
Miroslav Stampar 4b5457903a Minor update 2019-01-24 11:36:48 +01:00
Richard Fontana 78da395506 Add GPL Cooperation Commitment (#3445) 2019-01-24 11:07:13 +01:00
Miroslav Stampar 44a8242d2f Dummy commit to force md5-resum 2019-01-23 21:07:51 +01:00
neargle 66e2fc302c Add MySQL sys Schema in MYSQL_SYSTEM_DBS (#3443) 2019-01-23 20:58:53 +01:00
Miroslav Stampar bdc4457f34 Old exception handling format to new one 2019-01-22 14:09:13 +01:00
Miroslav Stampar ba356baab0 Minor stability patch for multi-threading console output (#3284) 2019-01-22 13:45:16 +01:00
Miroslav Stampar ae6235ce20 Fixes #3440 2019-01-22 13:06:13 +01:00
Miroslav Stampar ef8530af5b Fixing mess with template payloads and URI/JSON/XML/custom cases 2019-01-22 11:08:57 +01:00
Miroslav Stampar 3d88dc0a51 Fixes #3439 2019-01-22 10:12:17 +01:00
Miroslav Stampar a31ac0376d Minor refactoring related to last couple of commits 2019-01-22 03:14:23 +01:00
Miroslav Stampar 8f13bda035 Some more preparing for 2to3 (keys() is iter in 3) 2019-01-22 03:00:44 +01:00
Miroslav Stampar 1adc66b763 Dealing with deprecated next() 2019-01-22 02:47:06 +01:00
Miroslav Stampar 2c270ed250 One more 2to3 baby step 2019-01-22 02:29:52 +01:00
Miroslav Stampar 7074365f8e More refactoring like the last couple of commits 2019-01-22 02:08:02 +01:00
Miroslav Stampar fd705c3dff Baby steps 2019-01-22 01:28:24 +01:00
Miroslav Stampar db3bed3f44 Update related to the last commit 2019-01-22 01:20:27 +01:00
Miroslav Stampar 7672b9a0a2 Baby steps (2 to 3 at a time) 2019-01-22 00:40:48 +01:00
Miroslav Stampar 17b79cd21b Minor cleanup 2019-01-20 16:49:14 +01:00
Miroslav Stampar 36b69bbe79 More cleaning up 2019-01-20 15:34:30 +01:00
Miroslav Stampar daa915a6f2 Removing unusable WAF script 2019-01-20 15:26:57 +01:00
Miroslav Stampar 01dba5c505 Removing obsolete WAF 2019-01-20 15:13:43 +01:00
Miroslav Stampar b5db4dc15a Trivial update (comment) 2019-01-18 14:31:37 +01:00
Miroslav Stampar 915d2bdec0 Minor patch related to the 3438 2019-01-17 15:12:31 +01:00
Miroslav Stampar 7eb45b9d8f Patch related to the #3438 2019-01-17 15:06:00 +01:00
Miroslav Stampar 669afdd81b Adding new waf script 2019-01-16 14:38:50 +01:00
Miroslav Stampar 21ce71bee8 Removing junk 2019-01-16 10:32:56 +01:00
Miroslav Stampar 40f067aa17 Adding new WAF scripts (merging from identYwaf - same author) 2019-01-15 00:41:00 +01:00
Miroslav Stampar 6cdb90ddf8 Same sentence in Cloudflare (too) 2019-01-14 11:35:54 +01:00
Miroslav Stampar c0d4db3aba URI injection patch (on request by @bojanisc) 2019-01-13 12:07:46 +01:00
Miroslav Stampar d086b2aca0 Minor update of WAF scripts 2019-01-12 17:47:43 +01:00
Miroslav Stampar 7cf4b0e1d2 Too generic (removing) 2019-01-12 02:38:54 +01:00
Miroslav Stampar 660036c38b New WAF script 2019-01-12 01:56:18 +01:00
Miroslav Stampar 0a3144ebb5 New WAF script (Squarespace) 2019-01-12 00:15:13 +01:00
Miroslav Stampar 02d66db7e0 New WAF script (SiteGuard) 2019-01-11 23:00:28 +01:00
Miroslav Stampar c94bddd924 Adding new WAF script 2019-01-11 22:33:08 +01:00
Miroslav Stampar aea3749015 Dealing with FP for expressionengine.py 2019-01-11 12:35:35 +01:00
Miroslav Stampar 204c1950fc Fixes #3433 2019-01-10 16:43:06 +01:00
Miroslav Stampar 17be4d6374 Minor update 2019-01-10 16:05:46 +01:00
Miroslav Stampar d7ba7150ce Removing junk 2019-01-10 15:56:49 +01:00
Miroslav Stampar d31d2eeb27 Minor updates and removal of faulty denyall.py WAF script (junk - FP) 2019-01-10 15:35:52 +01:00
Miroslav Stampar c74c58c47e Varnish Cache is not a proof of Varnish WAF usage 2019-01-10 14:27:19 +01:00
Miroslav Stampar d16252e959 Removing junk 2019-01-10 14:19:20 +01:00
Miroslav Stampar 9fef4336b0 Minor update of safe3 WAF script 2019-01-10 14:19:03 +01:00
Miroslav Stampar aa7af33fd5 Update of airlock WAF script 2019-01-10 13:40:51 +01:00
Miroslav Stampar 241c6b02f0 Update of distil WAF script 2019-01-10 13:23:34 +01:00
Miroslav Stampar 915ee5ce53 Trivial file renaming 2019-01-10 13:06:35 +01:00
Miroslav Stampar beee81697c Removing some junk 2019-01-10 11:31:09 +01:00
Nicolas Bonnet 880545cad4 Fix incompatible errMsg for tor and osPwn args (#3432) 2019-01-10 11:28:10 +01:00
Miroslav Stampar 5274c88c7d Minor patch of --identify-waf mechanism 2019-01-09 16:26:11 +01:00
Miroslav Stampar 9a221470e7 Minor patch 2019-01-09 15:44:11 +01:00
Miroslav Stampar 256ec75580 Trivial update of banner 2019-01-09 15:12:16 +01:00
Miroslav Stampar debb64167a Minor update of WAF scripts 2019-01-08 15:36:28 +01:00
Miroslav Stampar 49514adcd9 Minor patch 2019-01-08 12:58:27 +01:00
Miroslav Stampar 02b78d2691 Update of WAF scripts 2019-01-08 12:41:05 +01:00
Miroslav Stampar 82e3c48c8c Removing junk 2019-01-08 11:17:42 +01:00
Miroslav Stampar 243b564b6a Minor updates to WAF scripts 2019-01-07 17:22:16 +01:00
Miroslav Stampar cb72223452 Minor patch 2019-01-07 16:23:18 +01:00
Miroslav Stampar bf207a7ea6 Minor improvement 2019-01-07 16:06:33 +01:00
Miroslav Stampar 3b4e44a38d Better results with following the redirect in identifyWaf phase 2019-01-07 16:05:59 +01:00
Miroslav Stampar 97cf5b9ace New WAF script 2019-01-07 15:52:22 +01:00
Miroslav Stampar ba617c49a4 Minor patch 2019-01-07 15:35:54 +01:00
Miroslav Stampar 929df9bc34 Minor update of WAF scripts 2019-01-07 15:29:35 +01:00
Miroslav Stampar 48cdc6a308 Wrong naming fix 2019-01-07 14:44:31 +01:00
Miroslav Stampar 3b7ef42b30 Goodbye junk 2019-01-07 14:23:20 +01:00
Miroslav Stampar bdddc5c333 Some more junk removal 2019-01-07 14:21:09 +01:00
Miroslav Stampar 8ceff3dcc7 Cleaning junk and updating asm.py WAF script 2019-01-07 14:13:29 +01:00
Miroslav Stampar fcfbc5d59f Removing junk 2019-01-07 13:56:37 +01:00
Miroslav Stampar 12883cac16 Minor update 2019-01-07 13:45:01 +01:00
Miroslav Stampar 9f75fd4fb8 New WAF scripts 2019-01-07 02:58:47 +01:00
Miroslav Stampar 54d0678cbe Adding new WAF scripts 2019-01-07 01:21:07 +01:00
Miroslav Stampar 30497acd0c Minor update of ExpressionEngine WAF script 2019-01-06 03:48:56 +01:00
Miroslav Stampar ed0420e635 Update of WAF script for Cloudfront 2019-01-06 03:22:15 +01:00
Miroslav Stampar 094ce29709 Removing useless netscaler WAF script (passive appliance) 2019-01-06 03:11:31 +01:00
Miroslav Stampar ddd8712c4f Trivial cleanup 2019-01-06 02:30:05 +01:00
Miroslav Stampar 37449262df Fixes #3425 2019-01-06 02:29:09 +01:00
Miroslav Stampar 45c699e9cf Minor patch 2019-01-06 00:37:30 +01:00
Miroslav Stampar e22fab1945 Minor update of PyPI info 2019-01-06 00:29:31 +01:00
Miroslav Stampar e3134cc965 Final preparation for 1.3 2019-01-05 23:14:28 +01:00
Miroslav Stampar 5957aad738 Update of checksums 2019-01-05 22:58:28 +01:00
Miroslav Stampar 4c4de54ad8 Prepare for 1.3 2019-01-05 21:48:39 +01:00
Miroslav Stampar 590e8ed5ae update_copyright_year() 2019-01-05 21:38:52 +01:00
Miroslav Stampar 12427ff6f8 Minor update 2019-01-05 21:29:59 +01:00
Miroslav Stampar 45d0010323 Most probably solves #3422 2018-12-31 01:20:43 +01:00
Miroslav Stampar e18b41fc82 Fixes #3421 2018-12-31 01:03:40 +01:00
Miroslav Stampar 586c461ae6 Minor patch 2018-12-31 01:01:19 +01:00
Miroslav Stampar c799e794f2 Minor update of modsecurity.py 2018-12-29 20:40:49 +01:00
Miroslav Stampar b31c264a59 Minor update 2018-12-28 20:49:40 +01:00
Miroslav Stampar a569f21ad7 Bug fix (--smoke hasn't tested wrapped functions) 2018-12-28 18:25:56 +01:00
Miroslav Stampar 8092551fa9 Minor refactoring 2018-12-28 18:22:44 +01:00
Miroslav Stampar 83972d405f Trivial text update 2018-12-28 17:54:58 +01:00
Miroslav Stampar de0df99d8e Update regarding #3418 (fallback for MsSQL's --passwords) 2018-12-28 00:41:48 +01:00
Miroslav Stampar ddee027afb Minor message update 2018-12-26 23:23:49 +01:00
Miroslav Stampar 6ce0350abc Fixes #3420 2018-12-26 22:12:13 +01:00
Miroslav Stampar 37de01e993 Fixes #3417 2018-12-23 10:18:27 +01:00
Miroslav Stampar 63cca82288 Fixes #3415 2018-12-23 09:58:04 +01:00
Denis 7d1c2633c9 Add contributed Ukrainian translation (#3414) 2018-12-23 09:24:53 +01:00
Miroslav Stampar 9564c8e8b1 Refactoring regarding casting warnings 2018-12-21 11:29:57 +01:00
Miroslav Stampar 5e099144d3 Minor message update 2018-12-21 10:38:27 +01:00
Miroslav Stampar a007cd30e5 Fixes #3412 2018-12-19 11:11:56 +01:00
Miroslav Stampar 4c9e0b9f1e Adding Bluedon WAF script 2018-12-18 00:35:08 +01:00
Miroslav Stampar 0c3fbc46df Adding Approach WAF script 2018-12-18 00:08:56 +01:00
Miroslav Stampar 107d9f90ad Minor message update 2018-12-17 23:41:04 +01:00
Miroslav Stampar daafe9b74a Bug fix (OR boolean based blind caused trouble to UNION with negative logic) 2018-12-17 23:25:23 +01:00
Miroslav Stampar 9727f0d691 Minor patch (--parse-errors with lots of HTML inside) 2018-12-17 22:49:09 +01:00
Miroslav Stampar 61e0459ec8 Minor update 2018-12-17 17:48:22 +01:00
Miroslav Stampar c5802a5367 Minor update related to the last commit 2018-12-17 17:43:11 +01:00
Miroslav Stampar 01d5da18e3 Adding experimental option --crack 2018-12-17 17:38:47 +01:00
Miroslav Stampar b288bfdbc3 Minor update 2018-12-17 17:03:51 +01:00
Miroslav Stampar 1e508547d8 Trivial console output update 2018-12-17 16:08:14 +01:00
Miroslav Stampar 4fe4c582c1 Minor output adjustments 2018-12-17 15:15:54 +01:00
Miroslav Stampar 28e7c8f378 Refactoring KeyboardInterrupt mess 2018-12-17 15:00:57 +01:00
Miroslav Stampar c497aa98ed Minor TCP optimization 2018-12-17 14:19:59 +01:00
Miroslav Stampar 4ba9e9397c One more update of DBMS error messages 2018-12-16 16:24:01 +01:00
Miroslav Stampar eedfa8c888 Another update of DBMS error messages 2018-12-16 16:00:04 +01:00
Miroslav Stampar c224ea0e37 Update of DBMS error messages 2018-12-16 15:20:46 +01:00
Miroslav Stampar f544554475 Bug fix (--forms with --url without protocol) 2018-12-16 02:56:31 +01:00
Miroslav Stampar c7c7e30130 Potential patch for #3374 2018-12-14 10:45:42 +01:00
Miroslav Stampar d1426a023f Fixes #3408 2018-12-14 10:09:40 +01:00
nil0x42 83a1b9b2e7 errors.xml: detect mysqli_*() errors. (#3407)
MySQL injection error message often happen with
mysqli_*() functions nowadays.
POC: https://duckduckgo.com/?q=%22warning..mysqli
2018-12-14 10:08:52 +01:00
Miroslav Stampar 38684ec220 Fixes #3403 2018-12-11 13:28:51 +01:00
Miroslav Stampar 2e5edce8b9 Fixes #3399 2018-12-10 15:22:53 +01:00
Miroslav Stampar a02662f03f Trivial cleanup 2018-12-10 14:53:53 +01:00
Miroslav Stampar 2c95b65eac Implementation for #2552 (sorry @mg98) 2018-12-10 14:53:11 +01:00
Miroslav Stampar e47c1aa61b Resolving some more hooking problems 2018-12-10 13:21:36 +01:00
Miroslav Stampar f81062d595 Resolving some more hooking problems 2018-12-10 13:20:34 +01:00
Miroslav Stampar ef911b6be4 Dummy commit (just to test hooks) 2018-12-10 13:10:01 +01:00
Miroslav Stampar 4f1b0787ed Commit hooks were disabled 2018-12-10 13:04:53 +01:00
Miroslav Stampar 070e173067 Another patch for #3389 (Fixes #3397) 2018-12-10 12:59:13 +01:00
Miroslav Stampar f04584bb68 Update of error message regexes 2018-12-07 11:22:53 +01:00
Miroslav Stampar 66d26f67bf Manual tagging (automatic tagging failed for some reason) 2018-12-07 10:06:31 +01:00
Miroslav Stampar 101d1f0d49 Fixes #3395 2018-12-03 23:18:52 +01:00
Miroslav Stampar 843126702d Fixes #3392 2018-12-03 23:12:45 +01:00
Miroslav Stampar 65f227fe65 Bug fix (privately reported: --technique=E --where='id=1') 2018-12-03 23:07:13 +01:00
Miroslav Stampar 536d9a597e Minor language update 2018-12-03 22:59:46 +01:00
Miroslav Stampar 0ce2128a9b Fixes #3394 2018-12-03 22:40:44 +01:00
Miroslav Stampar e7ed2bbcbb Fixes #3391) 2018-11-30 11:29:17 +01:00
Miroslav Stampar 560ff4154b Fixes #3388 (and refactors #1578) 2018-11-29 00:09:05 +01:00
Miroslav Stampar 1d0d5f1675 Fixes #3389 2018-11-28 23:09:13 +01:00
Miroslav Stampar f1a3c81aec Bug fix for handling of custom headers 2018-11-28 00:29:17 +01:00
Miroslav Stampar 277a4fa402 Potential patch for #3167 2018-11-26 23:40:47 +01:00
Miroslav Stampar 037db0f4a0 Fixes #3381 2018-11-23 15:55:05 +01:00
Miroslav Stampar 3f1bf742fc Fixes #3379 2018-11-22 08:07:27 +01:00
Miroslav Stampar abb911d741 Just for the sake of #3377 2018-11-19 09:53:09 +01:00
Miroslav Stampar dc5edf1a86 Patch regarding #3377 2018-11-19 09:52:09 +01:00
Miroslav Stampar e11febdcbc Fixes #3375 2018-11-19 09:44:13 +01:00
Miroslav Stampar f2af8861f9 Some more updates regarding #3140 2018-11-15 17:13:13 +01:00
Miroslav Stampar 2895e5c20f Initial commit for #3140 2018-11-15 15:27:17 +01:00
Miroslav Stampar b1e8c75672 Update README.md 2018-11-14 12:59:40 +01:00
Miroslav Stampar 6cc52cc12a Fixes #3366 2018-11-12 14:07:41 +01:00
Miroslav Stampar ddf353b86e Fixes #3357 2018-11-04 14:36:38 +01:00
Miroslav Stampar e6535d359d Update related to the #3358 2018-11-04 14:17:53 +01:00
Miroslav Stampar 90e381a5a5 Another update related to the #3356 2018-11-02 16:18:08 +01:00
Miroslav Stampar e99e9919cd Update related to the #3356 2018-11-02 15:44:44 +01:00
Miroslav Stampar dbdfbcc425 Adding dates to the start/end time 2018-11-01 22:59:20 +01:00
Miroslav Stampar 1d6832a84a Cosmetic update (not patch) related to the #3354 2018-11-01 22:41:33 +01:00
Miroslav Stampar 73d83280fe Minor patch (bounded injection case with leftover marker) 2018-11-01 22:24:36 +01:00
Miroslav Stampar 1bd8c519c3 Minor just in case update 2018-10-30 15:41:39 +01:00
Miroslav Stampar a4fdbf1343 Patch related to the #3348 2018-10-30 11:13:09 +01:00
Miroslav Stampar 130879fbf3 Minor patches 2018-10-30 10:37:39 +01:00
Miroslav Stampar db5ae9ae0b Minor update to #3326 (adding generic code >= 400) 2018-10-29 09:55:14 +01:00
Syed Afzal cc4833429f added china cache (#3326) 2018-10-29 09:51:18 +01:00
Miroslav Stampar 703b7079a4 Fixes #3319 2018-10-27 14:30:28 +02:00
Miroslav Stampar ef52ee977f Minor patch 2018-10-27 14:14:21 +02:00
Miroslav Stampar ba1b4c50be Trivial cleanup 2018-10-26 23:40:08 +02:00
Miroslav Stampar 1e7dfe11b4 Fixes #3318 2018-10-26 23:38:37 +02:00
Miroslav Stampar 92febd22a8 Minor update 2018-10-26 23:01:19 +02:00
Miroslav Stampar 83081b5e14 Minor patch related to the #3316 2018-10-26 14:00:51 +02:00
Miroslav Stampar f2035145fe Another update related to the #3316 2018-10-26 12:10:22 +02:00
Miroslav Stampar 48b407c0fa Updates regarding the #3316 2018-10-26 12:09:21 +02:00
Jennifer Torres 4466504f30 Lua-Nginx WAFs Bypass (#3316)
* Lua-Nginx WAFs Bypass

Lua-Nginx WAFs doesn't support processing for more than 100 parameters.
https://www.youtube.com/watch?v=JUvro7cqidY

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

Update header.

* Update luanginxwafbypass.py
2018-10-26 12:04:37 +02:00
Miroslav Stampar dc65afe65a Minor update related to the #3283 2018-10-24 16:33:23 +02:00
Miroslav Stampar 132e963b53 More general TypeMismatchException (for Hibernate too) 2018-10-24 15:12:13 +02:00
Miroslav Stampar f52beff7c3 Minor patch to handle late ImportError reports 2018-10-22 11:21:30 +02:00
Miroslav Stampar feb93dce44 Update related to the #3304 2018-10-17 12:24:52 +02:00
Miroslav Stampar e52422900e Fixes #3303 2018-10-16 19:37:27 +02:00
Miroslav Stampar c045afd842 Minor cleanup 2018-10-16 14:53:41 +02:00
Miroslav Stampar 0d2db32539 Finalizing #3283 2018-10-16 14:47:09 +02:00
Miroslav Stampar 77f4fd93e7 Minor leftover 2018-10-16 13:27:31 +02:00
Miroslav Stampar 68f5597b4a Some cleaning up for #3283 2018-10-16 13:26:55 +02:00
Miroslav Stampar 411f56e710 Initial implementation for #3283 2018-10-16 12:23:07 +02:00
Miroslav Stampar fb95ab8c17 Initial commit for #3283 (fixing H2 misidentification with PgSQL and/or HSQLDB) 2018-10-16 08:02:38 +02:00
Miroslav Stampar 9f6e04b141 Minor update of help text 2018-10-15 02:15:05 +02:00
Miroslav Stampar 1f2bdf5a3d Trivial message update 2018-10-15 00:56:23 +02:00
Miroslav Stampar 465a1e1a86 Minor update 2018-10-15 00:53:26 +02:00
Miroslav Stampar 6af127cb64 Fixes #3286 2018-10-14 22:17:10 +02:00
Miroslav Stampar 880d438418 Fixes #3284 2018-10-12 00:29:43 +02:00
Miroslav Stampar 5efe3228f8 Patch related to the #3282 2018-10-12 00:16:42 +02:00
Miroslav Stampar e005ba3f77 Minor patch 2018-10-11 23:59:09 +02:00
Miroslav Stampar f2b4dc3ffc Fixes #3275 2018-10-08 23:34:55 +02:00
Miroslav Stampar d1022f3f59 Fixes #3246 2018-10-04 13:51:41 +02:00
Miroslav Stampar 3984b94297 Fixes #3271 2018-10-04 13:42:13 +02:00
Miroslav Stampar eba01ee74e Just in case patch (for --api) 2018-10-03 12:46:40 +02:00
Miroslav Stampar 36b660309b Minor patch 2018-10-03 12:28:55 +02:00
Miroslav Stampar fd89fdf40b Minor cleaning up 2018-10-03 11:27:51 +02:00
Miroslav Stampar 2e53096962 Fixes #3268 2018-10-03 11:02:13 +02:00
Miroslav Stampar 79e45bd8d7 Minor update 2018-10-02 15:10:31 +02:00
Miroslav Stampar ed5f4abebd Minor updates 2018-10-02 14:56:20 +02:00
Miroslav Stampar 03bbfdbc56 Can't work out of the box (too many unknowns) 2018-10-02 14:11:26 +02:00
Miroslav Stampar 1b6365b195 Minor cleanup 2018-10-02 14:07:14 +02:00
Miroslav Stampar d38a0542d8 Minor update 2018-10-02 13:48:39 +02:00
Miroslav Stampar 9182b90b2b Removing an obsolete utility 2018-10-02 12:58:25 +02:00
Miroslav Stampar 80af22435a Update README.md 2018-10-02 12:21:29 +02:00
Miroslav Stampar 065c5e8157 Fixes #3264 2018-09-29 23:10:03 +02:00
Miroslav Stampar 932aa8dd94 Fixes #3262 2018-09-28 13:12:21 +02:00
Miroslav Stampar 71208e891c Update regarding #3258 2018-09-27 09:15:53 +02:00
Miroslav Stampar 3b369920a1 Minor patch related to the #3257 2018-09-26 15:33:34 +02:00
Miroslav Stampar 68a83098ab Update of THANKS (based on 2017 donation) 2018-09-25 14:06:32 +02:00
Miroslav Stampar f4a0820dcb Merging of tamper script arguments (e.g. --tamper A --tamper B -> --tamper=A,B) 2018-09-24 14:00:58 +02:00
Miroslav Stampar 459e1dd9a4 Update related to the #3252 2018-09-24 10:26:27 +02:00
Miroslav Stampar 4b698748f7 Fixes #3247 2018-09-21 23:25:25 +02:00
Miroslav Stampar e697354765 Fixing non-resumal of MsSQL/Sybase/MaxDB enumeration queries 2018-09-21 23:06:45 +02:00
Miroslav Stampar 721046831b Minor patch 2018-09-21 22:15:29 +02:00
Miroslav Stampar a4068f9abf Minor update 2018-09-20 16:52:02 +02:00
Miroslav Stampar 245c5e64e9 Minor cleanup 2018-09-19 11:13:59 +02:00
Miroslav Stampar cd08d13647 Adding a generic parameter replace payload 2018-09-19 11:05:55 +02:00
Miroslav Stampar 8abae02111 Improvement of anti-CSRF token extraction 2018-09-18 22:05:52 +02:00
Miroslav Stampar dd9bfd13f2 Trivial update 2018-09-18 17:03:27 +02:00
Miroslav Stampar 0c7eecee9f Trivial update (message language) 2018-09-18 16:52:17 +02:00
Miroslav Stampar 3e72da66f9 Minor update (preventing WAF specific response reports on generic 403) 2018-09-18 16:45:08 +02:00
Miroslav Stampar ca9a56c0ff Minor update of WebKnight WAF script 2018-09-15 23:27:24 +02:00
Miroslav Stampar 2d2b20344d Minor patch for bigip WAF script 2018-09-15 23:17:32 +02:00
Miroslav Stampar a8a7dee800 Fixes #3239 2018-09-15 21:36:21 +02:00
Miroslav Stampar 35d9ed8476 Cleaning a mess with stacked queries and pre-WHERE boundaries 2018-09-14 10:30:58 +02:00
Miroslav Stampar a5e3dce26f Proper naming 2018-09-14 10:01:31 +02:00
Miroslav Stampar 71448b1c16 Minor refactoring 2018-09-14 09:45:04 +02:00
Miroslav Stampar a633bc7f32 Trivial cleanup 2018-09-13 11:41:19 +02:00
Miroslav Stampar 6697e49f75 Adding aesecure and crawlprotect WAF scripts 2018-09-13 11:09:32 +02:00
xxbing db8bcd1d2e update xforwarder tamper (#3236) 2018-09-13 10:50:58 +02:00
Miroslav Stampar 16c052ef13 Fixes #3234 (user entered input) 2018-09-12 14:39:07 +02:00
Miroslav Stampar a8c0722631 Minor update regarding #3230 2018-09-10 12:43:59 +02:00
Miroslav Stampar c9a73aeed1 Minor patch for #3226 2018-09-10 11:51:00 +02:00
Miroslav Stampar 470b68a83c Implementation for Issue #3226 2018-09-10 11:47:19 +02:00
Miroslav Stampar f01ae291f8 Update related to the #3231 2018-09-10 10:27:28 +02:00
Ehsan Nezami c36749c3bb add u_pass to columns (#3231) 2018-09-10 10:26:28 +02:00
Miroslav Stampar 63b84c31e5 Update regarding the #3229 2018-09-08 23:36:08 +02:00
Miroslav Stampar ec253dd5bd Support for table name retrieval from mysql.innodb_table_stats (fallback if primary fails) 2018-09-07 11:53:43 +02:00
Miroslav Stampar 4c25a20efc Docstring update and smalldict update (merge with top1575) 2018-09-07 11:23:47 +02:00
Miroslav Stampar 2b56bdfaa6 Patch for MsSQL column name injection 2018-09-06 13:59:07 +02:00
Miroslav Stampar c37014b8e8 Implementation for an Issue #647 2018-09-06 00:59:29 +02:00
Miroslav Stampar 349e9b9fa5 Minor commit related to the #120 2018-09-06 00:16:59 +02:00
Miroslav Stampar ac481492c0 Final commit for #120 2018-09-05 23:29:52 +02:00
Miroslav Stampar 91c5151770 Another update related to the #120 2018-09-05 00:56:39 +02:00
Miroslav Stampar ad5a731999 First commit for Issue #120 2018-09-05 00:16:35 +02:00
Miroslav Stampar 95be19a692 Minor update 2018-09-05 00:15:15 +02:00
Miroslav Stampar dbcf030743 Accepting even dummy (e.g.) 'y' for --answers 2018-09-04 23:30:58 +02:00
Miroslav Stampar fa3f3baf1e Minor update 2018-09-04 23:24:40 +02:00
Miroslav Stampar f125f64a80 Minor style update (marker for empty cracked password) 2018-09-04 23:14:25 +02:00
Miroslav Stampar 12012b36b1 Automatic disabling of socket-preconnect for known problematic server (SimpleHTTPServer) 2018-09-04 23:01:17 +02:00
Miroslav Stampar 43c9e21c56 Performance improvement and reducing number of false-positives in heavily dynamic pages 2018-09-04 22:39:07 +02:00
Miroslav Stampar a831865633 Further narrowing down cloudfront WAF script (less FP on detection) 2018-08-30 17:44:37 +02:00
Miroslav Stampar 578c41f6de Fine tuning Incapsula WAF script 2018-08-30 16:49:06 +02:00
Miroslav Stampar dc01f2e773 Fine tuning of Cloudfrount WAF script (less FP) 2018-08-30 16:42:35 +02:00
Miroslav Stampar db327a8538 Minor update of WAF scripts 2018-08-30 16:19:31 +02:00
Miroslav Stampar aefb815064 Cutting down FP on Varnish WAF (ignoring Varnish Cache) 2018-08-30 16:02:27 +02:00
Miroslav Stampar 014978cebc Fine tuning Cloudflare WAF script 2018-08-30 16:00:40 +02:00
Miroslav Stampar 287371337d Update of ZENEDGE WAF script 2018-08-30 15:56:13 +02:00
Miroslav Stampar 62a3618353 Minor patches 2018-08-30 15:50:17 +02:00
Miroslav Stampar 366a3f9336 Detect redirect from stdout 2018-08-30 15:21:46 +02:00
Miroslav Stampar 74d2b60cf3 Minor colorization of WAF Detectify 2018-08-30 15:18:42 +02:00
Miroslav Stampar 9e892e93f3 Created a WAF Detectify utility 2018-08-30 14:54:15 +02:00
Miroslav Stampar 0bbf5f9467 Update of dotDefender WAF script 2018-08-29 12:21:33 +02:00
Miroslav Stampar 8be4b29fd1 Update of Incapsula WAF script 2018-08-29 12:13:22 +02:00
Miroslav Stampar 0507234add Minor update 2018-08-29 11:06:45 +02:00
Miroslav Stampar c3d9a1c2d4 Airlock also uses AL_SESS-S cookie 2018-08-29 10:56:24 +02:00
Miroslav Stampar 9e8b28be7c Minor patch (e.g. case: user's) 2018-08-28 14:33:48 +02:00
Miroslav Stampar f3f4a4cb37 Minor refactoring 2018-08-28 14:31:20 +02:00
Miroslav Stampar 2280f3ff2d Updating old links 2018-08-28 14:13:48 +02:00
Miroslav Stampar d6cf038e48 Fixes #3216 2018-08-25 22:57:49 +02:00
Miroslav Stampar 2dfc383700 Fixes #3215 2018-08-22 17:58:00 +02:00
Miroslav Stampar f20e7b403a Fixes #3211 2018-08-22 10:41:43 +02:00
Miroslav Stampar 36e62fe8a7 Minor update 2018-08-22 10:20:26 +02:00
Miroslav Stampar 2542b6d241 Minor patch (https version of site is not available) 2018-08-20 19:44:25 +02:00
Miroslav Stampar bc13d8923b Adding long_description to PyPI upload script 2018-08-20 19:43:27 +02:00
Miroslav Stampar e51db6b355 Update README.md 2018-08-20 19:33:19 +02:00
Miroslav Stampar 6d28ca1f93 Bug fix (single-quoted strings in long results caused line breaks) 2018-08-18 00:02:39 +02:00
Miroslav Stampar 03e4741a69 Trivial patch (display of used user queries) 2018-08-17 19:45:34 +02:00
Miroslav Stampar b899ab9eb3 Bug fix (sha-256,sha384... were recognized, though, not cracked) 2018-08-13 15:27:08 +02:00
Miroslav Stampar 2e017eee99 Fixes #3203 2018-08-10 14:16:27 +02:00
Miroslav Stampar a296d22195 Fixes #3205 2018-08-10 14:01:55 +02:00
Miroslav Stampar ad11749b15 One more payload (requires usage of --code or similar) 2018-08-09 16:21:35 +02:00
Miroslav Stampar 75a64245c5 Minor patch for colorization (multiple quoted strings in same line) 2018-08-09 16:21:04 +02:00
Miroslav Stampar 9e00202823 Minor patch (use redirection code for comparison) 2018-08-09 15:39:37 +02:00
Miroslav Stampar df977d93d4 Fixes #3204 2018-08-09 15:08:21 +02:00
Miroslav Stampar b0ca52086a Fixes #3202 2018-08-07 23:35:58 +02:00
Miroslav Stampar af89137f2c Update of WAF scripts 2018-08-05 14:19:27 +02:00
Miroslav Stampar 1f9bf587b5 Implementation for an Issue #3108 2018-07-31 02:18:33 +02:00
Miroslav Stampar f0e4c20004 First commit related to the #3108 2018-07-31 01:17:11 +02:00
Miroslav Stampar cef416559a Minor update 2018-07-31 00:20:52 +02:00
Miroslav Stampar ce47b6c76e Minor patch 2018-07-27 01:39:04 +02:00
Miroslav Stampar 39108bc100 Trivial refactoring of unused variables 2018-07-27 00:59:24 +02:00
Miroslav Stampar f63ceaa0c1 Minor refactoring 2018-07-27 00:53:14 +02:00
Miroslav Stampar 1e60378fb2 Minor refactoring 2018-07-27 00:30:30 +02:00
Miroslav Stampar 22c7bc54b4 Minor patch 2018-07-27 00:01:23 +02:00
Miroslav Stampar 5f1bae86b0 Fixes #3194 2018-07-19 18:00:56 +02:00
Miroslav Stampar a0cbf6991d Minor style update 2018-07-18 17:00:34 +02:00
Miroslav Stampar 9f2bc00426 Minor patch 2018-07-18 16:30:59 +02:00
Miroslav Stampar 6bb486c1bf Potential patch for #3192 2018-07-18 15:34:38 +02:00
Miroslav Stampar 741ce9e3f0 Trivial update (just to reset checksums) 2018-07-15 16:08:01 +02:00
Anastasios Stasinopoulos a479655097 Minor patch (--purge instead of --purge-output) (#3188) 2018-07-15 11:28:34 +02:00
Miroslav Stampar 4846d85ccd Pre-fetching latest revision number in case of update 2018-07-11 19:30:14 +02:00
Miroslav Stampar 3c439c3929 Known cause of majority of false-positives (Issue #3176) 2018-07-11 16:12:57 +02:00
Miroslav Stampar 5cc36a5736 Revert of last commit (Fixes #3179) 2018-07-10 15:54:06 +02:00
Miroslav Stampar 29dcdd3bef Potential patch for #3178 2018-07-10 15:35:07 +02:00
Miroslav Stampar 53eadb0af8 Fixes #3173 2018-07-09 12:22:51 +02:00
Miroslav Stampar 7b705b94e3 Fixes #3171 2018-07-09 12:20:18 +02:00
Miroslav Stampar 558484644a Minor refactoring 2018-07-06 16:22:19 +02:00
Miroslav Stampar e84142b6a9 Fixes #3172 2018-07-06 16:18:04 +02:00
Miroslav Stampar b44551230e Fixes #3165 2018-07-05 15:13:51 +02:00
Miroslav Stampar 4ecf6eee05 Minor style update 2018-07-05 14:21:32 +02:00
Miroslav Stampar 57be1856a6 Where things could go kaboom (changing terminal coloring) 2018-07-05 14:01:43 +02:00
Miroslav Stampar a424e4ab59 Fixes #3168 2018-07-02 13:09:25 +02:00
Miroslav Stampar 4660b816d5 Minor patch (fallback for masking of sensitive data) 2018-07-02 11:54:12 +02:00
Miroslav Stampar f92e1ebc40 Another trivial style update 2018-07-02 11:47:47 +02:00
Miroslav Stampar 48cd0421a6 Trivial style update 2018-07-02 11:41:36 +02:00
Miroslav Stampar 4b4f728d8e Updated MySQL active fingerprint payloads 2018-07-02 10:58:25 +02:00
Miroslav Stampar e8336ecfe1 Fix of a pesky often 'statistical model' retrieval 2018-06-29 23:57:20 +02:00
Miroslav Stampar 38ea0686a8 Minor patch (Issue #3149) 2018-06-29 22:48:43 +02:00
Miroslav Stampar 73b0de67b5 Fixes #3149 2018-06-29 22:37:57 +02:00
Miroslav Stampar fae97b3937 Another patch for #3164 2018-06-29 16:34:16 +02:00
Miroslav Stampar c0947846f4 Patch for #3164 2018-06-29 16:33:17 +02:00
Miroslav Stampar 5e2d0bd320 Minor patches (--purge instead of --purge-output) 2018-06-20 23:52:08 +02:00
Miroslav Stampar 4badb54607 Couple of small patches 2018-06-20 23:21:55 +02:00
Miroslav Stampar 29aaec8925 First part of checksum cleanup 2018-06-20 23:09:23 +02:00
Miroslav Stampar 27ff5d6fec Implementation of #3156 2018-06-20 23:04:58 +02:00
Miroslav Stampar 72ff6e24ff Minor wording update 2018-06-20 17:15:35 +02:00
Miroslav Stampar 717c451b8c Trivial style update 2018-06-20 15:21:42 +02:00
Miroslav Stampar e5968cae31 Fixes --profile 2018-06-20 13:51:03 +02:00
Miroslav Stampar 2b55ae3e2a Minor just in case update 2018-06-20 13:06:56 +02:00
Miroslav Stampar 8f4488d608 Minor patches related to the #739 2018-06-20 00:08:55 +02:00
Miroslav Stampar f1254fef4b Finalizes implementation for #739 2018-06-19 16:39:10 +02:00
Miroslav Stampar ccda26a567 Minor commit regarding #739 2018-06-19 16:23:17 +02:00
Miroslav Stampar 099110bc1f Minor commit regarding #739 2018-06-19 16:14:44 +02:00
Miroslav Stampar 0265b3fcfa Second commit regarding #739 2018-06-19 16:11:49 +02:00
Miroslav Stampar 961d2b24d1 First commit regarding #739 2018-06-19 16:08:38 +02:00
Miroslav Stampar 53578bcb7c Generic patch related to the #3153 2018-06-19 14:56:39 +02:00
Miroslav Stampar 756f02fb0e Fixes #3150 2018-06-15 14:22:24 +02:00
Miroslav Stampar 17c170e1f8 Fixes #3148 2018-06-13 23:51:09 +02:00
Miroslav Stampar 220c1be162 Fixes #3144 2018-06-12 23:02:38 +02:00
Miroslav Stampar 6b06332896 Fixes #3145 2018-06-12 22:45:16 +02:00
Miroslav Stampar c268663bd9 Minor code style updates 2018-06-09 23:38:00 +02:00
Miroslav Stampar a97fd1dede Fixes #3142 2018-06-09 22:59:08 +02:00
Miroslav Stampar b93284530e Patch related to the #3139 2018-06-08 15:13:50 +02:00
Miroslav Stampar cf4c263a4e Minor patch 2018-06-08 14:45:15 +02:00
Miroslav Stampar 23777143b6 Update related to the #3137 2018-06-07 10:07:12 +02:00
Miroslav Stampar 9b397f00be Minor refactoring 2018-06-07 01:28:02 +02:00
Miroslav Stampar d47c16e196 Minor refactoring 2018-06-07 00:55:32 +02:00
Miroslav Stampar e0c7b5c63c Minor wording update 2018-06-07 00:46:54 +02:00
Miroslav Stampar 091c8ab2dd Minor update (switching --invalid-logical to LIKE version) 2018-06-07 00:37:22 +02:00
Miroslav Stampar 86303bde55 Trivial update (wording) 2018-06-07 00:24:29 +02:00
Miroslav Stampar c89f119e1a Minor update 2018-06-05 01:12:50 +02:00
Miroslav Stampar 25369ca591 Adding new payload (HAVING boolean-based blind) 2018-06-05 00:59:47 +02:00
Miroslav Stampar a399b65033 Trivial update 2018-06-05 00:20:37 +02:00
Miroslav Stampar ed37ae1562 Adding new WAF script (Cloudbric) 2018-06-05 00:05:17 +02:00
Miroslav Stampar 5381d4d5be Minor update 2018-06-04 23:33:07 +02:00
Miroslav Stampar c1825b2651 Patch for #3130 2018-06-01 11:23:41 +02:00
Miroslav Stampar e7d448c56c Minor update regarding #3129 2018-06-01 10:21:59 +02:00
Miroslav Stampar 694b5bb5c0 New tamper script (per user request) 2018-05-30 15:48:16 +02:00
Miroslav Stampar eb498e6c03 Fixes #2819 2018-05-29 14:54:43 +02:00
Miroslav Stampar ca8b589d43 Fixes #3122 (by reverting 6c4e9ae427) 2018-05-29 14:26:31 +02:00
Miroslav Stampar 18706f7fad Minor patch for unhandled exception reports 2018-05-28 11:29:06 +02:00
Miroslav Stampar 80f3b9a711 Minor worflow change in case of unhandled exceptions (disregard --batch) 2018-05-28 11:10:42 +02:00
Miroslav Stampar 6b3f01bfeb Minor patch 2018-05-28 11:07:06 +02:00
Miroslav Stampar 42042fb5de Removing encoding report part (enough time has been passed to collect major problems) 2018-05-24 10:41:20 +02:00
Miroslav Stampar 2abc7fc588 Update related to the #3116 (consistency patch) 2018-05-24 10:13:13 +02:00
German 1ecc326714 Russian localization readme (#3116)
* add russian doc readme

* add link head readme
2018-05-24 10:11:09 +02:00
Miroslav Stampar d2d829abf5 Patch related to the #3117 2018-05-24 10:07:35 +02:00
Miroslav Stampar 43d9ac2bd4 Patch related to the #3101 2018-05-21 23:44:21 +02:00
Miroslav Stampar d8196cf7e6 Fixes #3110 2018-05-21 23:17:32 +02:00
Miroslav Stampar 42b0edca6d Fixes #3109 2018-05-19 12:35:39 +02:00
Miroslav Stampar 331ccc5549 Fixes #3100 2018-05-17 23:07:52 +02:00
Miroslav Stampar d5627fdf1b Fixes #3099 2018-05-15 12:15:47 +02:00
Miroslav Stampar 7b3a17bfe7 Patch for #3068 2018-05-09 13:38:39 +02:00
Miroslav Stampar 4a8f01c9dc Minor updates 2018-05-08 14:06:34 +02:00
Miroslav Stampar 13bf3e649a Trivial refactoring 2018-05-08 12:09:24 +02:00
Miroslav Stampar 9a63fb1055 Trivial refactoring 2018-05-08 11:59:56 +02:00
Miroslav Stampar 3544793961 Fixes #3088 2018-05-07 10:48:35 +02:00
Miroslav Stampar 7a8add0412 Update regarding #3068 2018-05-05 14:49:35 +02:00
Miroslav Stampar 1d382bcb4d Fixes #3086 2018-05-05 14:33:00 +02:00
Miroslav Stampar ec6ad3ce68 Bug fix (non-digit --union-char has not been working properly) 2018-05-05 14:22:06 +02:00
Miroslav Stampar 73d8952f2a Potential patch for #3084 2018-05-04 16:29:36 +02:00
Miroslav Stampar 2a810fb796 Trivial modifications (thou shalt not judge people by trivial commits) 2018-05-03 14:10:55 +02:00
466 changed files with 9561 additions and 7824 deletions
+2
View File
@@ -3,6 +3,8 @@
*.md5 text eol=lf
*.py text eol=lf
*.xml text eol=lf
LICENSE text eol=lf
COMMITMENT text eol=lf
*_ binary
*.dll binary
+1 -1
View File
@@ -19,7 +19,7 @@
* Client OS (e.g. `Microsoft Windows 10`)
* Program version (`python sqlmap.py --version` or `sqlmap --version` depending on installation):
* Target DBMS (e.g. `Microsoft SQL Server`):
* Detected WAF/IDS/IPS protection (e.g. `ModSecurity` or `unknown`):
* Detected WAF/IPS protection (e.g. `ModSecurity` or `unknown`):
* SQLi techniques found by sqlmap (e.g. `error-based` and `boolean-based blind`):
* Results of manual target assessment (e.g. found that the payload `query=test' AND 4113 IN ((SELECT 'foobar'))-- qKLV` works):
* Relevant console output (if any):
+46
View File
@@ -0,0 +1,46 @@
GPL Cooperation Commitment
Version 1.0
Before filing or continuing to prosecute any legal proceeding or claim
(other than a Defensive Action) arising from termination of a Covered
License, we commit to extend to the person or entity ('you') accused
of violating the Covered License the following provisions regarding
cure and reinstatement, taken from GPL version 3. As used here, the
term 'this License' refers to the specific Covered License being
enforced.
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly
and finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some
reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you
have received notice of violation of this License (for any work)
from that copyright holder, and you cure the violation prior to 30
days after your receipt of the notice.
We intend this Commitment to be irrevocable, and binding and
enforceable against us and assignees of or successors to our
copyrights.
Definitions
'Covered License' means the GNU General Public License, version 2
(GPLv2), the GNU Lesser General Public License, version 2.1
(LGPLv2.1), or the GNU Library General Public License, version 2
(LGPLv2), all as published by the Free Software Foundation.
'Defensive Action' means a legal proceeding or claim that We bring
against you in response to a prior proceeding or claim initiated by
you or your affiliate.
'We' means each contributor to this repository as of the date of
inclusion of this file, including subsidiaries of a corporate
contributor.
This work is available under a Creative Commons Attribution-ShareAlike
4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/).
+1 -1
View File
@@ -1,7 +1,7 @@
COPYING -- Describes the terms under which sqlmap is distributed. A copy
of the GNU General Public License (GPL) is appended to this file.
sqlmap is (C) 2006-2018 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
sqlmap is (C) 2006-2019 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
This program is free software; you may redistribute and/or modify it under
the terms of the GNU General Public License as published by the Free
+4 -2
View File
@@ -1,10 +1,10 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-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 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 lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/?utm_source=github.com&utm_medium=referral&utm_content=sqlmap+repo&utm_campaign=generic+advert).**
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/scan-website-security-issues/?utm_source=sqlmap.org&utm_medium=banner&utm_campaign=github).**
Screenshots
----
@@ -64,5 +64,7 @@ Translations
* [Japanese](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-ja-JP.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)
* [Spanish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-es-MX.md)
* [Turkish](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-tr-TR.md)
* [Ukrainian](https://github.com/sqlmapproject/sqlmap/blob/master/doc/translations/README-uk-UA.md)
+4 -4
View File
@@ -3,7 +3,7 @@
* Implemented support for automatic decoding of page content through detected charset.
* Implemented mechanism for proper data dumping on DBMSes not supporting `LIMIT/OFFSET` like mechanism(s) (e.g. Microsoft SQL Server, Sybase, etc.).
* Major improvements to program stabilization based on user reports.
* Added new tampering scripts avoiding popular WAF/IPS/IDS mechanisms.
* Added new tampering scripts avoiding popular WAF/IPS mechanisms.
* Fixed major bug with DNS leaking in Tor mode.
* Added wordlist compilation made of the most popular cracking dictionaries.
* Implemented multi-processor hash cracking routine(s).
@@ -23,7 +23,7 @@
* Added option `--csv-del` for manually setting delimiting character used in CSV output.
* Added switch `--hex` for using DBMS hex conversion function(s) for data retrieval.
* Added switch `--smart` for conducting through tests only in case of positive heuristic(s).
* Added switch `--check-waf` for checking of existence of WAF/IPS/IDS protection.
* Added switch `--check-waf` for checking of existence of WAF/IPS protection.
* Added switch `--schema` to enumerate DBMS schema: shows all columns of all databases' tables.
* Added switch `--count` to count the number of entries for a specific table or all database(s) tables.
* Major improvements to switches `--tables` and `--columns`.
@@ -55,7 +55,7 @@
* Added option `--host` to set the HTTP Host header value.
* Added switch `--hostname` to turn on retrieval of DBMS server hostname.
* Added switch `--hpp` to turn on the usage of HTTP parameter pollution WAF bypass method.
* Added switch `--identify-waf` for turning on the thorough testing of WAF/IPS/IDS protection.
* Added switch `--identify-waf` for turning on the thorough testing of WAF/IPS protection.
* Added switch `--ignore-401` to ignore HTTP Error Code 401 (Unauthorized).
* Added switch `--invalid-bignum` for usage of big numbers while invalidating values.
* Added switch `--invalid-logical` for usage of logical operations while invalidating values.
@@ -78,7 +78,7 @@
* Added option `--skip` to skip testing of given parameter(s).
* Added switch `--skip-static` to skip testing parameters that not appear to be dynamic.
* Added switch `--skip-urlencode` to skip URL encoding of payload data.
* Added switch `--skip-waf` to skip heuristic detection of WAF/IPS/IDS protection.
* Added switch `--skip-waf` to skip heuristic detection of WAF/IPS protection.
* Added switch `--smart` to conduct thorough tests only if positive heuristic(s).
* Added option `--sql-file` for setting file(s) holding SQL statements to be executed (in case of stacked SQLi).
* Added switch `--sqlmap-shell` to turn on interactive sqlmap shell prompt.
+7
View File
@@ -565,6 +565,9 @@ Efrain Torres, <et(at)metasploit.com>
* for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository
* for his great Metasploit WMAP Framework
Jennifer Torres, <jtorresf42(at)gmail.com>
* for contributing a tamper script luanginx.py
Sandro Tosi, <matrixhasu(at)gmail.com>
* for helping to create sqlmap Debian package correctly
@@ -597,6 +600,7 @@ Carlos Gabriel Vergara, <carlosgabrielvergara(at)gmail.com>
Patrick Webster, <patrick(at)aushack.com>
* for suggesting an enhancement
* for donating to sqlmap development (from OSI.Security)
Ed Williams, <ed.williams(at)ngssecure.com>
* for suggesting a minor enhancement
@@ -760,6 +764,9 @@ ultramegaman, <seclists(at)ultramegaman.com>
Vinicius, <viniciusmaxdaloop(at)gmail.com>
* for reporting a minor bug
w8ay
* for contributing an implementation for chunked transfer-encoding (switch --chunked)
wanglei, <wanglei(at)17uxi.cn>
* for reporting a minor bug
+4 -5
View File
@@ -15,11 +15,6 @@ This file lists bundled packages and their associated licensing terms.
Copyright (C) 2013, Jonathan Hartley.
* The Fcrypt library located under thirdparty/fcrypt/.
Copyright (C) 2000, 2001, 2004 Carey Evans.
* The Odict library located under thirdparty/odict/.
Copyright (C) 2005, Nicola Larosa, Michael Foord.
* The Oset library located under thirdparty/oset/.
Copyright (C) 2010, BlueDynamics Alliance, Austria.
Copyright (C) 2009, Raymond Hettinger, and others.
* The PrettyPrint library located under thirdparty/prettyprint/.
Copyright (C) 2010, Chris Hall.
* The SocksiPy library located under thirdparty/socks/.
@@ -281,6 +276,10 @@ 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 ordereddict library located under thirdparty/odict/.
Copyright (C) 2009, Raymond Hettinger.
* The six Python 2 and 3 compatibility library located under thirdparty/six/.
Copyright (C) 2010-2018, Benjamin Peterson.
* The Termcolor library located under thirdparty/termcolor/.
Copyright (C) 2008-2011, Volvox Development Team.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![Лиценз](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![Лиценз](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap e инструмент за тестване и проникване, с отворен код, който автоматизира процеса на откриване и използване на недостатъците на SQL база данните чрез SQL инжекция, която ги взима от сървъра. Снабден е с мощен детектор, множество специални функции за най-добрия тестер и широк спектър от функции, които могат да се използват за множество цели - извличане на данни от базата данни, достъп до основната файлова система и изпълняване на команди на операционната система.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "Out-of-band".
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
**sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet aussi l'exécution des commandes sur le système d'exploitation.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom sustavu korištenjem tzv. "out-of-band" veza.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![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_.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmapはオープンソースのペネトレーションテスティングツールです。SQLインジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。
強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalającuch na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap é uma ferramenta de teste de penetração de código aberto que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de penetração por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
+50
View File
@@ -0,0 +1,50 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения, множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в операционной системе через out-of-band соединение.
Скриншоты
----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Вы можете посетить [набор скриншотов](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) демонстрируемые некоторые функции в wiki.
Установка
----
Вы можете скачать последнюю версию tarball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/tarball/master) или последний zipball, нажав [сюда](https://github.com/sqlmapproject/sqlmap/zipball/master).
Предпочтительно вы можете загрузить sqlmap, клонируя [Git](https://github.com/sqlmapproject/sqlmap) репозиторий:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap работает из коробки с [Python](http://www.python.org/download/) версии **2.6.x** и **2.7.x** на любой платформе.
Использование
----
Чтобы получить список основных опций и вариантов выбора, используйте:
python sqlmap.py -h
Чтобы получить список всех опций и вариантов выбора, используйте:
python sqlmap.py -hh
Вы можете найти пробный запуск [тут](https://asciinema.org/a/46601).
Чтобы получить обзор возможностей sqlmap, список поддерживаемых функций и описание всех параметров и переключателей, а также примеры, вам рекомендуется ознакомится с [пользовательским мануалом](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Ссылки
----
* Основной сайт: http://sqlmap.org
* Скачивание: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) или [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Канал новостей RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Отслеживание проблем: https://github.com/sqlmapproject/sqlmap/issues
* Пользовательский мануал: https://github.com/sqlmapproject/sqlmap/wiki
* Часто задаваемые вопросы (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
* Демки: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
* Скриншоты: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır.
+50
View File
@@ -0,0 +1,50 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-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 - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення, безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній системі через out-of-band з'єднання.
Скриншоти
----
![Screenshot](https://raw.github.com/wiki/sqlmapproject/sqlmap/images/sqlmap_screenshot.png)
Ви можете ознайомитися з [колекцією скриншотів](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), які демонструють деякі функції в wiki.
Встановлення
----
Ви можете завантажити останню версію tarball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/tarball/master) або останню версію zipball натиснувши [сюди](https://github.com/sqlmapproject/sqlmap/zipball/master).
Найкраще завантажити sqlmap шляхом клонування [Git](https://github.com/sqlmapproject/sqlmap) репозиторію:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap «працює з коробки» з [Python](http://www.python.org/download/) версії **2.6.x** та **2.7.x** на будь-якій платформі.
Використання
----
Щоб отримати список основних опцій і перемикачів, використовуйте:
python sqlmap.py -h
Щоб отримати список всіх опцій і перемикачів, використовуйте:
python sqlmap.py -hh
Ви можете знайти приклад виконання [тут](https://asciinema.org/a/46601).
Для того, щоб ознайомитися з можливостями sqlmap, списком підтримуваних функцій та описом всіх параметрів і перемикачів, а також прикладами, вам рекомендується скористатися [інструкцією користувача](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Посилання
----
* Основний сайт: http://sqlmap.org
* Завантаження: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) або [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Канал новин RSS: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues
* Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki
* Поширенні питання (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
* Twitter: [@sqlmap](https://twitter.com/sqlmap)
* Демо: [http://www.youtube.com/user/inquisb/videos](http://www.youtube.com/user/inquisb/videos)
* Скриншоти: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
+1 -1
View File
@@ -1,6 +1,6 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过外带数据连接的方式执行操作系统命令。
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+3 -4
View File
@@ -3,12 +3,11 @@
"""
beep.py - Make a beep sound
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import os
import subprocess
import sys
import wave
@@ -16,11 +15,11 @@ BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
def beep():
try:
if subprocess.mswindows:
if sys.platform == "nt":
_win_wav_play(BEEP_WAV_FILENAME)
elif sys.platform == "darwin":
_mac_beep()
elif sys.platform == "linux2":
elif sys.platform.startswith("linux"):
_linux_wav_play(BEEP_WAV_FILENAME)
else:
_speaker_beep()
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+16 -11
View File
@@ -3,24 +3,28 @@
"""
cloak.py - Simple file encryption/compression utility
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import os
import struct
import sys
import zlib
from optparse import OptionError
from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
def hideAscii(data):
retVal = ""
retVal = b""
for i in xrange(len(data)):
if ord(data[i]) < 128:
retVal += chr(ord(data[i]) ^ 127)
else:
retVal += data[i]
value = data[i] if isinstance(data[i], int) else ord(data[i])
retVal += struct.pack('B', value ^ (127 if value < 128 else 0))
return retVal
@@ -37,8 +41,9 @@ def decloak(inputFile=None, data=None):
data = f.read()
try:
data = zlib.decompress(hideAscii(data))
except:
print 'ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile
except Exception as ex:
print(ex)
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
sys.exit(1)
finally:
f.close()
@@ -59,11 +64,11 @@ def main():
if not args.inputFile:
parser.error('Missing the input file, -h for help')
except (OptionError, TypeError), e:
parser.error(e)
except (OptionError, TypeError) as ex:
parser.error(ex)
if not os.path.isfile(args.inputFile):
print 'ERROR: the provided input file \'%s\' is non existent' % args.inputFile
print('ERROR: the provided input file \'%s\' is non existent' % args.inputFile)
sys.exit(1)
if not args.decrypt:
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+9 -8
View File
@@ -3,13 +3,14 @@
"""
dbgtool.py - Portable executable to ASCII debug script converter
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import os
import sys
import struct
from optparse import OptionError
from optparse import OptionParser
@@ -19,7 +20,7 @@ def convert(inputFile):
fileSize = fileStat.st_size
if fileSize > 65280:
print "ERROR: the provided input file '%s' is too big for debug.exe" % inputFile
print("ERROR: the provided input file '%s' is too big for debug.exe" % inputFile)
sys.exit(1)
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
@@ -32,7 +33,7 @@ def convert(inputFile):
fileContent = fp.read()
for fileChar in fileContent:
unsignedFileChar = struct.unpack("B", fileChar)[0]
unsignedFileChar = fileChar if sys.version_info >= (3, 0) else ord(fileChar)
if unsignedFileChar != 0:
counter2 += 1
@@ -59,7 +60,7 @@ def convert(inputFile):
def main(inputFile, outputFile):
if not os.path.isfile(inputFile):
print "ERROR: the provided input file '%s' is not a regular file" % inputFile
print("ERROR: the provided input file '%s' is not a regular file" % inputFile)
sys.exit(1)
script = convert(inputFile)
@@ -70,7 +71,7 @@ def main(inputFile, outputFile):
sys.stdout.write(script)
sys.stdout.close()
else:
print script
print(script)
if __name__ == "__main__":
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
@@ -86,8 +87,8 @@ if __name__ == "__main__":
if not args.inputFile:
parser.error("Missing the input file, -h for help")
except (OptionError, TypeError), e:
parser.error(e)
except (OptionError, TypeError) as ex:
parser.error(ex)
inputFile = args.inputFile
outputFile = args.outputFile
+3 -4
View File
@@ -22,7 +22,6 @@
import os
import select
import socket
import subprocess
import sys
def setNonBlocking(fd):
@@ -37,7 +36,7 @@ def setNonBlocking(fd):
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
def main(src, dst):
if subprocess.mswindows:
if sys.platform == "nt":
sys.stderr.write('icmpsh master can only run on Posix systems\n')
sys.exit(255)
@@ -80,7 +79,7 @@ def main(src, dst):
cmd = ''
# Wait for incoming replies
if sock in select.select([ sock ], [], [])[0]:
if sock in select.select([sock], [], [])[0]:
buff = sock.recv(4096)
if 0 == len(buff):
@@ -128,7 +127,7 @@ def main(src, dst):
try:
# Send it to the target host
sock.sendto(ip.get_packet(), (dst, 0))
except socket.error, ex:
except socket.error as ex:
sys.stderr.write("'%s'\n" % ex)
sys.stderr.flush()
-137
View File
@@ -1,137 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import os
import re
import urllib2
import urlparse
from xml.dom.minidom import Document
# Path to the XML file with signatures
MSSQL_XML = os.path.abspath("../../xml/banner/mssql.xml")
# Url to update Microsoft SQL Server XML versions file from
MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx"
def updateMSSQLXML():
if not os.path.exists(MSSQL_XML):
errMsg = "[ERROR] file '%s' does not exist. Please run the script from its parent directory" % MSSQL_XML
print errMsg
return
infoMsg = "[INFO] retrieving data from '%s'" % MSSQL_VERSIONS_URL
print infoMsg
try:
req = urllib2.Request(MSSQL_VERSIONS_URL)
f = urllib2.urlopen(req)
mssqlVersionsHtmlString = f.read()
f.close()
except urllib2.URLError:
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
__mssqlHostname = __mssqlPath[1]
warnMsg = "[WARNING] sqlmap was unable to connect to %s," % __mssqlHostname
warnMsg += " check your Internet connection and retry"
print warnMsg
return
releases = re.findall("class=\"BCC_DV_01DarkBlueTitle\">SQL Server\s(.+?)\sBuilds", mssqlVersionsHtmlString, re.I)
releasesCount = len(releases)
# Create the minidom document
doc = Document()
# Create the <root> base element
root = doc.createElement("root")
doc.appendChild(root)
for index in xrange(0, releasesCount):
release = releases[index]
# Skip Microsoft SQL Server 6.5 because the HTML
# table is in another format
if release == "6.5":
continue
# Create the <signatures> base element
signatures = doc.createElement("signatures")
signatures.setAttribute("release", release)
root.appendChild(signatures)
startIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index])
if index == releasesCount - 1:
stopIdx = len(mssqlVersionsHtmlString)
else:
stopIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index + 1])
mssqlVersionsReleaseString = mssqlVersionsHtmlString[startIdx:stopIdx]
servicepackVersion = re.findall("</td><td>(7\.0|2000|2005|2008|2008 R2)*(.*?)</td><td.*?([\d\.]+)</td>[\r]*\n", mssqlVersionsReleaseString, re.I)
for servicePack, version in servicepackVersion:
if servicePack.startswith(" "):
servicePack = servicePack[1:]
if "/" in servicePack:
servicePack = servicePack[:servicePack.index("/")]
if "(" in servicePack:
servicePack = servicePack[:servicePack.index("(")]
if "-" in servicePack:
servicePack = servicePack[:servicePack.index("-")]
if "*" in servicePack:
servicePack = servicePack[:servicePack.index("*")]
if servicePack.startswith("+"):
servicePack = "0%s" % servicePack
servicePack = servicePack.replace("\t", " ")
servicePack = servicePack.replace("No SP", "0")
servicePack = servicePack.replace("RTM", "0")
servicePack = servicePack.replace("TM", "0")
servicePack = servicePack.replace("SP", "")
servicePack = servicePack.replace("Service Pack", "")
servicePack = servicePack.replace("<a href=\"http:", "")
servicePack = servicePack.replace(" ", " ")
servicePack = servicePack.replace("+ ", "+")
servicePack = servicePack.replace(" +", "+")
if servicePack.endswith(" "):
servicePack = servicePack[:-1]
if servicePack and version:
# Create the main <card> element
signature = doc.createElement("signature")
signatures.appendChild(signature)
# Create a <version> element
versionElement = doc.createElement("version")
signature.appendChild(versionElement)
# Give the <version> elemenet some text
versionText = doc.createTextNode(version)
versionElement.appendChild(versionText)
# Create a <servicepack> element
servicepackElement = doc.createElement("servicepack")
signature.appendChild(servicepackElement)
# Give the <servicepack> elemenet some text
servicepackText = doc.createTextNode(servicePack)
servicepackElement.appendChild(servicepackText)
# Save our newly created XML to the signatures file
mssqlXml = codecs.open(MSSQL_XML, "w", "utf8")
doc.writexml(writer=mssqlXml, addindent=" ", newl="\n")
mssqlXml.close()
infoMsg = "[INFO] done. retrieved data parsed and saved into '%s'" % MSSQL_XML
print infoMsg
if __name__ == "__main__":
updateMSSQLXML()
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+10 -5
View File
@@ -1,12 +1,14 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
safe2bin.py - Simple safe(hex) to binary format converter
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import binascii
import re
import string
@@ -16,6 +18,9 @@ import sys
from optparse import OptionError
from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
# Regex used for recognition of hex encoded characters
HEX_ENCODED_CHAR_REGEX = r"(?P<result>\\x[0-9A-Fa-f]{2})"
@@ -108,11 +113,11 @@ def main():
if not args.inputFile:
parser.error('Missing the input file, -h for help')
except (OptionError, TypeError), e:
parser.error(e)
except (OptionError, TypeError) as ex:
parser.error(ex)
if not os.path.isfile(args.inputFile):
print 'ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile
print('ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile)
sys.exit(1)
f = open(args.inputFile, 'r')
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Stress test against Python3
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
+20 -17
View File
@@ -1,27 +1,30 @@
#!/usr/bin/env python
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files
from __future__ import print_function
import sys
if len(sys.argv) > 0:
items = list()
if __name__ == "__main__":
if len(sys.argv) > 1:
items = list()
with open(sys.argv[1], 'r') as f:
for item in f.readlines():
item = item.strip()
try:
str.encode(item)
if item in items:
if item:
print item
else:
items.append(item)
except:
pass
with open(sys.argv[1], 'r') as f:
for item in f.readlines():
item = item.strip()
try:
str.encode(item)
if item in items:
if item:
print(item)
else:
items.append(item)
except:
pass
with open(sys.argv[1], 'w+') as f:
f.writelines("\n".join(items))
with open(sys.argv[1], 'w+') as f:
f.writelines("\n".join(items))
+30
View File
@@ -0,0 +1,30 @@
#! /usr/bin/env python
from __future__ import print_function
import os
import sys
def check(filepath):
if filepath.endswith(".py"):
content = open(filepath, "rb").read()
pattern = "\n\n\n".encode("ascii")
if pattern in content:
index = content.find(pattern)
print(filepath, repr(content[index - 30:index + 30]))
if __name__ == "__main__":
try:
BASE_DIRECTORY = sys.argv[1]
except IndexError:
print("no directory specified, defaulting to current working directory")
BASE_DIRECTORY = os.getcwd()
print("looking for *.py scripts in subdirectories of '%s'" % BASE_DIRECTORY)
for root, dirs, files in os.walk(BASE_DIRECTORY):
if any(_ in root for _ in ("extra", "thirdparty")):
continue
for name in files:
filepath = os.path.join(root, name)
check(filepath)
-7
View File
@@ -1,7 +0,0 @@
#!/bin/bash
# Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Runs pep8 on all python files (prerequisite: apt-get install pep8)
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pep8 '{}' \;
+12 -1
View File
@@ -1,6 +1,17 @@
#!/bin/bash
: '
cat > .git/hooks/post-commit << EOF
#!/bin/bash
source ./extra/shutils/postcommit-hook.sh
EOF
chmod +x .git/hooks/post-commit
'
SETTINGS="../../lib/core/settings.py"
PYPI="../../extra/shutils/pypi.sh"
declare -x SCRIPTPATH="${0}"
@@ -18,6 +29,6 @@ then
git tag $NEW_TAG
git push origin $NEW_TAG
echo "Going to push PyPI package"
/bin/bash ${SCRIPTPATH%/*}/pypi.sh
/bin/bash ${SCRIPTPATH%/*}/$PYPI
fi
fi
+11 -6
View File
@@ -1,14 +1,22 @@
#!/bin/bash
: '
cat > .git/hooks/pre-commit << EOF
#!/bin/bash
source ./extra/shutils/precommit-hook.sh
EOF
chmod +x .git/hooks/pre-commit
'
PROJECT="../../"
SETTINGS="../../lib/core/settings.py"
CHECKSUM="../../txt/checksum.md5"
declare -x SCRIPTPATH="${0}"
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
CHECKSUM_FULLPATH=${SCRIPTPATH%/*}/$CHECKSUM
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
@@ -16,7 +24,7 @@ if [ -f $SETTINGS_FULLPATH ]
then
LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"')
declare -a LINE
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.append(0) if len(_) < 3 else _; _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.extend([0] * (4 - len(_))); _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
if [ -n "$INCREMENTED" ]
then
sed -i "s/${LINE}/${INCREMENTED}/" $SETTINGS_FULLPATH
@@ -27,6 +35,3 @@ then
fi
git add "$SETTINGS_FULLPATH"
fi
truncate -s 0 "$CHECKSUM_FULLPATH"
cd $PROJECT_FULLPATH && for i in $(find . -name "*.py" -o -name "*.xml" -o -iname "*_" | sort); do git ls-files $i --error-unmatch &>/dev/null && md5sum $i | stdbuf -i0 -o0 -e0 sed 's/\.\///' >> "$CHECKSUM_FULLPATH"; git add "$CHECKSUM_FULLPATH"; done
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
# Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pycodestyle --ignore=E501,E302,E305,E722,E402 '{}' \;
+11 -9
View File
@@ -3,6 +3,8 @@
# Runs pylint on all python scripts found in a directory tree
# Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
from __future__ import print_function
import os
import re
import sys
@@ -17,26 +19,26 @@ def check(module):
if module[-3:] == ".py":
print "CHECKING ", module
print("CHECKING ", module)
pout = os.popen("pylint --rcfile=/dev/null %s" % module, 'r')
for line in pout:
if re.match(r"\AE:", line):
print line.strip()
print(line.strip())
if __RATING__ and "Your code has been rated at" in line:
print line
print(line)
score = re.findall(r"\d.\d\d", line)[0]
total += float(score)
count += 1
if __name__ == "__main__":
try:
print sys.argv
print(sys.argv)
BASE_DIRECTORY = sys.argv[1]
except IndexError:
print "no directory specified, defaulting to current working directory"
print("no directory specified, defaulting to current working directory")
BASE_DIRECTORY = os.getcwd()
print "looking for *.py scripts in subdirectories of ", BASE_DIRECTORY
print("looking for *.py scripts in subdirectories of ", BASE_DIRECTORY)
for root, dirs, files in os.walk(BASE_DIRECTORY):
if any(_ in root for _ in ("extra", "thirdparty")):
continue
@@ -45,6 +47,6 @@ if __name__ == "__main__":
check(filepath)
if __RATING__:
print "==" * 50
print "%d modules found" % count
print "AVERAGE SCORE = %.02f" % (total / count)
print("==" * 50)
print("%d modules found" % count)
print("AVERAGE SCORE = %.02f" % (total / count))
+13 -7
View File
@@ -16,7 +16,7 @@ cat > $TMP_DIR/setup.py << EOF
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -25,10 +25,17 @@ from setuptools import setup, find_packages
setup(
name='sqlmap',
version='$VERSION',
description="Automatic SQL injection and database takeover tool",
description='Automatic SQL injection and database takeover tool',
long_description=open('README.rst').read(),
long_description_content_type='text/x-rst',
author='Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar',
author_email='[email protected], [email protected]',
url='https://sqlmap.org',
url='http://sqlmap.org',
project_urls={
'Documentation': 'https://github.com/sqlmapproject/sqlmap/wiki',
'Source': 'https://github.com/sqlmapproject/sqlmap/',
'Tracker': 'https://github.com/sqlmapproject/sqlmap/issues',
},
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
license='GNU General Public License v2 (GPLv2)',
packages=find_packages(),
@@ -60,7 +67,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -152,7 +159,7 @@ Links
- User's manual: https://github.com/sqlmapproject/sqlmap/wiki
- Frequently Asked Questions (FAQ):
https://github.com/sqlmapproject/sqlmap/wiki/FAQ
- Twitter: [@sqlmap](https://twitter.com/sqlmap)
- Twitter: https://twitter.com/sqlmap
- Demos: http://www.youtube.com/user/inquisb/videos
- Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
@@ -170,7 +177,6 @@ Links
EOF
sed -i "s/^VERSION =.*/VERSION = \"$VERSION\"/g" sqlmap/lib/core/settings.py
sed -i "s/^TYPE =.*/TYPE = \"$TYPE\"/g" sqlmap/lib/core/settings.py
sed -i "s/.*lib\/core\/settings\.py/`md5sum sqlmap/lib/core/settings.py | cut -d ' ' -f 1` lib\/core\/settings\.py/g" sqlmap/txt/checksum.md5
for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
python setup.py sdist upload
rm -rf $TMP_DIR
rm -rf $TMP_DIR
-164
View File
@@ -1,164 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
# See the file 'LICENSE' for copying permission
import codecs
import inspect
import os
import re
import smtplib
import subprocess
import sys
import time
import traceback
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
sys.path.append(os.path.normpath("%s/../../" % os.path.dirname(inspect.getfile(inspect.currentframe()))))
from lib.core.revision import getRevisionNumber
START_TIME = time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
SQLMAP_HOME = "/opt/sqlmap"
SMTP_SERVER = "127.0.0.1"
SMTP_PORT = 25
SMTP_TIMEOUT = 30
FROM = "[email protected]"
#TO = "[email protected]"
TO = ["[email protected]", "[email protected]"]
SUBJECT = "regression test started on %s using revision %s" % (START_TIME, getRevisionNumber())
TARGET = "debian"
def prepare_email(content):
global FROM
global TO
global SUBJECT
msg = MIMEMultipart()
msg["Subject"] = SUBJECT
msg["From"] = FROM
msg["To"] = TO if isinstance(TO, basestring) else ','.join(TO)
msg.attach(MIMEText(content))
return msg
def send_email(msg):
global SMTP_SERVER
global SMTP_PORT
global SMTP_TIMEOUT
try:
s = smtplib.SMTP(host=SMTP_SERVER, port=SMTP_PORT, timeout=SMTP_TIMEOUT)
s.sendmail(FROM, TO, msg.as_string())
s.quit()
# Catch all for SMTP exceptions
except smtplib.SMTPException, e:
print "Failure to send email: %s" % str(e)
def failure_email(msg):
msg = prepare_email(msg)
send_email(msg)
sys.exit(1)
def main():
global SUBJECT
content = ""
test_counts = []
attachments = {}
updateproc = subprocess.Popen("cd /opt/sqlmap/ ; python /opt/sqlmap/sqlmap.py --update", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = updateproc.communicate()
if stderr:
failure_email("Update of sqlmap failed with error:\n\n%s" % stderr)
regressionproc = subprocess.Popen("python /opt/sqlmap/sqlmap.py --live-test", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
stdout, stderr = regressionproc.communicate()
if stderr:
failure_email("Execution of regression test failed with error:\n\n%s" % stderr)
failed_tests = re.findall("running live test case: (.+?) \((\d+)\/\d+\)[\r]*\n.+test failed (at parsing items: (.+))?\s*\- scan folder: (\/.+) \- traceback: (.*?)( - SQL injection not detected)?[\r]*\n", stdout)
for failed_test in failed_tests:
title = failed_test[0]
test_count = int(failed_test[1])
parse = failed_test[3] if failed_test[3] else None
output_folder = failed_test[4]
traceback = False if failed_test[5] == "False" else bool(failed_test[5])
detected = False if failed_test[6] else True
test_counts.append(test_count)
console_output_file = os.path.join(output_folder, "console_output")
log_file = os.path.join(output_folder, TARGET, "log")
traceback_file = os.path.join(output_folder, "traceback")
if os.path.exists(console_output_file):
console_output_fd = codecs.open(console_output_file, "rb", "utf8")
console_output = console_output_fd.read()
console_output_fd.close()
attachments[test_count] = str(console_output)
if os.path.exists(log_file):
log_fd = codecs.open(log_file, "rb", "utf8")
log = log_fd.read()
log_fd.close()
if os.path.exists(traceback_file):
traceback_fd = codecs.open(traceback_file, "rb", "utf8")
traceback = traceback_fd.read()
traceback_fd.close()
content += "Failed test case '%s' (#%d)" % (title, test_count)
if parse:
content += " at parsing: %s:\n\n" % parse
content += "### Log file:\n\n"
content += "%s\n\n" % log
elif not detected:
content += " - SQL injection not detected\n\n"
else:
content += "\n\n"
if traceback:
content += "### Traceback:\n\n"
content += "%s\n\n" % str(traceback)
content += "#######################################################################\n\n"
end_string = "Regression test finished at %s" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime())
if content:
content += end_string
SUBJECT = "Failed %s (%s)" % (SUBJECT, ", ".join("#%d" % count for count in test_counts))
msg = prepare_email(content)
for test_count, attachment in attachments.items():
attachment = MIMEText(attachment)
attachment.add_header("Content-Disposition", "attachment", filename="test_case_%d_console_output.txt" % test_count)
msg.attach(attachment)
send_email(msg)
else:
SUBJECT = "Successful %s" % SUBJECT
msg = prepare_email("All test cases were successful\n\n%s" % end_string)
send_email(msg)
if __name__ == "__main__":
log_fd = open("/tmp/sqlmapregressiontest.log", "wb")
log_fd.write("Regression test started at %s\n" % START_TIME)
try:
main()
except Exception, e:
log_fd.write("An exception has occurred:\n%s" % str(traceback.format_exc()))
log_fd.write("Regression test finished at %s\n\n" % time.strftime("%H:%M:%S %d-%m-%Y", time.gmtime()))
log_fd.close()
-141
View File
@@ -1,141 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import cookielib
import re
import socket
import sys
import urllib
import urllib2
import ConfigParser
from operator import itemgetter
TIMEOUT = 10
CONFIG_FILE = 'sqlharvest.cfg'
TABLES_FILE = 'tables.txt'
USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; AskTB5.3)'
SEARCH_URL = 'http://www.google.com/m?source=mobileproducts&dc=gorganic'
MAX_FILE_SIZE = 2 * 1024 * 1024 # if a result (.sql) file for downloading is more than 2MB in size just skip it
QUERY = 'CREATE TABLE ext:sql'
REGEX_URLS = r';u=([^"]+?)&amp;q='
REGEX_RESULT = r'(?i)CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
def main():
tables = dict()
cookies = cookielib.CookieJar()
cookie_processor = urllib2.HTTPCookieProcessor(cookies)
opener = urllib2.build_opener(cookie_processor)
opener.addheaders = [("User-Agent", USER_AGENT)]
conn = opener.open(SEARCH_URL)
page = conn.read() # set initial cookie values
config = ConfigParser.ConfigParser()
config.read(CONFIG_FILE)
if not config.has_section("options"):
config.add_section("options")
if not config.has_option("options", "index"):
config.set("options", "index", "0")
i = int(config.get("options", "index"))
try:
with open(TABLES_FILE, 'r') as f:
for line in f.xreadlines():
if len(line) > 0 and ',' in line:
temp = line.split(',')
tables[temp[0]] = int(temp[1])
except:
pass
socket.setdefaulttimeout(TIMEOUT)
files, old_files = None, None
try:
while True:
abort = False
old_files = files
files = []
try:
conn = opener.open("%s&q=%s&start=%d&sa=N" % (SEARCH_URL, QUERY.replace(' ', '+'), i * 10))
page = conn.read()
for match in re.finditer(REGEX_URLS, page):
files.append(urllib.unquote(match.group(1)))
if len(files) >= 10:
break
abort = (files == old_files)
except KeyboardInterrupt:
raise
except Exception, msg:
print msg
if abort:
break
sys.stdout.write("\n---------------\n")
sys.stdout.write("Result page #%d\n" % (i + 1))
sys.stdout.write("---------------\n")
for sqlfile in files:
print sqlfile
try:
req = urllib2.Request(sqlfile)
response = urllib2.urlopen(req)
if "Content-Length" in response.headers:
if int(response.headers.get("Content-Length")) > MAX_FILE_SIZE:
continue
page = response.read()
found = False
counter = 0
for match in re.finditer(REGEX_RESULT, page):
counter += 1
table = match.group("result").strip().strip("`\"'").replace('"."', ".").replace("].[", ".").strip('[]')
if table and not any(_ in table for _ in ('>', '<', '--', ' ')):
found = True
sys.stdout.write('*')
if table in tables:
tables[table] += 1
else:
tables[table] = 1
if found:
sys.stdout.write("\n")
except KeyboardInterrupt:
raise
except Exception, msg:
print msg
else:
i += 1
except KeyboardInterrupt:
pass
finally:
with open(TABLES_FILE, 'w+') as f:
tables = sorted(tables.items(), key=itemgetter(1), reverse=True)
for table, count in tables:
f.write("%s,%d\n" % (table, count))
config.set("options", "index", str(i + 1))
with open(CONFIG_FILE, 'w+') as f:
config.write(f)
if __name__ == "__main__":
main()
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+148
View File
@@ -0,0 +1,148 @@
#!/usr/bin/env python
"""
vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import re
import sqlite3
import sys
import traceback
if sys.version_info >= (3, 0):
from http.client import FOUND
from http.client import NOT_FOUND
from http.client import OK
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
from socketserver import ThreadingMixIn
from urllib.parse import parse_qs
from urllib.parse import unquote_plus
else:
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from httplib import FOUND
from httplib import NOT_FOUND
from httplib import OK
from SocketServer import ThreadingMixIn
from urlparse import parse_qs
from urllib import unquote_plus
SCHEMA = """
CREATE TABLE users (
id INTEGER,
name TEXT,
surname TEXT
);
INSERT INTO users (id, name, surname) VALUES (1, 'luther', 'blisset');
INSERT INTO users (id, name, surname) VALUES (2, 'fluffy', 'bunny');
INSERT INTO users (id, name, surname) VALUES (3, 'wu', 'ming');
INSERT INTO users (id, name, surname) VALUES (4, 'sqlmap/1.0-dev (http://sqlmap.org)', 'user agent header');
INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull');
"""
LISTEN_ADDRESS = "localhost"
LISTEN_PORT = 8440
_conn = None
_cursor = None
_server = None
def init():
global _conn
global _cursor
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
_cursor = _conn.cursor()
_cursor.executescript(SCHEMA)
class ThreadingServer(ThreadingMixIn, HTTPServer):
def finish_request(self, *args, **kwargs):
try:
HTTPServer.finish_request(self, *args, **kwargs)
except Exception:
traceback.print_exc()
class ReqHandler(BaseHTTPRequestHandler):
def do_REQUEST(self):
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
params = {}
if query:
params.update(parse_qs(query))
if hasattr(self, "data"):
params.update(parse_qs(self.data))
for key in params:
if params[key]:
params[key] = params[key][-1]
self.url, self.params = path, params
if self.url == '/':
if "id" not in params:
self.send_response(FOUND)
self.send_header("Connection", "close")
self.send_header("Location", "/?id=1")
self.end_headers()
else:
self.send_response(OK)
self.send_header("Content-type", "text/html")
self.send_header("Connection", "close")
self.end_headers()
try:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params.get("id", ""))
output = "<b>SQL results:</b>\n"
output += "<table border=\"1\">\n"
for row in _cursor.fetchall():
output += "<tr>"
for value in row:
output += "<td>%s</td>" % value
output += "</tr>\n"
output += "</table>\n"
output += "</body></html>";
except Exception as ex:
output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex)
self.wfile.write(output.encode("utf8"))
else:
self.send_response(NOT_FOUND)
self.send_header("Connection", "close")
self.end_headers()
def do_GET(self):
self.do_REQUEST()
def do_POST(self):
length = int(self.headers.get("Content-length", 0))
if length:
data = self.rfile.read(length)
data = unquote_plus(data.decode("utf8"))
self.data = data
self.do_REQUEST()
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))
_server.serve_forever()
except KeyboardInterrupt:
_server.socket.close()
raise
if __name__ == "__main__":
try:
init()
run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
except KeyboardInterrupt:
print("\r[x] Ctrl-C received")
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+69 -19
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -75,7 +75,7 @@ def action():
if conf.getPasswordHashes:
try:
conf.dumper.userSettings("database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash", CONTENT_TYPE.PASSWORDS)
except SqlmapNoneDataException, ex:
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
@@ -83,7 +83,7 @@ def action():
if conf.getPrivileges:
try:
conf.dumper.userSettings("database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege", CONTENT_TYPE.PRIVILEGES)
except SqlmapNoneDataException, ex:
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
@@ -91,40 +91,90 @@ def action():
if conf.getRoles:
try:
conf.dumper.userSettings("database management system users roles", conf.dbmsHandler.getRoles(), "role", CONTENT_TYPE.ROLES)
except SqlmapNoneDataException, ex:
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getDbs:
conf.dumper.dbs(conf.dbmsHandler.getDbs())
try:
conf.dumper.dbs(conf.dbmsHandler.getDbs())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getTables:
conf.dumper.dbTables(conf.dbmsHandler.getTables())
try:
conf.dumper.dbTables(conf.dbmsHandler.getTables())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonTables:
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
try:
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getSchema:
conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
try:
conf.dumper.dbTableColumns(conf.dbmsHandler.getSchema(), CONTENT_TYPE.SCHEMA)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getColumns:
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
try:
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns(), CONTENT_TYPE.COLUMNS)
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.getCount:
conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
try:
conf.dumper.dbTablesCount(conf.dbmsHandler.getCount())
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.commonColumns:
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
try:
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpTable:
conf.dbmsHandler.dumpTable()
try:
conf.dbmsHandler.dumpTable()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.dumpAll:
conf.dbmsHandler.dumpAll()
try:
conf.dbmsHandler.dumpAll()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.search:
conf.dbmsHandler.search()
try:
conf.dbmsHandler.search()
except SqlmapNoneDataException as ex:
logger.critical(ex)
except:
raise
if conf.query:
conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
@@ -140,11 +190,11 @@ def action():
conf.dbmsHandler.udfInjectCustom()
# File system options
if conf.rFile:
conf.dumper.rFile(conf.dbmsHandler.readFile(conf.rFile))
if conf.fileRead:
conf.dumper.rFile(conf.dbmsHandler.readFile(conf.fileRead))
if conf.wFile:
conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType)
if conf.fileWrite:
conf.dbmsHandler.writeFile(conf.fileWrite, conf.fileDest, conf.fileWriteType)
# Operating system options
if conf.osCmd:
+138 -90
View File
@@ -1,18 +1,18 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import copy
import httplib
import logging
import os
import random
import re
import socket
import subprocess
import sys
import tempfile
import time
@@ -21,6 +21,7 @@ from lib.core.agent import agent
from lib.core.common import Backend
from lib.core.common import extractRegexResult
from lib.core.common import extractTextTagContent
from lib.core.common import filterNone
from lib.core.common import findDynamicContent
from lib.core.common import Format
from lib.core.common import getFilteredPageContent
@@ -47,6 +48,7 @@ from lib.core.common import unArrayizeValue
from lib.core.common import urlencode
from lib.core.common import wasLastResponseDBMSError
from lib.core.common import wasLastResponseHTTPError
from lib.core.compat import xrange
from lib.core.convert import unicodeencode
from lib.core.defaults import defaults
from lib.core.data import conf
@@ -68,11 +70,14 @@ from lib.core.enums import NULLCONNECTION
from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
from lib.core.settings import CHECK_INTERNET_ADDRESS
from lib.core.settings import CHECK_INTERNET_VALUE
@@ -82,14 +87,17 @@ from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
from lib.core.settings import FI_ERROR_REGEX
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
from lib.core.settings import IPS_WAF_CHECK_PAYLOAD
from lib.core.settings import IDS_WAF_CHECK_RATIO
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import URI_HTTP_HEADER
from lib.core.settings import UPPER_RATIO_BOUND
from lib.core.threads import getCurrentThreadData
@@ -99,6 +107,8 @@ from lib.request.inject import checkBooleanExpression
from lib.request.templates import getPageTemplate
from lib.techniques.union.test import unionTest
from lib.techniques.union.use import configUnion
from thirdparty import six
from thirdparty.six.moves import http_client as _http_client
def checkSqlInjection(place, parameter, value):
# Store here the details about boundaries and payload used to
@@ -357,7 +367,7 @@ def checkSqlInjection(place, parameter, value):
# Parse test's <request>
comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
for boundary in boundaries:
injectable = False
@@ -419,11 +429,14 @@ def checkSqlInjection(place, parameter, value):
templatePayload = None
vector = None
origValue = value
if kb.customInjectionMark in origValue:
origValue = origValue.split(kb.customInjectionMark)[0]
origValue = re.search(r"(\w*)\Z", origValue).group(1)
# Threat the parameter original value according to the
# test's <where> tag
if where == PAYLOAD.WHERE.ORIGINAL or conf.prefix:
origValue = value
if kb.tamperFunctions:
templatePayload = agent.payload(place, parameter, value="", newValue=origValue, where=where)
elif where == PAYLOAD.WHERE.NEGATIVE:
@@ -433,7 +446,7 @@ def checkSqlInjection(place, parameter, value):
if conf.invalidLogical:
_ = int(kb.data.randomInt[:2])
origValue = "%s AND %s=%s" % (value, _, _ + 1)
origValue = "%s AND %s LIKE %s" % (origValue, _, _ + 1)
elif conf.invalidBignum:
origValue = kb.data.randomInt[:6]
elif conf.invalidString:
@@ -468,13 +481,13 @@ def checkSqlInjection(place, parameter, value):
# payload was successful
# Parse test's <response>
for method, check in test.response.items():
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
# In case of boolean-based blind SQL injection
if method == PAYLOAD.METHOD.COMPARISON:
# Generate payload used for comparison
def genCmpPayload():
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
# Forge response payload by prepending with
# boundary's prefix and appending the boundary's
@@ -558,18 +571,18 @@ def checkSqlInjection(place, parameter, value):
logger.info(infoMsg)
else:
trueSet = set(extractTextTagContent(trueRawResponse))
trueSet = trueSet.union(__ for _ in trueSet for __ in _.split())
trueSet |= set(__ for _ in trueSet for __ in _.split())
falseSet = set(extractTextTagContent(falseRawResponse))
falseSet = falseSet.union(__ for _ in falseSet for __ in _.split())
falseSet |= set(__ for _ in falseSet for __ in _.split())
if threadData.lastErrorPage and threadData.lastErrorPage[1]:
errorSet = set(extractTextTagContent(threadData.lastErrorPage[1]))
errorSet = errorSet.union(__ for _ in errorSet for __ in _.split())
errorSet |= set(__ for _ in errorSet for __ in _.split())
else:
errorSet = set()
candidates = filter(None, (_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet)))
candidates = filterNone(_.strip() if _.strip() in trueRawResponse and _.strip() not in falseRawResponse else None for _ in (trueSet - falseSet - errorSet))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
@@ -583,7 +596,7 @@ def checkSqlInjection(place, parameter, value):
logger.info(infoMsg)
if not any((conf.string, conf.notString)):
candidates = filter(None, (_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet)))
candidates = filterNone(_.strip() if _.strip() in falseRawResponse and _.strip() not in trueRawResponse else None for _ in (falseSet - trueSet))
if candidates:
candidates = sorted(candidates, key=lambda _: len(_))
@@ -608,7 +621,7 @@ def checkSqlInjection(place, parameter, value):
page, headers, _ = Request.queryPage(reqPayload, place, content=True, raise404=False)
output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastHTTPError[2] if wasLastResponseHTTPError() else None, re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers.keys() if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, listToStrValue((headers[key] for key in headers if key.lower() != URI_HTTP_HEADER.lower()) if headers else None), re.DOTALL | re.IGNORECASE)
output = output or extractRegexResult(check, threadData.lastRedirectMsg[1] if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
if output:
@@ -620,10 +633,10 @@ def checkSqlInjection(place, parameter, value):
injectable = True
except SqlmapConnectionException, msg:
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')" % msg
debugMsg += "error-based payload used ('%s')" % getSafeExString(ex)
logger.debug(debugMsg)
# In case of time-based blind or stacked queries
@@ -682,7 +695,7 @@ def checkSqlInjection(place, parameter, value):
# Test for UNION query SQL injection
reqPayload, vector = unionTest(comment, place, parameter, value, prefix, suffix)
if isinstance(reqPayload, basestring):
if isinstance(reqPayload, six.string_types):
infoMsg = "%s parameter '%s' is '%s' injectable" % (paramType, parameter, title)
logger.info(infoMsg)
@@ -761,7 +774,7 @@ def checkSqlInjection(place, parameter, value):
infoMsg = "executing alerting shell command(s) ('%s')" % conf.alert
logger.info(infoMsg)
process = subprocess.Popen(conf.alert, shell=True)
process = subprocess.Popen(conf.alert.encode(sys.getfilesystemencoding() or UNICODE_ENCODING), shell=True)
process.wait()
kb.alerted = True
@@ -783,7 +796,7 @@ def checkSqlInjection(place, parameter, value):
if conf.multipleTargets:
msg = "how do you want to proceed? [ne(X)t target/(s)kip current test/(e)nd detection phase/(n)ext parameter/(c)hange verbosity/(q)uit]"
choice = readInput(msg, default='T', checkBatch=False).upper()
choice = readInput(msg, default='X', checkBatch=False).upper()
else:
msg = "how do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(c)hange verbosity/(q)uit]"
choice = readInput(msg, default='S', checkBatch=False).upper()
@@ -856,8 +869,8 @@ def heuristicCheckDbms(injection):
if conf.noEscape and dbms not in FROM_DUMMY_TABLE:
continue
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms
break
@@ -893,7 +906,7 @@ def checkFalsePositives(injection):
kb.injection = injection
for i in xrange(conf.level):
for level in xrange(conf.level):
while True:
randInt1, randInt2, randInt3 = (_() for j in xrange(3))
@@ -989,11 +1002,6 @@ def checkFilteredChars(injection):
kb.injection = popValue()
def heuristicCheckSqlInjection(place, parameter):
if kb.nullConnection:
debugMsg = "heuristic check skipped because NULL connection used"
logger.debug(debugMsg)
return None
if kb.heavilyDynamic:
debugMsg = "heuristic check skipped because of heavy dynamicity"
logger.debug(debugMsg)
@@ -1051,9 +1059,19 @@ def heuristicCheckSqlInjection(place, parameter):
kb.heuristicTest = HEURISTIC_TEST.CASTED if casting else HEURISTIC_TEST.NEGATIVE if not result else HEURISTIC_TEST.POSITIVE
if casting:
errMsg = "possible %s casting " % ("integer" if origValue.isdigit() else "type")
errMsg += "detected (e.g. \"$%s=intval($_REQUEST['%s'])\") " % (parameter, parameter)
errMsg += "at the back-end web application"
errMsg = "possible %s casting detected (e.g. '" % ("integer" if origValue.isdigit() else "type")
platform = conf.url.split('.')[-1].lower()
if platform == WEB_PLATFORM.ASP:
errMsg += "%s=CInt(request.querystring(\"%s\"))" % (parameter, parameter)
elif platform == WEB_PLATFORM.ASPX:
errMsg += "int.TryParse(Request.QueryString[\"%s\"], out %s)" % (parameter, parameter)
elif platform == WEB_PLATFORM.JSP:
errMsg += "%s=Integer.parseInt(request.getParameter(\"%s\"))" % (parameter, parameter)
else:
errMsg += "$%s=intval($_REQUEST[\"%s\"])" % (parameter, parameter)
errMsg += "') at the back-end web application"
logger.error(errMsg)
if kb.ignoreCasted is None:
@@ -1118,14 +1136,6 @@ def checkDynParam(place, parameter, value):
try:
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
if not dynResult:
infoMsg = "confirming that %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg)
randInt = randomInt()
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
except SqlmapConnectionException:
pass
@@ -1229,7 +1239,7 @@ def checkStability():
logger.error(errMsg)
else:
warnMsg = "target URL content is not stable. sqlmap will base the page "
warnMsg = "target URL content is not stable (i.e. content differs). sqlmap will base the page "
warnMsg += "comparison on a sequence matcher. If no dynamic nor "
warnMsg += "injectable parameters are detected, or in case of "
warnMsg += "junk results, refer to user's manual paragraph "
@@ -1314,9 +1324,8 @@ def checkRegexp():
rawResponse = "%s%s" % (listToStrValue(headers.headers if headers else ""), page)
if not re.search(conf.regexp, rawResponse, re.I | re.M):
warnMsg = "you provided '%s' as the regular expression to " % conf.regexp
warnMsg += "match, but such a regular expression does not have any "
warnMsg += "match within the target URL raw response, sqlmap "
warnMsg = "you provided '%s' as the regular expression " % conf.regexp
warnMsg += "which does not have any match within the target URL raw response. sqlmap "
warnMsg += "will carry on anyway"
logger.warn(warnMsg)
@@ -1331,11 +1340,14 @@ def checkWaf():
if any((conf.string, conf.notString, conf.regexp, conf.dummy, conf.offline, conf.skipWaf)):
return None
if kb.originalCode == _http_client.NOT_FOUND:
return None
_ = hashDBRetrieve(HASHDB_KEYS.CHECK_WAF_RESULT, True)
if _ is not None:
if _:
warnMsg = "previous heuristics detected that the target "
warnMsg += "is protected by some kind of WAF/IPS/IDS"
warnMsg += "is protected by some kind of WAF/IPS"
logger.critical(warnMsg)
return _
@@ -1343,11 +1355,11 @@ def checkWaf():
return None
infoMsg = "checking if the target is protected by "
infoMsg += "some kind of WAF/IPS/IDS"
infoMsg += "some kind of WAF/IPS"
logger.info(infoMsg)
retVal = False
payload = "%d %s" % (randomInt(), IDS_WAF_CHECK_PAYLOAD)
payload = "%d %s" % (randomInt(), IPS_WAF_CHECK_PAYLOAD)
if PLACE.URI in conf.parameters:
place = PLACE.POST
@@ -1357,7 +1369,12 @@ def checkWaf():
value = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + DEFAULT_GET_POST_DELIMITER
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect)
pushValue(conf.timeout)
kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IDS_WAF_CHECK_TIMEOUT
try:
@@ -1366,16 +1383,19 @@ def checkWaf():
retVal = True
finally:
kb.matchRatio = None
conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue()
if retVal:
warnMsg = "heuristics detected that the target "
warnMsg += "is protected by some kind of WAF/IPS/IDS"
warnMsg += "is protected by some kind of WAF/IPS"
logger.critical(warnMsg)
if not conf.identifyWaf:
message = "do you want sqlmap to try to detect backend "
message += "WAF/IPS/IDS? [y/N] "
message += "WAF/IPS? [y/N] "
if readInput(message, default='N', boolean=True):
conf.identifyWaf = True
@@ -1399,7 +1419,7 @@ def identifyWaf():
kb.testMode = True
infoMsg = "using WAF scripts to detect "
infoMsg += "backend WAF/IPS/IDS protection"
infoMsg += "backend WAF/IPS protection"
logger.info(infoMsg)
@cachedmethod
@@ -1407,16 +1427,24 @@ def identifyWaf():
page, headers, code = None, None, None
try:
pushValue(kb.redirectChoice)
kb.redirectChoice = REDIRECTION.NO
pushValue(kb.resendPostOnRedirect)
kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = True
if kwargs.get("get"):
kwargs["get"] = urlencode(kwargs["get"])
kwargs["raise404"] = False
kwargs["silent"] = True
kwargs["finalCode"] = True
page, headers, code = Request.getPage(*args, **kwargs)
except Exception:
pass
finally:
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue()
return page or "", headers or {}, code
retVal = []
@@ -1426,9 +1454,9 @@ def identifyWaf():
continue
try:
logger.debug("checking for WAF/IPS/IDS product '%s'" % product)
logger.debug("checking for WAF/IPS product '%s'" % product)
found = function(_)
except Exception, ex:
except Exception as ex:
errMsg = "exception occurred while running "
errMsg += "WAF script for '%s' ('%s')" % (product, getSafeExString(ex))
logger.critical(errMsg)
@@ -1436,19 +1464,19 @@ def identifyWaf():
found = False
if found:
errMsg = "WAF/IPS/IDS identified as '%s'" % product
errMsg = "WAF/IPS identified as '%s'" % product
logger.critical(errMsg)
retVal.append(product)
if retVal:
if kb.wafSpecificResponse and len(retVal) == 1 and "unknown" in retVal[0].lower():
if kb.wafSpecificResponse and "You don't have permission to access" not in kb.wafSpecificResponse and len(retVal) == 1 and "unknown" in retVal[0].lower():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.SPECIFIC_RESPONSE)
os.close(handle)
with openFile(filename, "w+b") as f:
f.write(kb.wafSpecificResponse)
message = "WAF/IPS/IDS specific response can be found in '%s'. " % filename
message = "WAF/IPS specific response can be found in '%s'. " % filename
message += "If you know the details on used protection please "
message += "report it along with specific response "
message += "to '%s'" % DEV_EMAIL_ADDRESS
@@ -1465,7 +1493,7 @@ def identifyWaf():
if not choice:
raise SqlmapUserQuitException
else:
warnMsg = "WAF/IPS/IDS product hasn't been identified"
warnMsg = "WAF/IPS product hasn't been identified"
logger.warn(warnMsg)
kb.testType = None
@@ -1482,46 +1510,59 @@ def checkNullConnection():
if conf.data:
return False
infoMsg = "testing NULL connection to the target URL"
logger.info(infoMsg)
_ = hashDBRetrieve(HASHDB_KEYS.CHECK_NULL_CONNECTION_RESULT, True)
if _ is not None:
kb.nullConnection = _
pushValue(kb.pageCompress)
kb.pageCompress = False
if _:
dbgMsg = "resuming NULL connection method '%s'" % _
logger.debug(dbgMsg)
try:
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD, raise404=False)
else:
infoMsg = "testing NULL connection to the target URL"
logger.info(infoMsg)
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD
pushValue(kb.pageCompress)
kb.pageCompress = False
infoMsg = "NULL connection is supported with HEAD method ('Content-Length')"
logger.info(infoMsg)
else:
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
try:
page, headers, _ = Request.getPage(method=HTTPMETHOD.HEAD, raise404=False)
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE
if not page and HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.HEAD
infoMsg = "NULL connection is supported with GET method ('Range')"
infoMsg = "NULL connection is supported with HEAD method ('Content-Length')"
logger.info(infoMsg)
else:
_, headers, _ = Request.getPage(skipRead=True)
page, headers, _ = Request.getPage(auxHeaders={HTTP_HEADER.RANGE: "bytes=-1"})
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.SKIP_READ
if page and len(page) == 1 and HTTP_HEADER.CONTENT_RANGE in (headers or {}):
kb.nullConnection = NULLCONNECTION.RANGE
infoMsg = "NULL connection is supported with 'skip-read' method"
infoMsg = "NULL connection is supported with GET method ('Range')"
logger.info(infoMsg)
else:
_, headers, _ = Request.getPage(skipRead=True)
except SqlmapConnectionException:
pass
if HTTP_HEADER.CONTENT_LENGTH in (headers or {}):
kb.nullConnection = NULLCONNECTION.SKIP_READ
finally:
kb.pageCompress = popValue()
infoMsg = "NULL connection is supported with 'skip-read' method"
logger.info(infoMsg)
return kb.nullConnection is not None
except SqlmapConnectionException:
pass
finally:
kb.pageCompress = popValue()
kb.nullConnection = False if kb.nullConnection is None else kb.nullConnection
hashDBWrite(HASHDB_KEYS.CHECK_NULL_CONNECTION_RESULT, kb.nullConnection, True)
return kb.nullConnection in getPublicTypeMembers(NULLCONNECTION, True)
def checkConnection(suppressOutput=False):
threadData = getCurrentThreadData()
if not re.search(r"\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z", conf.hostname):
if not any((conf.proxy, conf.tor, conf.dummy, conf.offline)):
try:
@@ -1531,10 +1572,14 @@ def checkConnection(suppressOutput=False):
except socket.gaierror:
errMsg = "host '%s' does not exist" % conf.hostname
raise SqlmapConnectionException(errMsg)
except socket.error, ex:
except socket.error as ex:
errMsg = "problem occurred while "
errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapConnectionException(errMsg)
except UnicodeError as ex:
errMsg = "problem occurred while "
errMsg += "handling a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapDataException(errMsg)
if not suppressOutput and not conf.dummy and not conf.offline:
infoMsg = "testing connection to the target URL"
@@ -1542,11 +1587,14 @@ def checkConnection(suppressOutput=False):
try:
kb.originalPageTime = time.time()
page, headers, _ = Request.queryPage(content=True, noteResponseTime=False)
kb.originalPage = kb.pageTemplate = page
Request.queryPage(content=True, noteResponseTime=False)
kb.errorIsNone = False
if any(_ in (kb.serverHeader or "") for _ in PRECONNECT_INCOMPATIBLE_SERVERS):
singleTimeWarnMessage("turning off pre-connect mechanism because of incompatible server ('%s')" % kb.serverHeader)
conf.disablePrecon = True
if not kb.originalPage and wasLastResponseHTTPError():
errMsg = "unable to retrieve page content"
raise SqlmapConnectionException(errMsg)
@@ -1562,17 +1610,14 @@ def checkConnection(suppressOutput=False):
else:
kb.errorIsNone = True
threadData = getCurrentThreadData()
if kb.redirectChoice == REDIRECTION.YES and threadData.lastRedirectURL and threadData.lastRedirectURL[0] == threadData.lastRequestUID:
if (threadData.lastRedirectURL[1] or "").startswith("https://") and unicodeencode(conf.hostname) in threadData.lastRedirectURL[1]:
conf.url = re.sub(r"https?://", "https://", conf.url)
match = re.search(r":(\d+)", threadData.lastRedirectURL[1])
port = match.group(1) if match else 443
conf.url = re.sub(r":\d+/", ":%s/" % port, conf.url)
conf.url = re.sub(r":\d+(/|\Z)", ":%s\g<1>" % port, conf.url)
except SqlmapConnectionException, ex:
except SqlmapConnectionException as ex:
if conf.ipv6:
warnMsg = "check connection to a provided "
warnMsg += "IPv6 address with a tool like ping6 "
@@ -1581,7 +1626,7 @@ def checkConnection(suppressOutput=False):
warnMsg += "any addressing issues"
singleTimeWarnMessage(warnMsg)
if any(code in kb.httpErrorCodes for code in (httplib.NOT_FOUND, )):
if any(code in kb.httpErrorCodes for code in (_http_client.NOT_FOUND, )):
errMsg = getSafeExString(ex)
logger.critical(errMsg)
@@ -1595,6 +1640,9 @@ def checkConnection(suppressOutput=False):
kb.ignoreNotFound = True
else:
raise
finally:
kb.originalPage = kb.pageTemplate = threadData.lastPage
kb.originalCode = threadData.lastCode
return True
+33 -18
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -40,6 +40,7 @@ from lib.core.common import safeCSValue
from lib.core.common import showHttpErrorCodes
from lib.core.common import urlencode
from lib.core.common import urldecode
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -56,9 +57,11 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException
from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import ASP_NET_CONTROL_REGEX
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS
@@ -69,6 +72,7 @@ from lib.core.settings import REFERER_ALIASES
from lib.core.settings import USER_AGENT_ALIASES
from lib.core.target import initTargetEnv
from lib.core.target import setupTargetEnv
from lib.utils.hash import crackHashFile
def _selectInjection():
"""
@@ -87,7 +91,7 @@ def _selectInjection():
if point not in points:
points[point] = injection
else:
for key in points[point].keys():
for key in points[point]:
if key != 'data':
points[point][key] = points[point][key] or injection[key]
points[point]['data'].update(injection['data'])
@@ -241,18 +245,22 @@ def _saveToResultsFile():
if key not in results:
results[key] = []
results[key].extend(injection.data.keys())
results[key].extend(list(injection.data.keys()))
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
try:
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line)
conf.resultsFP.flush()
conf.resultsFP.flush()
except IOError as ex:
errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFilename, getSafeExString(ex))
raise SqlmapSystemException(errMsg)
@stackedmethod
def start():
@@ -262,6 +270,9 @@ def start():
check if they are dynamic and SQL injection affected
"""
if conf.hashFile:
crackHashFile(conf.hashFile)
if conf.direct:
initTargetEnv()
setupTargetEnv()
@@ -307,6 +318,7 @@ def start():
conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders)
conf.httpHeaders.extend(targetHeaders or [])
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()
parseTargetUrl()
@@ -416,7 +428,7 @@ def start():
checkStability()
# Do a little prioritization reorder of a testable parameter list
parameters = conf.parameters.keys()
parameters = list(conf.parameters.keys())
# Order of testing list (first to last)
orderList = (PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER, PLACE.URI, PLACE.POST, PLACE.GET)
@@ -480,7 +492,7 @@ def start():
elif parameter in conf.testParameter:
pass
elif parameter == conf.rParam:
elif parameter in conf.rParam:
testSqlInj = False
infoMsg = "skipping randomizing %s parameter '%s'" % (paramType, parameter)
@@ -498,14 +510,14 @@ def start():
infoMsg = "skipping %s parameter '%s'" % (paramType, parameter)
logger.info(infoMsg)
elif parameter == conf.csrfToken:
elif conf.csrfToken and re.search(conf.csrfToken, parameter, re.I):
testSqlInj = False
infoMsg = "skipping anti-CSRF token parameter '%s'" % parameter
logger.info(infoMsg)
# Ignore session-like parameters for --level < 4
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False
infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
@@ -524,7 +536,7 @@ def start():
testSqlInj = False
else:
infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter)
infoMsg = "%s parameter '%s' appears to be dynamic" % (paramType, parameter)
logger.info(infoMsg)
kb.testedParams.add(paramKey)
@@ -631,6 +643,9 @@ def start():
errMsg += "involved (e.g. WAF) maybe you could try to use "
errMsg += "option '--tamper' (e.g. '--tamper=space2comment')"
if not conf.randomAgent:
errMsg += " and/or switch '--random-agent'"
raise SqlmapNotVulnerableException(errMsg.rstrip('.'))
else:
# Flush the flag
@@ -675,7 +690,7 @@ def start():
except SqlmapSilentQuitException:
raise
except SqlmapBaseException, ex:
except SqlmapBaseException as ex:
errMsg = getSafeExString(ex)
if conf.multipleTargets:
+31 -14
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -10,6 +10,7 @@ from lib.core.data import conf
from lib.core.data import kb
from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES
@@ -21,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy
@@ -46,6 +48,8 @@ from plugins.dbms.db2 import DB2Map
from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.hsqldb import HSQLDBMap
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
from plugins.dbms.h2 import H2Map
from plugins.dbms.h2.connector import Connector as H2Conn
from plugins.dbms.informix import InformixMap
from plugins.dbms.informix.connector import Connector as InformixConn
@@ -67,6 +71,7 @@ def setHandler():
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
]
@@ -90,29 +95,41 @@ def setHandler():
conf.dbmsConnector = Connector()
if conf.direct:
exception = None
dialect = DBMS_DICT[dbms][3]
if dialect:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
try:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
else:
try:
conf.dbmsConnector.connect()
except NameError:
pass
else:
conf.dbmsConnector.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
except Exception as ex:
exception = ex
if not dialect or exception:
try:
conf.dbmsConnector.connect()
except Exception as ex:
if exception:
raise exception
else:
if not isinstance(ex, NameError):
raise
else:
msg = "support for direct connection to '%s' is not available. " % dbms
msg += "Please rerun with '--dependencies'"
raise SqlmapConnectionException(msg)
if conf.forceDbms == dbms or handler.checkDbms():
if kb.resolutionDbms:
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
conf.dbmsHandler._dbms = kb.resolutionDbms
else:
conf.dbmsHandler = handler
conf.dbmsHandler._dbms = dbms
conf.dbmsHandler._dbms = dbms
break
else:
conf.dbmsConnector = None
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+26 -16
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,6 +9,7 @@ import re
from lib.core.common import Backend
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import getSQLSnippet
from lib.core.common import getUnicode
from lib.core.common import isDBMSVersionAtLeast
@@ -23,6 +24,7 @@ from lib.core.common import splitFields
from lib.core.common import unArrayizeValue
from lib.core.common import urlencode
from lib.core.common import zeroDepthSearch
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import queries
@@ -43,6 +45,7 @@ from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import NULL
from lib.core.settings import PAYLOAD_DELIMITER
from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.unescaper import unescaper
@@ -104,9 +107,9 @@ class Agent(object):
if place == PLACE.URI:
origValue = origValue.split(kb.customInjectionMark)[0]
else:
origValue = filter(None, (re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z")))[0].group(0)
origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0)
origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':', ','):
for char in ('?', '=', ':', ',', '&'):
if char in origValue:
origValue = origValue[origValue.rfind(char) + 1:]
elif place == PLACE.CUSTOM_POST:
@@ -142,7 +145,7 @@ class Agent(object):
match = re.search(r"\A[^ ]+", newValue)
newValue = newValue[len(match.group() if match else ""):]
_ = randomInt(2)
value = "%s%s AND %s=%s" % (origValue, match.group() if match else "", _, _ + 1)
value = "%s%s AND %s LIKE %s" % (origValue, match.group() if match else "", _, _ + 1)
elif conf.invalidBignum:
value = randomInt(6)
elif conf.invalidString:
@@ -198,7 +201,7 @@ class Agent(object):
regex = r"(\A|\b)%s=%s%s" % (re.escape(parameter), re.escape(origValue), r"(\Z|\b)" if origValue[-1].isalnum() else "")
retVal = _(regex, "%s=%s" % (parameter, self.addPayloadDelimiters(newValue)), paramString)
else:
retVal = _(r"(\A|\b)%s=%s(\Z|%s|%s|\s)" % (re.escape(parameter), re.escape(origValue), DEFAULT_GET_POST_DELIMITER, DEFAULT_COOKIE_DELIMITER), "%s=%s\g<2>" % (parameter, self.addPayloadDelimiters(newValue)), paramString)
retVal = _(r"(\A|\b)%s=%s(\Z|%s|%s|\s)" % (re.escape(parameter), re.escape(origValue), DEFAULT_GET_POST_DELIMITER, DEFAULT_COOKIE_DELIMITER), r"%s=%s\g<2>" % (parameter, self.addPayloadDelimiters(newValue)), paramString)
if retVal == paramString and urlencode(parameter) != parameter:
retVal = _(r"(\A|\b)%s=%s" % (re.escape(urlencode(parameter)), re.escape(origValue)), "%s=%s" % (urlencode(parameter), self.addPayloadDelimiters(newValue)), paramString)
@@ -246,6 +249,9 @@ class Agent(object):
else:
query = kb.injection.prefix or prefix or ""
if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes
query = query.replace("'[RANDSTR]'", unescaper.escape(randomStr(), quote=False))
if not (expression and expression[0] == ';') and not (query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (query and query[-1] == '('):
query += " "
@@ -311,9 +317,12 @@ class Agent(object):
for _ in set(re.findall(r"(?i)\[RANDSTR(?:\d+)?\]", payload)):
payload = payload.replace(_, randomStr())
if origValue is not None and "[ORIGVALUE]" in payload:
if origValue is not None:
origValue = getUnicode(origValue)
payload = getUnicode(payload).replace("[ORIGVALUE]", origValue if origValue.isdigit() else unescaper.escape("'%s'" % origValue))
if "[ORIGVALUE]" in payload:
payload = getUnicode(payload).replace("[ORIGVALUE]", origValue if origValue.isdigit() else unescaper.escape("'%s'" % origValue))
if "[ORIGINAL]" in payload:
payload = getUnicode(payload).replace("[ORIGINAL]", origValue)
if INFERENCE_MARKER in payload:
if Backend.getIdentifiedDbms() is not None:
@@ -342,6 +351,7 @@ class Agent(object):
if payload:
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)):
payload = payload.replace(_, str(randomInt()))
@@ -535,7 +545,7 @@ class Agent(object):
fieldsToCastStr = fieldsToCastStr or ""
# Function
if re.search("\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
if re.search(r"\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
fieldsToCastList = [fieldsToCastStr]
else:
fieldsToCastList = splitFields(fieldsToCastStr)
@@ -616,7 +626,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):
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -627,7 +637,7 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
_ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
concatenatedQuery = re.sub(r"('%s'\|\|)(.+)(%s)" % (kb.chars.start, re.escape(castedFields)), "\g<2>\g<1>\g<3>", concatenatedQuery)
concatenatedQuery = re.sub(r"('%s'\|\|)(.+)(%s)" % (kb.chars.start, re.escape(castedFields)), r"\g<2>\g<1>\g<3>", concatenatedQuery)
elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -639,7 +649,7 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectTop:
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
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)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
elif fieldsSelectCase:
@@ -815,7 +825,7 @@ class Agent(object):
limitRegExp2 = None
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
@@ -905,14 +915,14 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.HSQLDB):
match = re.search(r"ORDER BY [^ ]+", limitedQuery)
if match:
limitedQuery = re.sub(r"\s*%s\s*" % match.group(0), " ", limitedQuery).strip()
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
limitedQuery += " %s" % match.group(0)
if query.startswith("SELECT "):
@@ -1086,7 +1096,7 @@ class Agent(object):
if conf.dumpWhere and query:
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
if "%s)" % conf.tbl.upper() in prefix.upper():
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)
elif re.search(r"(?i)\bWHERE\b", prefix):
prefix += " AND %s" % conf.dumpWhere
+8 -7
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -16,6 +16,7 @@ import os
import sys
import tempfile
from lib.core.compat import xrange
from lib.core.enums import MKSTEMP_PREFIX
from lib.core.exception import SqlmapSystemException
from lib.core.settings import BIGARRAY_CHUNK_SIZE
@@ -87,7 +88,7 @@ class BigArray(list):
try:
with open(self.chunks[-1], "rb") as f:
self.chunks[-1] = pickle.loads(bz2.decompress(f.read()))
except IOError, ex:
except IOError as ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
raise SqlmapSystemException(errMsg)
@@ -109,7 +110,7 @@ class BigArray(list):
with open(filename, "w+b") as f:
f.write(bz2.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename
except (OSError, IOError), ex:
except (OSError, IOError) as ex:
errMsg = "exception occurred while storing data "
errMsg += "to a temporary file ('%s'). Please " % ex.message
errMsg += "make sure that there is enough disk space left. If problem persists, "
@@ -126,7 +127,7 @@ class BigArray(list):
try:
with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
except IOError, ex:
except Exception as ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
raise SqlmapSystemException(errMsg)
@@ -148,7 +149,7 @@ class BigArray(list):
if y < 0:
y += len(self)
index = y / self.chunk_length
index = y // self.chunk_length
offset = y % self.chunk_length
chunk = self.chunks[index]
@@ -159,7 +160,7 @@ class BigArray(list):
return self.cache.data[offset]
def __setitem__(self, y, value):
index = y / self.chunk_length
index = y // self.chunk_length
offset = y % self.chunk_length
chunk = self.chunks[index]
+686 -233
View File
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import binascii
import os
import random
import uuid
import sys
class WichmannHill(random.Random):
"""
Reference: https://svn.python.org/projects/python/trunk/Lib/random.py
"""
VERSION = 1 # used by getstate/setstate
def seed(self, a=None):
"""Initialize internal state from hashable object.
None or no argument seeds from current time or from an operating
system specific randomness source if available.
If a is not None or an int or long, hash(a) is used instead.
If a is an int or long, a is used directly. Distinct values between
0 and 27814431486575L inclusive are guaranteed to yield distinct
internal states (this guarantee is specific to the default
Wichmann-Hill generator).
"""
if a is None:
try:
a = int(binascii.hexlify(os.urandom(16)), 16)
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
if not isinstance(a, int):
a = hash(a)
a, x = divmod(a, 30268)
a, y = divmod(a, 30306)
a, z = divmod(a, 30322)
self._seed = int(x)+1, int(y)+1, int(z)+1
self.gauss_next = None
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
# Wichman-Hill random number generator.
#
# Wichmann, B. A. & Hill, I. D. (1982)
# Algorithm AS 183:
# An efficient and portable pseudo-random number generator
# Applied Statistics 31 (1982) 188-190
#
# see also:
# Correction to Algorithm AS 183
# Applied Statistics 33 (1984) 123
#
# McLeod, A. I. (1985)
# A remark on Algorithm AS 183
# Applied Statistics 34 (1985),198-200
# This part is thread-unsafe:
# BEGIN CRITICAL SECTION
x, y, z = self._seed
x = (171 * x) % 30269
y = (172 * y) % 30307
z = (170 * z) % 30323
self._seed = x, y, z
# END CRITICAL SECTION
# Note: on a platform using IEEE-754 double arithmetic, this can
# never return 0.0 (asserted by Tim; proof too long for a comment).
return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
def getstate(self):
"""Return internal state; can be passed to setstate() later."""
return self.VERSION, self._seed, self.gauss_next
def setstate(self, state):
"""Restore internal state from object returned by getstate()."""
version = state[0]
if version == 1:
version, self._seed, self.gauss_next = state
else:
raise ValueError("state with version %s passed to "
"Random.setstate() of version %s" %
(version, self.VERSION))
def jumpahead(self, n):
"""Act as if n calls to random() were made, but quickly.
n is an int, greater than or equal to 0.
Example use: If you have 2 threads and know that each will
consume no more than a million random numbers, create two Random
objects r1 and r2, then do
r2.setstate(r1.getstate())
r2.jumpahead(1000000)
Then r1 and r2 will use guaranteed-disjoint segments of the full
period.
"""
if not n >= 0:
raise ValueError("n must be >= 0")
x, y, z = self._seed
x = int(x * pow(171, n, 30269)) % 30269
y = int(y * pow(172, n, 30307)) % 30307
z = int(z * pow(170, n, 30323)) % 30323
self._seed = x, y, z
def __whseed(self, x=0, y=0, z=0):
"""Set the Wichmann-Hill seed from (x, y, z).
These must be integers in the range [0, 256).
"""
if not type(x) == type(y) == type(z) == int:
raise TypeError('seeds must be integers')
if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
raise ValueError('seeds must be in range(0, 256)')
if 0 == x == y == z:
# Initialize from current time
import time
t = int(time.time() * 256)
t = int((t&0xffffff) ^ (t>>24))
t, x = divmod(t, 256)
t, y = divmod(t, 256)
t, z = divmod(t, 256)
# Zero is a poor seed, so substitute 1
self._seed = (x or 1, y or 1, z or 1)
self.gauss_next = None
def whseed(self, a=None):
"""Seed from hashable object's hash code.
None or no argument seeds from current time. It is not guaranteed
that objects with distinct hash codes lead to distinct internal
states.
This is obsolete, provided for compatibility with the seed routine
used prior to Python 2.1. Use the .seed() method instead.
"""
if a is None:
self.__whseed()
return
a = hash(a)
a, x = divmod(a, 256)
a, y = divmod(a, 256)
a, z = divmod(a, 256)
x = (x + a) % 256 or 1
y = (y + a) % 256 or 1
z = (z + a) % 256 or 1
self.__whseed(x, y, z)
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
def choose_boundary():
return uuid.uuid4().hex
if sys.version_info >= (3, 0):
xrange = range
else:
xrange = xrange
+32 -40
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,18 +9,15 @@ try:
import cPickle as pickle
except:
import pickle
finally:
import pickle as picklePy
import base64
import json
import re
import StringIO
import sys
from lib.core.settings import IS_WIN
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import PICKLE_REDUCE_WHITELIST
from thirdparty import six
def base64decode(value):
"""
@@ -30,7 +27,7 @@ def base64decode(value):
'foobar'
"""
return base64.b64decode(value)
return base64.b64decode(unicodeencode(value))
def base64encode(value):
"""
@@ -40,7 +37,7 @@ def base64encode(value):
'Zm9vYmFy'
"""
return base64.b64encode(value)
return base64.b64encode(unicodeencode(value))
def base64pickle(value):
"""
@@ -66,7 +63,7 @@ def base64pickle(value):
return retVal
def base64unpickle(value, unsafe=False):
def base64unpickle(value):
"""
Decodes value from Base64 to plain format and deserializes (with pickle) its content
@@ -76,26 +73,10 @@ def base64unpickle(value, unsafe=False):
retVal = None
def _(self):
if len(self.stack) > 1:
func = self.stack[-2]
if func not in PICKLE_REDUCE_WHITELIST:
raise Exception("abusing reduce() is bad, Mkay!")
self.load_reduce()
def loads(str):
f = StringIO.StringIO(str)
if unsafe:
unpickler = picklePy.Unpickler(f)
unpickler.dispatch[picklePy.REDUCE] = _
else:
unpickler = pickle.Unpickler(f)
return unpickler.load()
try:
retVal = loads(base64decode(value))
retVal = pickle.loads(base64decode(value))
except TypeError:
retVal = loads(base64decode(bytes(value)))
retVal = pickle.loads(base64decode(bytes(value)))
return retVal
@@ -108,7 +89,14 @@ def hexdecode(value):
"""
value = value.lower()
return (value[2:] if value.startswith("0x") else value).decode("hex")
value = value[2:] if value.startswith("0x") else value
if six.PY2:
retVal = value.decode("hex")
else:
retVal = bytes.fromhex(value)
return retVal
def hexencode(value, encoding=None):
"""
@@ -118,7 +106,14 @@ def hexencode(value, encoding=None):
'666f6f626172'
"""
return unicodeencode(value, encoding).encode("hex")
retVal = unicodeencode(value, encoding)
if six.PY2:
retVal = retVal.encode("hex")
else:
retVal = retVal.hex()
return retVal
def unicodeencode(value, encoding=None):
"""
@@ -129,11 +124,13 @@ def unicodeencode(value, encoding=None):
"""
retVal = value
if isinstance(value, unicode):
if isinstance(value, six.text_type):
try:
retVal = value.encode(encoding or UNICODE_ENCODING)
except UnicodeEncodeError:
retVal = value.encode(UNICODE_ENCODING, "replace")
retVal = value.encode(encoding or UNICODE_ENCODING, "replace")
return retVal
def utf8encode(value):
@@ -165,7 +162,7 @@ def htmlunescape(value):
"""
retVal = value
if value and isinstance(value, basestring):
if value and isinstance(value, six.string_types):
codes = (("&lt;", '<'), ("&gt;", '>'), ("&quot;", '"'), ("&nbsp;", ' '), ("&amp;", '&'), ("&apos;", "'"))
retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal)
try:
@@ -183,13 +180,11 @@ def stdoutencode(data):
retVal = None
try:
data = data or ""
retVal = unicodeencode(data or "", sys.stdout.encoding)
# Reference: http://bugs.python.org/issue1602
if IS_WIN:
output = data.encode(sys.stdout.encoding, "replace")
if '?' in output and '?' not in data:
if '?' in retVal and '?' not in retVal:
warnMsg = "cannot properly display Unicode characters "
warnMsg += "inside Windows OS command prompt "
warnMsg += "(http://bugs.python.org/issue1602). All "
@@ -199,11 +194,8 @@ def stdoutencode(data):
warnMsg += "corresponding output files. "
singleTimeWarnMessage(warnMsg)
retVal = output
else:
retVal = data.encode(sys.stdout.encoding)
except:
retVal = data.encode(UNICODE_ENCODING) if isinstance(data, unicode) else data
retVal = unicodeencode(data or "")
return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+97 -2
View File
@@ -1,13 +1,16 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import collections
import copy
import types
from thirdparty.odict import OrderedDict
class AttribDict(dict):
"""
This class defines the sqlmap object, inheriting from Python data
@@ -104,3 +107,95 @@ class InjectionDict(AttribDict):
self.dbms = None
self.dbms_version = None
self.os = None
# Reference: https://www.kunxi.org/2014/05/lru-cache-in-python
class LRUDict(object):
def __init__(self, capacity):
self.capacity = capacity
self.cache = OrderedDict()
def __len__(self):
return len(self.cache)
def __contains__(self, key):
return key in self.cache
def __getitem__(self, key):
value = self.cache.pop(key)
self.cache[key] = value
return value
def get(self, key):
return self.__getitem__(key)
def __setitem__(self, key, value):
try:
self.cache.pop(key)
except KeyError:
if len(self.cache) >= self.capacity:
self.cache.popitem(last=False)
self.cache[key] = value
def set(self, key, value):
self.__setitem__(key, value)
def keys(self):
return self.cache.keys()
# Reference: https://code.activestate.com/recipes/576694/
class OrderedSet(collections.MutableSet):
def __init__(self, iterable=None):
self.end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.map = {} # key --> [key, prev, next]
if iterable is not None:
self |= iterable
def __len__(self):
return len(self.map)
def __contains__(self, key):
return key in self.map
def add(self, key):
if key not in self.map:
end = self.end
curr = end[1]
curr[2] = end[1] = self.map[key] = [key, curr, end]
def discard(self, key):
if key in self.map:
key, prev, next = self.map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def pop(self, last=True):
if not self:
raise KeyError('set is empty')
key = self.end[1][0] if last else self.end[2][0]
self.discard(key)
return key
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, list(self))
def __eq__(self, other):
if isinstance(other, OrderedSet):
return len(self) == len(other) and list(self) == list(other)
return set(self) == set(other)
+27 -8
View File
@@ -1,31 +1,50 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import functools
import hashlib
import threading
from lib.core.settings import MAX_CACHE_ITEMS
from lib.core.datatype import LRUDict
from lib.core.threads import getCurrentThreadData
def cachedmethod(f, cache={}):
_lock = threading.Lock()
def cachedmethod(f, cache=LRUDict(capacity=MAX_CACHE_ITEMS)):
"""
Method with a cached content
Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/
"""
@functools.wraps(f)
def _(*args, **kwargs):
key = int(hashlib.md5("".join(str(_) for _ in (f, args, kwargs))).hexdigest()[:8], 16)
if key not in cache:
cache[key] = f(*args, **kwargs)
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs))).hexdigest(), 16) & 0x7fffffffffffffff
return cache[key]
try:
with _lock:
result = cache[key]
except KeyError:
result = f(*args, **kwargs)
with _lock:
cache[key] = result
return result
return _
def stackedmethod(f):
"""
Method using pushValue/popValue functions (fallback function for stack realignment)
"""
@functools.wraps(f)
def _(*args, **kwargs):
threadData = getCurrentThreadData()
originalLevel = len(threadData.valueStack)
@@ -38,4 +57,4 @@ def stackedmethod(f):
return result
return _
return _
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+39 -2
View File
@@ -1,10 +1,11 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.enums import CONTENT_TYPE
from lib.core.enums import DBMS
from lib.core.enums import OS
from lib.core.enums import POST_HINT
@@ -21,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
FIREBIRD_TYPES = {
@@ -194,6 +196,7 @@ DBMS_DICT = {
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
DBMS.H2: (H2_ALIASES, None, None, None),
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
}
@@ -262,6 +265,10 @@ SQL_STATEMENTS = {
"commit ",
"rollback ",
),
"SQL administration": (
"set ",
),
}
POST_HINT_CONTENT_TYPES = {
@@ -279,6 +286,8 @@ DEPRECATED_OPTIONS = {
"--binary": "use '--binary-fields' instead",
"--auth-private": "use '--auth-file' instead",
"--ignore-401": "use '--ignore-code' instead",
"--second-order": "use '--second-url' instead",
"--purge-output": "use '--purge' instead",
"--check-payload": None,
"--check-waf": None,
"--pickled-options": "use '--api -c ...' instead",
@@ -293,3 +302,31 @@ DEFAULT_DOC_ROOTS = {
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
OS.LINUX: ("/var/www/", "/var/www/html", "/usr/local/apache2/htdocs", "/var/www/nginx-default", "/srv/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
}
PART_RUN_CONTENT_TYPES = {
"checkDbms": CONTENT_TYPE.TECHNIQUES,
"getFingerprint": CONTENT_TYPE.DBMS_FINGERPRINT,
"getBanner": CONTENT_TYPE.BANNER,
"getCurrentUser": CONTENT_TYPE.CURRENT_USER,
"getCurrentDb": CONTENT_TYPE.CURRENT_DB,
"getHostname": CONTENT_TYPE.HOSTNAME,
"isDba": CONTENT_TYPE.IS_DBA,
"getUsers": CONTENT_TYPE.USERS,
"getPasswordHashes": CONTENT_TYPE.PASSWORDS,
"getPrivileges": CONTENT_TYPE.PRIVILEGES,
"getRoles": CONTENT_TYPE.ROLES,
"getDbs": CONTENT_TYPE.DBS,
"getTables": CONTENT_TYPE.TABLES,
"getColumns": CONTENT_TYPE.COLUMNS,
"getSchema": CONTENT_TYPE.SCHEMA,
"getCount": CONTENT_TYPE.COUNT,
"dumpTable": CONTENT_TYPE.DUMP_TABLE,
"search": CONTENT_TYPE.SEARCH,
"sqlQuery": CONTENT_TYPE.SQL_QUERY,
"tableExists": CONTENT_TYPE.COMMON_TABLES,
"columnExists": CONTENT_TYPE.COMMON_COLUMNS,
"readFile": CONTENT_TYPE.FILE_READ,
"writeFile": CONTENT_TYPE.FILE_WRITE,
"osCmd": CONTENT_TYPE.OS_CMD,
"regRead": CONTENT_TYPE.REG_READ
}
+23 -19
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -20,6 +20,7 @@ from lib.core.common import dataToStdout
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import isListLike
from lib.core.common import isMultiThreadMode
from lib.core.common import normalizeUnicode
from lib.core.common import openFile
from lib.core.common import prioritySortColumns
@@ -27,6 +28,7 @@ from lib.core.common import randomInt
from lib.core.common import safeCSValue
from lib.core.common import unicodeencode
from lib.core.common import unsafeSQLIdentificatorNaming
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -47,7 +49,9 @@ from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
from lib.core.settings import VERSION_STRING
from lib.core.settings import WINDOWS_RESERVED_NAMES
from thirdparty import six
from thirdparty.magic import magic
from extra.safe2bin.safe2bin import safechardecode
@@ -73,16 +77,17 @@ class Dump(object):
if console:
dataToStdout(text)
if kb.get("multiThreadMode"):
multiThreadMode = isMultiThreadMode()
if multiThreadMode:
self._lock.acquire()
try:
self._outputFP.write(text)
except IOError, ex:
except IOError as ex:
errMsg = "error occurred while writing to log file ('%s')" % getSafeExString(ex)
raise SqlmapGenericException(errMsg)
if kb.get("multiThreadMode"):
if multiThreadMode:
self._lock.release()
kb.dataOutputFlag = True
@@ -98,7 +103,7 @@ class Dump(object):
self._outputFile = os.path.join(conf.outputPath, "log")
try:
self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb")
except IOError, ex:
except IOError as ex:
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
raise SqlmapGenericException(errMsg)
@@ -109,8 +114,6 @@ class Dump(object):
self._write(data, content_type=content_type)
def string(self, header, data, content_type=None, sort=True):
kb.stickyLevel = None
if conf.api:
self._write(data, content_type=content_type)
return
@@ -132,7 +135,7 @@ class Dump(object):
if "\n" in _:
self._write("%s:\n---\n%s\n---" % (header, _))
else:
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, basestring) else _))
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, six.string_types) else _))
else:
self._write("%s:\tNone" % header)
@@ -141,7 +144,7 @@ class Dump(object):
try:
elements = set(elements)
elements = list(elements)
elements.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
elements.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
except:
pass
@@ -153,7 +156,7 @@ class Dump(object):
self._write("%s [%d]:" % (header, len(elements)))
for element in elements:
if isinstance(element, basestring):
if isinstance(element, six.string_types):
self._write("[*] %s" % element)
elif isListLike(element):
self._write("[*] " + ", ".join(getUnicode(e) for e in element))
@@ -170,7 +173,7 @@ class Dump(object):
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):
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -192,7 +195,7 @@ class Dump(object):
userSettings = userSettings[0]
users = userSettings.keys()
users.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
users.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
if conf.api:
self._write(userSettings, content_type=content_type)
@@ -286,7 +289,7 @@ class Dump(object):
colType = None
colList = columns.keys()
colList.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
colList.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
for column in colList:
colType = columns[column]
@@ -378,7 +381,7 @@ class Dump(object):
if count is None:
count = "Unknown"
tables.sort(key=lambda _: _.lower() if isinstance(_, basestring) else _)
tables.sort(key=lambda _: _.lower() if hasattr(_, "lower") else _)
for table in tables:
blank1 = " " * (maxlength1 - len(normalizeUnicode(table) or unicode(table)))
@@ -425,10 +428,10 @@ class Dump(object):
if not os.path.isdir(dumpDbPath):
try:
os.makedirs(dumpDbPath)
except Exception, ex:
except Exception as ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
except IOError, _:
except IOError as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
@@ -532,6 +535,7 @@ class Dump(object):
elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")
@@ -622,8 +626,8 @@ class Dump(object):
with open(filepath, "wb") as f:
_ = safechardecode(value, True)
f.write(_)
except magic.MagicException, err:
logger.debug(str(err))
except magic.MagicException as ex:
logger.debug(getSafeExString(ex))
if conf.dumpFormat == DUMP_FORMAT.CSV:
if field == fields:
+23 -36
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -43,6 +43,7 @@ class DBMS:
SQLITE = "SQLite"
SYBASE = "Sybase"
HSQLDB = "HSQLDB"
H2 = "H2"
INFORMIX = "Informix"
class DBMS_DIRECTORY_NAME:
@@ -57,6 +58,7 @@ class DBMS_DIRECTORY_NAME:
SQLITE = "sqlite"
SYBASE = "sybase"
HSQLDB = "hsqldb"
H2 = "h2"
INFORMIX = "informix"
class CUSTOM_LOGGING:
@@ -154,13 +156,17 @@ class HASH:
# Reference: http://www.zytrax.com/tech/web/mobile_ids.html
class MOBILES:
BLACKBERRY = ("BlackBerry 9900", "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+")
GALAXY = ("Samsung Galaxy S", "Mozilla/5.0 (Linux; U; Android 2.2; en-US; SGH-T959D Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1")
BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+")
GALAXY = ("Samsung Galaxy S7", "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36")
HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)")
HTC = ("HTC Sensation", "Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30")
IPHONE = ("Apple iPhone 4s", "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3")
HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36")
HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36")
IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.14977")
NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19")
NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344")
PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR3.170623.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36")
XIAOMI = ("Xiaomi Mi 3", "Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; MI 3W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 XiaoMi/MiuiBrowser/2.1.1")
class PROXY_TYPE:
HTTP = "HTTP"
@@ -225,6 +231,7 @@ class HASHDB_KEYS:
DBMS = "DBMS"
DBMS_FORK = "DBMS_FORK"
CHECK_WAF_RESULT = "CHECK_WAF_RESULT"
CHECK_NULL_CONNECTION_RESULT = "CHECK_NULL_CONNECTION_RESULT"
CONF_TMP_PATH = "CONF_TMP_PATH"
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS"
@@ -246,7 +253,7 @@ class PAYLOAD:
2: "error-based",
3: "inline query",
4: "stacked queries",
5: "AND/OR time-based blind",
5: "time-based blind",
6: "UNION query",
}
@@ -256,6 +263,7 @@ class PAYLOAD:
3: "LIKE single quoted string",
4: "Double quoted string",
5: "LIKE double quoted string",
6: "Identifier (e.g. column name)",
}
RISK = {
@@ -275,6 +283,7 @@ class PAYLOAD:
6: "TOP",
7: "Table name",
8: "Column name",
9: "Pre-WHERE (non-query)",
}
class METHOD:
@@ -306,7 +315,7 @@ class ADJUST_TIME_DELAY:
NO = 0
YES = 1
class WEB_API:
class WEB_PLATFORM:
PHP = "php"
ASP = "asp"
ASPX = "aspx"
@@ -340,34 +349,6 @@ class CONTENT_TYPE:
OS_CMD = 24
REG_READ = 25
PART_RUN_CONTENT_TYPES = {
"checkDbms": CONTENT_TYPE.TECHNIQUES,
"getFingerprint": CONTENT_TYPE.DBMS_FINGERPRINT,
"getBanner": CONTENT_TYPE.BANNER,
"getCurrentUser": CONTENT_TYPE.CURRENT_USER,
"getCurrentDb": CONTENT_TYPE.CURRENT_DB,
"getHostname": CONTENT_TYPE.HOSTNAME,
"isDba": CONTENT_TYPE.IS_DBA,
"getUsers": CONTENT_TYPE.USERS,
"getPasswordHashes": CONTENT_TYPE.PASSWORDS,
"getPrivileges": CONTENT_TYPE.PRIVILEGES,
"getRoles": CONTENT_TYPE.ROLES,
"getDbs": CONTENT_TYPE.DBS,
"getTables": CONTENT_TYPE.TABLES,
"getColumns": CONTENT_TYPE.COLUMNS,
"getSchema": CONTENT_TYPE.SCHEMA,
"getCount": CONTENT_TYPE.COUNT,
"dumpTable": CONTENT_TYPE.DUMP_TABLE,
"search": CONTENT_TYPE.SEARCH,
"sqlQuery": CONTENT_TYPE.SQL_QUERY,
"tableExists": CONTENT_TYPE.COMMON_TABLES,
"columnExists": CONTENT_TYPE.COMMON_COLUMNS,
"readFile": CONTENT_TYPE.FILE_READ,
"writeFile": CONTENT_TYPE.FILE_WRITE,
"osCmd": CONTENT_TYPE.OS_CMD,
"regRead": CONTENT_TYPE.REG_READ
}
class CONTENT_STATUS:
IN_PROGRESS = 0
COMPLETE = 1
@@ -382,6 +363,7 @@ class AUTOCOMPLETE_TYPE:
SQL = 0
OS = 1
SQLMAP = 2
API = 3
class NOTE:
FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable"
@@ -396,8 +378,13 @@ class MKSTEMP_PREFIX:
COOKIE_JAR = "sqlmapcookiejar-"
BIG_ARRAY = "sqlmapbigarray-"
SPECIFIC_RESPONSE = "sqlmapresponse-"
PREPROCESS = "sqlmappreprocess-"
class TIMEOUT_STATE:
NORMAL = 0
EXCEPTION = 1
TIMEOUT = 2
class HINT:
PREPEND = 0
APPEND = 1
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+374 -373
View File
File diff suppressed because it is too large Load Diff
+12 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -61,6 +61,7 @@ optDict = {
"csrfToken": "string",
"csrfUrl": "string",
"forceSSL": "boolean",
"chunked": "boolean",
"hpp": "boolean",
"evalCode": "string",
},
@@ -109,7 +110,8 @@ optDict = {
"uChar": "string",
"uFrom": "string",
"dnsDomain": "string",
"secondOrder": "string",
"secondUrl": "string",
"secondReq": "string",
},
"Fingerprint": {
@@ -164,9 +166,9 @@ optDict = {
},
"File system": {
"rFile": "string",
"wFile": "string",
"dFile": "string",
"fileRead": "string",
"fileWrite": "string",
"fileDest": "string",
},
"Takeover": {
@@ -191,7 +193,6 @@ optDict = {
},
"General": {
# "xmlFile": "string",
"trafficFile": "string",
"batch": "boolean",
"binaryFields": "string",
@@ -210,6 +211,8 @@ optDict = {
"hexConvert": "boolean",
"outputDir": "string",
"parseErrors": "boolean",
"preprocess": "string",
"repair": "boolean",
"saveConfig": "string",
"scope": "string",
"testFilter": "string",
@@ -226,9 +229,10 @@ optDict = {
"disableColoring": "boolean",
"googlePage": "integer",
"identifyWaf": "boolean",
"listTampers": "boolean",
"mobile": "boolean",
"offline": "boolean",
"purgeOutput": "boolean",
"purge": "boolean",
"skipWaf": "boolean",
"smart": "boolean",
"tmpDir": "string",
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
from lib.core.settings import IS_WIN
from thirdparty.six.moves import http_client as _http_client
def dirtyPatches():
"""
Place for "dirty" Python related patches
"""
# accept overly long result lines (e.g. SQLi results in HTTP header responses)
_http_client._MAXLINE = 1 * 1024 * 1024
# add support for inet_pton() on Windows OS
if IS_WIN:
from thirdparty.wininetpton import win_inet_pton
# Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
# Reference: http://bugs.python.org/issue17849
if hasattr(_http_client, "LineAndFileWrapper"):
def _(self, *args):
return self._readline()
_http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
_http_client.LineAndFileWrapper.readline = _
+22 -17
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,7 +9,7 @@ import codecs
import os
import cProfile
from lib.core.common import getUnicode
from lib.core.common import getSafeExString
from lib.core.data import logger
from lib.core.data import paths
from lib.core.settings import UNICODE_ENCODING
@@ -25,8 +25,8 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
from thirdparty.xdot import xdot
import gtk
import pydot
except ImportError, e:
errMsg = "profiling requires third-party libraries ('%s') " % getUnicode(e, UNICODE_ENCODING)
except ImportError as ex:
errMsg = "profiling requires third-party libraries ('%s') " % getSafeExString(ex)
errMsg += "(Hint: 'sudo apt-get install python-pydot python-pyparsing python-profiler graphviz')"
logger.error(errMsg)
@@ -50,7 +50,7 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
if os.path.exists(imageOutputFile):
os.remove(imageOutputFile)
infoMsg = "profiling the execution into file %s" % profileOutputFile
infoMsg = "profiling the execution into file '%s'" % profileOutputFile
logger.info(infoMsg)
# Start sqlmap main function and generate a raw profile file
@@ -80,15 +80,20 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
if isinstance(pydotGraph, list):
pydotGraph = pydotGraph[0]
pydotGraph.write_png(imageOutputFile)
try:
pydotGraph.write_png(imageOutputFile)
except OSError:
errMsg = "profiling requires graphviz installed "
errMsg += "(Hint: 'sudo apt-get install graphviz')"
logger.error(errMsg)
else:
infoMsg = "displaying interactive graph with xdot library"
logger.info(infoMsg)
infoMsg = "displaying interactive graph with xdot library"
logger.info(infoMsg)
# Display interactive Graphviz dot file by using extra/xdot/xdot.py
# http://code.google.com/p/jrfonseca/wiki/XDot
win = xdot.DotWindow()
win.connect('destroy', gtk.main_quit)
win.set_filter("dot")
win.open_file(dotOutputFile)
gtk.main()
# Display interactive Graphviz dot file by using extra/xdot/xdot.py
# http://code.google.com/p/jrfonseca/wiki/XDot
win = xdot.DotWindow()
win.connect('destroy', gtk.main_quit)
win.set_filter("dot")
win.open_file(dotOutputFile)
gtk.main()
+3 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -56,9 +56,7 @@ if PLATFORM == 'mac' and _readline:
# http://mail.python.org/pipermail/python-dev/2003-August/037845.html
# has the original discussion.
if _readline:
try:
_readline.clear_history()
except AttributeError:
if not hasattr(_readline, "clear_history"):
def clear_history():
pass
+5 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -27,7 +27,7 @@ class Replication(object):
self.connection = sqlite3.connect(dbpath)
self.connection.isolation_level = None
self.cursor = self.connection.cursor()
except sqlite3.OperationalError, ex:
except sqlite3.OperationalError as ex:
errMsg = "error occurred while opening a replication "
errMsg += "file '%s' ('%s')" % (self.filepath, getSafeExString(ex))
raise SqlmapConnectionException(errMsg)
@@ -63,7 +63,7 @@ class Replication(object):
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s" %s' % (unsafeSQLIdentificatorNaming(colname), coltype) for colname, coltype in self.columns)))
else:
self.execute('CREATE TABLE "%s" (%s)' % (self.name, ','.join('"%s"' % unsafeSQLIdentificatorNaming(colname) for colname in self.columns)))
except Exception, ex:
except Exception as ex:
errMsg = "problem occurred ('%s') while initializing the sqlite database " % getSafeExString(ex, UNICODE_ENCODING)
errMsg += "located at '%s'" % self.parent.dbpath
raise SqlmapGenericException(errMsg)
@@ -82,7 +82,7 @@ class Replication(object):
def execute(self, sql, parameters=[]):
try:
self.parent.cursor.execute(sql, parameters)
except sqlite3.OperationalError, ex:
except sqlite3.OperationalError as ex:
errMsg = "problem occurred ('%s') while accessing sqlite database " % getSafeExString(ex, UNICODE_ENCODING)
errMsg += "located at '%s'. Please make sure that " % self.parent.dbpath
errMsg += "it's not used by some other program"
+9 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -44,9 +44,12 @@ def getRevisionNumber():
break
if not retVal:
process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, _ = process.communicate()
match = re.search(r"(?i)[0-9a-f]{32}", stdout or "")
retVal = match.group(0) if match else None
try:
process = subprocess.Popen("git rev-parse --verify HEAD", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, _ = process.communicate()
match = re.search(r"(?i)[0-9a-f]{32}", stdout or "")
retVal = match.group(0) if match else None
except:
pass
return retVal[:7] if retVal else None
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+80 -48
View File
@@ -1,30 +1,29 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import os
import random
import re
import subprocess
import string
import sys
import types
from lib.core.datatype import AttribDict
from lib.core.enums import DBMS
from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.2.5.0"
VERSION = "1.3.4.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)
DESCRIPTION = "automatic SQL injection and database takeover tool"
SITE = "http://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
DEV_EMAIL_ADDRESS = "[email protected]"
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
@@ -38,17 +37,17 @@ BANNER = """\033[01;33m\
___ ___[.]_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m
|_ -| . [.] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V |_| \033[0m\033[4;37m%s\033[0m\n
|_|V... |_| \033[0m\033[4;37m%s\033[0m\n
""" % (TYPE_COLORS.get(TYPE, 31), VERSION_STRING.split('/')[-1], SITE)
# Minimum distance of ratio from kb.matchRatio to result in True
DIFF_TOLERANCE = 0.05
CONSTANT_RATIO = 0.9
# Ratio used in heuristic check for WAF/IPS/IDS protected targets
# Ratio used in heuristic check for WAF/IPS protected targets
IDS_WAF_CHECK_RATIO = 0.5
# Timeout used in heuristic check for WAF/IPS/IDS protected targets
# Timeout used in heuristic check for WAF/IPS protected targets
IDS_WAF_CHECK_TIMEOUT = 10
# Lower and upper values for match ratio in case of stable page
@@ -71,6 +70,7 @@ RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
SLEEP_TIME_MARKER = "[SLEEPTIME]"
INFERENCE_MARKER = "[INFERENCE]"
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
CHAR_INFERENCE_MARK = "%c"
@@ -97,6 +97,9 @@ MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
# Timeout before the pre-connection candidate is being disposed (because of high probability that the web server will reset it)
PRECONNECT_CANDIDATE_TIMEOUT = 10
# Servers known to cause issue with pre-connection mechanism (because of lack of multi-threaded support)
PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP", "BaseHTTP")
# Maximum sleep time in "Murphy" (testing) mode
MAX_MURPHY_SLEEP_TIME = 3
@@ -104,7 +107,7 @@ MAX_MURPHY_SLEEP_TIME = 3
GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&amp;cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)"
# Regular expression used for extracting results from DuckDuckGo search
DUCKDUCKGO_REGEX = r'"u":"([^"]+)'
DUCKDUCKGO_REGEX = r'<a class="result__url" href="(htt[^"]+)'
# Regular expression used for extracting results from Bing search
BING_REGEX = r'<h2><a href="([^"]+)" h='
@@ -161,6 +164,9 @@ MAX_TECHNIQUES_PER_VALUE = 2
# In case of missing piece of partial union dump, buffered array must be flushed after certain size
MAX_BUFFERED_PARTIAL_UNION_LENGTH = 1024
# Maximum size of cache used in @cachedmethod decorator
MAX_CACHE_ITEMS = 256
# Suffix used for naming meta databases in DBMS(es) without explicit database name
METADB_SUFFIX = "_masterdb"
@@ -170,11 +176,14 @@ PUSH_VALUE_EXCEPTION_RETRY_COUNT = 3
# Minimum time response set needed for time-comparison based on standard deviation
MIN_TIME_RESPONSES = 30
# Maximum time response set used during time-comparison based on standard deviation
MAX_TIME_RESPONSES = 200
# Minimum comparison ratio set needed for searching valid union column number based on standard deviation
MIN_UNION_RESPONSES = 5
# After these number of blanks at the end inference should stop (just in case)
INFERENCE_BLANK_BREAK = 10
INFERENCE_BLANK_BREAK = 5
# Use this replacement character for cases when inference is not able to retrieve the proper character value
INFERENCE_UNKNOWN_CHAR = '?'
@@ -207,23 +216,24 @@ DUMMY_USER_PREFIX = "__dummy__"
DEFAULT_PAGE_ENCODING = "iso-8859-1"
try:
unicode(DEFAULT_PAGE_ENCODING, DEFAULT_PAGE_ENCODING)
codecs.lookup(DEFAULT_PAGE_ENCODING)
except LookupError:
DEFAULT_PAGE_ENCODING = "utf8"
# Marker for program piped input
STDIN_PIPE_DASH = '-'
# URL used in dummy runs
DUMMY_URL = "http://foo/bar?id=1"
# System variables
IS_WIN = subprocess.mswindows
# The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
PLATFORM = os.name
PYVERSION = sys.version.split()[0]
IS_WIN = PLATFORM == "nt"
# DBMS system databases
MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb")
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema")
MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema", "sys")
PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent")
ORACLE_SYSTEM_DBS = ('ANONYMOUS', 'APEX_030200', 'APEX_PUBLIC_USER', 'APPQOSSYS', 'BI', 'CTXSYS', 'DBSNMP', 'DIP', 'EXFSYS', 'FLOWS_%', 'FLOWS_FILES', 'HR', 'IX', 'LBACSYS', 'MDDATA', 'MDSYS', 'MGMT_VIEW', 'OC', 'OE', 'OLAPSYS', 'ORACLE_OCM', 'ORDDATA', 'ORDPLUGINS', 'ORDSYS', 'OUTLN', 'OWBSYS', 'PM', 'SCOTT', 'SH', 'SI_INFORMTN_SCHEMA', 'SPATIAL_CSW_ADMIN_USR', 'SPATIAL_WFS_ADMIN_USR', 'SYS', 'SYSMAN', 'SYSTEM', 'WKPROXY', 'WKSYS', 'WK_TEST', 'WMSYS', 'XDB', 'XS$NULL')
SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master")
@@ -233,6 +243,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")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -246,20 +257,21 @@ MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",)
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
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 + INFORMIX_ALIASES
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
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_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))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
HOST_ALIASES = ("host",)
HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
# 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")
@@ -317,17 +329,19 @@ CURRENT_DB = "CD"
SESSION_SQLITE_FILE = "session.sqlite"
# Regular expressions used for finding file paths in error messages
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"href=['\"]file://(?P<result>/[^'\"]+)")
FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"\bin (?P<result>[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P<result>[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P<result>/\w[/\w.~-]+)", r"\bhref=['\"]file://(?P<result>/[^'\"]+)", r"\bin <b>(?P<result>[^<]+): line \d+")
# Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = (
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)",
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>[^<]+)",
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
r"<li>Error Type:<br>(?P<result>.+?)</li>",
r"(?s)<li>Error Type:<br>(?P<result>.+?)</li>",
r"CDbCommand (?P<result>[^<>\n]*SQL[^<>\n]+)",
r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P<result>[^<>]+)",
r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)"
r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P<result>[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)",
r"(?P<result>query error: SELECT[^<>]+)"
)
# Regular expression used for parsing charset info from meta html headers
@@ -349,7 +363,7 @@ COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "
WEBSCARAB_SPLITTER = "### Conversation"
# Splitter used between requests in BURP log files
BURP_REQUEST_REGEX = r"={10,}\s+[^=]+={10,}\s(.+?)\s={10,}"
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+={10,}"
# Regex used for parsing XML Burp saved history items
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
@@ -364,10 +378,10 @@ URI_HTTP_HEADER = "URI"
URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
# Regex used for masking sensitive data
SENSITIVE_DATA_REGEX = "(\s|=)(?P<result>[^\s=]*%s[^\s]*)\s"
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\s]*)\s"
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
SENSITIVE_OPTIONS = ("hostname", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "rFile", "wFile", "dFile", "testParameter", "authCred")
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred")
# Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10
@@ -388,7 +402,7 @@ CANDIDATE_SENTENCE_MIN_LENGTH = 10
CUSTOM_INJECTION_MARK_CHAR = '*'
# Other way to declare injection position
INJECT_HERE_REGEX = '(?i)%INJECT[_ ]?HERE%'
INJECT_HERE_REGEX = r"(?i)%INJECT[_ ]?HERE%"
# Minimum chunk length used for retrieving data over error based payloads
MIN_ERROR_CHUNK_LENGTH = 8
@@ -406,7 +420,7 @@ REFLECTED_VALUE_MARKER = "__REFLECTED_VALUE__"
REFLECTED_BORDER_REGEX = r"[^A-Za-z]+"
# Regular expression used for replacing non-alphanum characters
REFLECTED_REPLACEMENT_REGEX = r".+"
REFLECTED_REPLACEMENT_REGEX = r"[^\n]{1,100}"
# Maximum time (in seconds) spent per reflective value(s) replacement
REFLECTED_REPLACEMENT_TIMEOUT = 3
@@ -426,8 +440,11 @@ DEFAULT_MSSQL_SCHEMA = "dbo"
# Display hash attack info every mod number of items
HASH_MOD_ITEM_DISPLAY = 11
# Display marker for (cracked) empty password
HASH_EMPTY_PASSWORD_MARKER = "<empty>"
# Maximum integer value
MAX_INT = sys.maxint
MAX_INT = sys.maxsize
# Replacement for unsafe characters in dump table filenames
UNSAFE_DUMP_FILEPATH_REPLACEMENT = '_'
@@ -487,13 +504,11 @@ LEGAL_DISCLAIMER = "Usage of sqlmap for attacking targets without prior mutual c
REFLECTIVE_MISS_THRESHOLD = 20
# Regular expression used for extracting HTML title
HTML_TITLE_REGEX = "<title>(?P<result>[^<]+)</title>"
HTML_TITLE_REGEX = r"<title>(?P<result>[^<]+)</title>"
# Table used for Base64 conversion in WordPress hash cracking routine
ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
PICKLE_REDUCE_WHITELIST = (types.BooleanType, types.DictType, types.FloatType, types.IntType, types.ListType, types.LongType, types.NoneType, types.StringType, types.TupleType, types.UnicodeType, types.XRangeType, type(AttribDict()), type(set()))
# Chars used to quickly distinguish if the user provided tainted parameter values
DUMMY_SQL_INJECTION_CHARS = ";()'"
@@ -512,9 +527,6 @@ BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)"
# Template used for common column existence check
BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
# Payload used for checking of existence of IDS/IPS/WAF (dummier the better)
IDS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
# Data inside shellcodeexec to be filled with random string
SHELLCODEEXEC_RANDOM_STRING_MARKER = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
@@ -524,13 +536,16 @@ CHECK_INTERNET_ADDRESS = "https://ipinfo.io/"
# Value to look for in response to CHECK_INTERNET_ADDRESS
CHECK_INTERNET_VALUE = "IP Address Details"
# Vectors used for provoking specific WAF/IPS/IDS behavior(s)
# Payload used for checking of existence of WAF/IPS (dummier the better)
IPS_WAF_CHECK_PAYLOAD = "AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#"
# Vectors used for provoking specific WAF/IPS behavior(s)
WAF_ATTACK_VECTORS = (
"", # NIL
"search=<script>alert(1)</script>",
"file=../../../../etc/passwd",
"q=<invalid>foobar",
"id=1 %s" % IDS_WAF_CHECK_PAYLOAD
"id=1 %s" % IPS_WAF_CHECK_PAYLOAD
)
# Used for status representation in dictionary attack phase
@@ -571,7 +586,7 @@ UNION_CHAR_REGEX = r"\A\w+\Z"
UNENCODED_ORIGINAL_VALUE = "original"
# Common column names containing usernames (used for hash cracking in some cases)
COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "usufrutuario", "korisnik", "usuario", "consumidor", "client", "cuser")
COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "utilizator", "utilizador", "usufrutuario", "korisnik", "uporabnik", "usuario", "consumidor", "client", "cuser")
# Default delimiter in GET/POST values
DEFAULT_GET_POST_DELIMITER = '&'
@@ -583,7 +598,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
# Github OAuth token used for creating an automatic Issue for unhandled exceptions
GITHUB_REPORT_OAUTH_TOKEN = "NTMyNWNkMmZkMzRlMDZmY2JkMmY0MGI4NWI0MzVlM2Q5YmFjYWNhYQ=="
GITHUB_REPORT_OAUTH_TOKEN = "NTYzYjhmZWJjYzc0Njg2ODJhNzhmNDg1YzM0YzlkYjk3N2JiMzE3Nw=="
# Skip unforced HashDB flush requests below the threshold number of cached items
HASHDB_FLUSH_THRESHOLD = 32
@@ -598,7 +613,7 @@ HASHDB_RETRIEVE_RETRIES = 3
HASHDB_END_TRANSACTION_RETRIES = 3
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
HASHDB_MILESTONE_VALUE = "dPHoJRQYvs" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))'
HASHDB_MILESTONE_VALUE = "BZzRotigLX" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))'
# Warn user of possible delay due to large page dump in full UNION query injections
LARGE_OUTPUT_THRESHOLD = 1024 ** 2
@@ -631,7 +646,7 @@ BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
# Regular expression used for recognition of file inclusion errors
FI_ERROR_REGEX = "(?i)[^\n]{0,100}(no such file|failed (to )?open)[^\n]{0,100}"
FI_ERROR_REGEX = r"(?i)[^\n]{0,100}(no such file|failed (to )?open)[^\n]{0,100}"
# Length of prefix and suffix used in non-SQLI heuristic checks
NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
@@ -661,7 +676,10 @@ 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")
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")
# 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")
# Generic www root directory names
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
@@ -673,7 +691,7 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100
# Strings for detecting formatting errors
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "DataTypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
# Regular expression used for extracting ASP.NET view state values
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
@@ -741,14 +759,14 @@ METASPLOIT_SESSION_TIMEOUT = 120
# Reference: http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject.html
LOBLKSIZE = 2048
# Suffix used to mark variables having keyword names
EVALCODE_KEYWORD_SUFFIX = "_KEYWORD"
# Prefix used to mark special variables (e.g. keywords, having special chars, etc.)
EVALCODE_ENCODED_PREFIX = "EVAL_"
# Reference: http://www.cookiecentral.com/faq/#3.5
NETSCAPE_FORMAT_HEADER_COOKIES = "# Netscape HTTP Cookie File."
# Infixes used for automatic recognition of parameters carrying anti-CSRF tokens
CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf")
CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token")
# Prefixes used in brute force search for web server document root
BRUTE_DOC_ROOT_PREFIXES = {
@@ -756,6 +774,9 @@ BRUTE_DOC_ROOT_PREFIXES = {
OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%")
}
# Table prefix to use in "takeover" functionalities (i.e. auxiliary tables used by sqlmap at the vulnerable DBMS)
TAKEOVER_TABLE_PREFIX = "sqlmap"
# Suffixes used in brute force search for web server document root
BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build")
@@ -768,6 +789,9 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
# Letters of lower frequency used in kb.chars
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
# SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk)
HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules")
# CSS style used in HTML dump format
HTML_DUMP_CSS_STYLE = """<style>
table{
@@ -786,9 +810,17 @@ tr:nth-child(even) {
background-color: #D3DFEE
}
td{
font-size:10px;
font-size:12px;
}
th{
font-size:10px;
font-size:12px;
}
</style>"""
# Leaving (dirty) possibility to change values from here (e.g. `export SQLMAP__MAX_NUMBER_OF_THREADS=20`)
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
+31 -23
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,6 +9,7 @@ import atexit
import os
from lib.core import readlineng as readline
from lib.core.common import getSafeExString
from lib.core.data import logger
from lib.core.data import paths
from lib.core.enums import AUTOCOMPLETE_TYPE
@@ -53,28 +54,33 @@ def clearHistory():
readline.clear_history()
def saveHistory(completion=None):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
pass
except:
pass
except:
pass
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError as ex:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, getSafeExString(ex))
logger.warn(warnMsg)
except KeyboardInterrupt:
pass
def loadHistory(completion=None):
if not readlineAvailable():
@@ -86,14 +92,16 @@ def loadHistory(completion=None):
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
if os.path.exists(historyPath):
try:
readline.read_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem loading the history file '%s' (%s)" % (historyPath, msg)
except IOError as ex:
warnMsg = "there was a problem loading the history file '%s' (%s)" % (historyPath, getSafeExString(ex))
logger.warn(warnMsg)
def autoCompletion(completion=None, os=None, commands=None):
+11 -11
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -31,7 +31,7 @@ def blockingReadFromFD(fd):
while True:
try:
output += os.read(fd, 8192)
except (OSError, IOError), ioe:
except (OSError, IOError) as ioe:
if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
# Uncomment the following line if the process seems to
# take a huge amount of cpu time
@@ -52,7 +52,7 @@ def blockingWriteToFD(fd, data):
try:
data_length = len(data)
wrote_data = os.write(fd, data)
except (OSError, IOError), io:
except (OSError, IOError) as io:
if io.errno in (errno.EAGAIN, errno.EINTR):
continue
else:
@@ -85,7 +85,7 @@ class Popen(subprocess.Popen):
getattr(self, which).close()
setattr(self, which, None)
if subprocess.mswindows:
if IS_WIN:
def send(self, input):
if not self.stdin:
return None
@@ -95,8 +95,8 @@ class Popen(subprocess.Popen):
(errCode, written) = WriteFile(x, input)
except ValueError:
return self._close('stdin')
except (subprocess.pywintypes.error, Exception), why:
if why[0] in (109, errno.ESHUTDOWN):
except (subprocess.pywintypes.error, Exception) as ex:
if ex[0] in (109, errno.ESHUTDOWN):
return self._close('stdin')
raise
@@ -116,8 +116,8 @@ class Popen(subprocess.Popen):
(errCode, read) = ReadFile(x, nAvail, None)
except (ValueError, NameError):
return self._close(which)
except (subprocess.pywintypes.error, Exception), why:
if why[0] in (109, errno.ESHUTDOWN):
except (subprocess.pywintypes.error, Exception) as ex:
if ex[0] in (109, errno.ESHUTDOWN):
return self._close(which)
raise
@@ -134,8 +134,8 @@ class Popen(subprocess.Popen):
try:
written = os.write(self.stdin.fileno(), input)
except OSError, why:
if why[0] == errno.EPIPE: # broken pipe
except OSError as ex:
if ex[0] == errno.EPIPE: # broken pipe
return self._close('stdin')
raise
+53 -56
View File
@@ -1,11 +1,10 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import functools
import os
import re
@@ -13,7 +12,6 @@ import subprocess
import sys
import tempfile
import time
import urlparse
from lib.core.common import Backend
from lib.core.common import getSafeExString
@@ -28,6 +26,7 @@ from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import resetCookieJar
from lib.core.common import urldecode
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@@ -45,6 +44,7 @@ from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUserQuitException
from lib.core.option import _setDBMS
@@ -52,9 +52,11 @@ from lib.core.option import _setKnowledgeBaseAttributes
from lib.core.option import _setAuthCred
from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import HOST_ALIASES
from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import JSON_RECOGNITION_REGEX
from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX
from lib.core.settings import MULTIPART_RECOGNITION_REGEX
@@ -71,7 +73,8 @@ from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import USER_AGENT_ALIASES
from lib.core.settings import XML_RECOGNITION_REGEX
from lib.utils.hashdb import HashDB
from thirdparty.odict.odict import OrderedDict
from thirdparty.odict import OrderedDict
from thirdparty.six.moves import urllib as _urllib
def _setRequestParams():
"""
@@ -83,6 +86,7 @@ def _setRequestParams():
conf.parameters[None] = "direct connection"
return
hintNames = []
testableParameters = False
# Perform checks on GET parameters
@@ -101,7 +105,6 @@ def _setRequestParams():
if conf.data is not None:
conf.method = HTTPMETHOD.POST if not conf.method or conf.method == HTTPMETHOD.GET else conf.method
hintNames = []
def process(match, repl):
retVal = match.group(0)
@@ -148,8 +151,8 @@ def _setRequestParams():
match = re.search(r'(?P<name>[^"]+)"\s*:\s*\[([^\]]+)\]', conf.data)
if match and not (conf.testParameter and match.group("name") not in conf.testParameter):
_ = match.group(2)
_ = re.sub(r'("[^"]+)"', '\g<1>%s"' % kb.customInjectionMark, _)
_ = re.sub(r'(\A|,|\s+)(-?\d[\d\.]*\b)', '\g<0>%s' % kb.customInjectionMark, _)
_ = re.sub(r'("[^"]+)"', r'\g<1>%s"' % kb.customInjectionMark, _)
_ = 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
@@ -210,7 +213,7 @@ def _setRequestParams():
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]+)[\"']?).+?)(((\r)?\n)+--)", functools.partial(process, repl=r"\g<1>%s\g<4>" % kb.customInjectionMark), conf.data)
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
@@ -274,7 +277,7 @@ def _setRequestParams():
if not kb.processUserMarks:
if place == PLACE.URI:
query = urlparse.urlsplit(value).query
query = _urllib.parse.urlsplit(value).query
if query:
parameters = conf.parameters[PLACE.GET] = query
paramDict = paramToDict(PLACE.GET, parameters)
@@ -344,7 +347,7 @@ def _setRequestParams():
# Url encoding of the header values should be avoided
# Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value
if httpHeader.title() == HTTP_HEADER.USER_AGENT:
if httpHeader.upper() == HTTP_HEADER.USER_AGENT.upper():
conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True)))
@@ -353,7 +356,7 @@ def _setRequestParams():
conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.REFERER:
elif httpHeader.upper() == HTTP_HEADER.REFERER.upper():
conf.parameters[PLACE.REFERER] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True)))
@@ -362,7 +365,7 @@ def _setRequestParams():
conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.HOST:
elif httpHeader.upper() == HTTP_HEADER.HOST.upper():
conf.parameters[PLACE.HOST] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True)))
@@ -391,8 +394,8 @@ def _setRequestParams():
raise SqlmapGenericException(errMsg)
if conf.csrfToken:
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) and not re.search(r"\b%s\b" % re.escape(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, {}):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))) 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, {}):
errMsg = "anti-CSRF token parameter '%s' not " % conf.csrfToken._original
errMsg += "found in provided GET, POST, Cookie or header values"
raise SqlmapGenericException(errMsg)
else:
@@ -406,7 +409,10 @@ def _setRequestParams():
message += "Do you want sqlmap to automatically update it in further requests? [y/N] "
if readInput(message, default='N', boolean=True):
conf.csrfToken = getUnicode(parameter)
class _(unicode):
pass
conf.csrfToken = _(re.escape(getUnicode(parameter)))
conf.csrfToken._original = getUnicode(parameter)
break
def _setHashDB():
@@ -422,8 +428,8 @@ def _setHashDB():
try:
os.remove(conf.hashDBFile)
logger.info("flushing session file")
except OSError, msg:
errMsg = "unable to flush the session file (%s)" % msg
except OSError as ex:
errMsg = "unable to flush the session file ('%s')" % getSafeExString(ex)
raise SqlmapFilePathException(errMsg)
conf.hashDB = HashDB(conf.hashDBFile)
@@ -467,7 +473,13 @@ def _resumeDBMS():
value = hashDBRetrieve(HASHDB_KEYS.DBMS)
if not value:
return
if conf.offline:
errMsg = "unable to continue in offline mode "
errMsg += "because of lack of usable "
errMsg += "session data"
raise SqlmapNoneDataException(errMsg)
else:
return
dbms = value.lower()
dbmsVersion = [UNKNOWN_DBMS_VERSION]
@@ -547,7 +559,7 @@ def _setResultsFile():
conf.resultsFilename = os.path.join(paths.SQLMAP_OUTPUT_PATH, time.strftime(RESULTS_FILE_FORMAT).lower())
try:
conf.resultsFP = openFile(conf.resultsFilename, "a", UNICODE_ENCODING, buffering=0)
except (OSError, IOError), ex:
except (OSError, IOError) as ex:
try:
warnMsg = "unable to create results file '%s' ('%s'). " % (conf.resultsFilename, getUnicode(ex))
handle, conf.resultsFilename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.RESULTS, suffix=".csv")
@@ -555,7 +567,7 @@ def _setResultsFile():
conf.resultsFP = openFile(conf.resultsFilename, "w+", UNICODE_ENCODING, buffering=0)
warnMsg += "Using temporary file '%s' instead" % conf.resultsFilename
logger.warn(warnMsg)
except IOError, _:
except IOError as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
@@ -571,7 +583,7 @@ def _createFilesDir():
Create the file directory.
"""
if not conf.rFile:
if not conf.fileRead:
return
conf.filePath = paths.SQLMAP_FILES_PATH % conf.hostname
@@ -579,7 +591,7 @@ def _createFilesDir():
if not os.path.isdir(conf.filePath):
try:
os.makedirs(conf.filePath)
except OSError, ex:
except OSError as ex:
tempDir = tempfile.mkdtemp(prefix="sqlmapfiles")
warnMsg = "unable to create files directory "
warnMsg += "'%s' (%s). " % (conf.filePath, getUnicode(ex))
@@ -601,7 +613,7 @@ def _createDumpDir():
if not os.path.isdir(conf.dumpPath):
try:
os.makedirs(conf.dumpPath)
except OSError, ex:
except OSError as ex:
tempDir = tempfile.mkdtemp(prefix="sqlmapdump")
warnMsg = "unable to create dump directory "
warnMsg += "'%s' (%s). " % (conf.dumpPath, getUnicode(ex))
@@ -619,43 +631,15 @@ def _createTargetDirs():
Create the output directory.
"""
try:
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
os.makedirs(paths.SQLMAP_OUTPUT_PATH)
_ = os.path.join(paths.SQLMAP_OUTPUT_PATH, randomStr())
open(_, "w+b").close()
os.remove(_)
if conf.outputDir:
warnMsg = "using '%s' as the output directory" % paths.SQLMAP_OUTPUT_PATH
logger.warn(warnMsg)
except (OSError, IOError), ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmapoutput")
except Exception, _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
errMsg += "create temporary files and/or directories"
raise SqlmapSystemException(errMsg)
warnMsg = "unable to %s output directory " % ("create" if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH) else "write to the")
warnMsg += "'%s' (%s). " % (paths.SQLMAP_OUTPUT_PATH, getUnicode(ex))
warnMsg += "Using temporary directory '%s' instead" % getUnicode(tempDir)
logger.warn(warnMsg)
paths.SQLMAP_OUTPUT_PATH = tempDir
conf.outputPath = os.path.join(getUnicode(paths.SQLMAP_OUTPUT_PATH), normalizeUnicode(getUnicode(conf.hostname)))
try:
if not os.path.isdir(conf.outputPath):
os.makedirs(conf.outputPath)
except (OSError, IOError, TypeError), ex:
except (OSError, IOError, TypeError) as ex:
try:
tempDir = tempfile.mkdtemp(prefix="sqlmapoutput")
except Exception, _:
except Exception as _:
errMsg = "unable to write to the temporary directory ('%s'). " % _
errMsg += "Please make sure that your disk is not full and "
errMsg += "that you have sufficient write permissions to "
@@ -669,14 +653,16 @@ def _createTargetDirs():
conf.outputPath = tempDir
conf.outputPath = getUnicode(conf.outputPath)
try:
with codecs.open(os.path.join(conf.outputPath, "target.txt"), "w+", UNICODE_ENCODING) as f:
with openFile(os.path.join(conf.outputPath, "target.txt"), "w+") as f:
f.write(kb.originalUrls.get(conf.url) or conf.url or conf.hostname)
f.write(" (%s)" % (HTTPMETHOD.POST if conf.data else HTTPMETHOD.GET))
f.write(" # %s" % getUnicode(subprocess.list2cmdline(sys.argv), encoding=sys.stdin.encoding))
if conf.data:
f.write("\n\n%s" % getUnicode(conf.data))
except IOError, ex:
except IOError as ex:
if "denied" in getUnicode(ex):
errMsg = "you don't have enough permissions "
else:
@@ -689,6 +675,13 @@ def _createTargetDirs():
_createFilesDir()
_configureDumper()
def _setAuxOptions():
"""
Setup auxiliary (host-dependent) options
"""
kb.aliasName = randomStr(seed=hash(conf.hostname or ""))
def _restoreMergedOptions():
"""
Restore merged options (command line, configuration file and default values)
@@ -735,6 +728,9 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
kb.postSpaceToPlus = '+' in original
match = re.search(INJECT_HERE_REGEX, conf.data or "") or re.search(INJECT_HERE_REGEX, conf.url or "")
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv():
_createTargetDirs()
_setRequestParams()
@@ -742,3 +738,4 @@ def setupTargetEnv():
_resumeHashDBValues()
_setResultsFile()
_setAuthCred()
_setAuxOptions()
+12 -8
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -17,6 +17,7 @@ import traceback
from extra.beep.beep import beep
from lib.controller.controller import start
from lib.core.common import checkIntegrity
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import getUnicode
@@ -51,6 +52,9 @@ def smokeTest():
retVal = True
count, length = 0, 0
if not checkIntegrity():
retVal = False
for root, _, files in os.walk(paths.SQLMAP_ROOT_PATH):
if any(_ in root for _ in ("thirdparty", "extra")):
continue
@@ -71,10 +75,10 @@ def smokeTest():
try:
__import__(path)
module = sys.modules[path]
except Exception, msg:
except Exception as ex:
retVal = False
dataToStdout("\r")
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), msg)
errMsg = "smoke test failed at importing module '%s' (%s):\n%s" % (path, os.path.join(root, filename), ex)
logger.error(errMsg)
else:
# Run doc tests
@@ -271,10 +275,10 @@ def runCase(parse):
result = start()
except KeyboardInterrupt:
pass
except SqlmapBaseException, e:
handled_exception = e
except Exception, e:
unhandled_exception = e
except SqlmapBaseException as ex:
handled_exception = ex
except Exception as ex:
unhandled_exception = ex
finally:
sys.stdout.seek(0)
console = sys.stdout.read()
+21 -17
View File
@@ -1,21 +1,25 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import difflib
import random
import threading
import time
import traceback
from lib.core.compat import WichmannHill
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
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 SqlmapThreadException
from lib.core.exception import SqlmapUserQuitException
@@ -54,7 +58,7 @@ class _ThreadData(threading.local):
self.lastRequestMsg = None
self.lastRequestUID = 0
self.lastRedirectURL = None
self.random = random.WichmannHill()
self.random = WichmannHill()
self.resumed = False
self.retriesCount = 0
self.seqMatcher = difflib.SequenceMatcher(None)
@@ -91,11 +95,12 @@ def exceptionHandledFunction(threadFunction, silent=False):
kb.threadContinue = False
kb.threadException = True
raise
except Exception, ex:
if not silent:
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
except Exception as ex:
if not silent and kb.get("threadContinue"):
errMsg = ex.message if isinstance(ex, SqlmapBaseException) else "%s: %s" % (type(ex).__name__, ex.message)
logger.error("thread %s: '%s'" % (threading.currentThread().getName(), errMsg))
if conf.verbose > 1:
if conf.get("verbose") > 1:
traceback.print_exc()
def setDaemon(thread):
@@ -108,7 +113,6 @@ def setDaemon(thread):
def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardException=True, threadChoice=False, startThreadMsg=True):
threads = []
kb.multiThreadMode = True
kb.threadContinue = True
kb.threadException = False
@@ -150,7 +154,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
try:
thread.start()
except Exception, ex:
except Exception as ex:
errMsg = "error occurred while starting new thread ('%s')" % ex.message
logger.critical(errMsg)
break
@@ -166,8 +170,9 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
alive = True
time.sleep(0.1)
except (KeyboardInterrupt, SqlmapUserQuitException), ex:
print
except (KeyboardInterrupt, SqlmapUserQuitException) as ex:
print()
kb.prependFlag = False
kb.threadContinue = False
kb.threadException = True
@@ -183,25 +188,24 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
if forwardException:
raise
except (SqlmapConnectionException, SqlmapValueException), ex:
print
except (SqlmapConnectionException, SqlmapValueException) as ex:
print()
kb.threadException = True
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
if conf.get("verbose") > 1:
traceback.print_exc()
except:
from lib.core.common import unhandledExceptionMessage
print
print()
kb.threadException = True
errMsg = unhandledExceptionMessage()
logger.error("thread %s: %s" % (threading.currentThread().getName(), errMsg))
traceback.print_exc()
finally:
kb.multiThreadMode = False
kb.bruteMode = False
kb.threadContinue = True
kb.threadException = False
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+18 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -17,6 +17,7 @@ import zipfile
from lib.core.common import dataToStdout
from lib.core.common import getSafeExString
from lib.core.common import getLatestRevision
from lib.core.common import pollProcess
from lib.core.common import readInput
from lib.core.data import conf
@@ -25,6 +26,7 @@ from lib.core.data import paths
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 ZIPBALL_PAGE
from lib.core.settings import UNICODE_ENCODING
@@ -39,16 +41,21 @@ def update():
warnMsg += "from GitHub (e.g. 'git clone --depth 1 %s sqlmap')" % GIT_REPOSITORY
logger.warn(warnMsg)
if VERSION == getLatestRevision():
logger.info("already at the latest revision '%s'" % getRevisionNumber())
return
message = "do you want to try to fetch the latest 'zipball' from repository and extract it (experimental) ? [y/N]"
if readInput(message, default='N', boolean=True):
directory = os.path.abspath(paths.SQLMAP_ROOT_PATH)
try:
open(os.path.join(directory, "sqlmap.py"), "w+b")
except Exception, ex:
except Exception as ex:
errMsg = "unable to update content of directory '%s' ('%s')" % (directory, getSafeExString(ex))
logger.error(errMsg)
else:
attrs = os.stat(os.path.join(directory, "sqlmap.py")).st_mode
for wildcard in ('*', ".*"):
for _ in glob.glob(os.path.join(directory, wildcard)):
try:
@@ -78,11 +85,16 @@ def update():
version = re.search(r"(?m)^VERSION\s*=\s*['\"]([^'\"]+)", f.read()).group(1)
logger.info("updated to the latest version '%s#dev'" % version)
success = True
except Exception, ex:
except Exception as ex:
logger.error("update could not be completed ('%s')" % getSafeExString(ex))
else:
if not success:
logger.error("update could not be completed")
else:
try:
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"
@@ -91,14 +103,14 @@ def update():
debugMsg = "sqlmap will try to update itself using 'git' command"
logger.debug(debugMsg)
dataToStdout("\r[%s] [INFO] update in progress " % time.strftime("%X"))
dataToStdout("\r[%s] [INFO] update in progress" % time.strftime("%X"))
try:
process = subprocess.Popen("git checkout . && git pull %s HEAD" % GIT_REPOSITORY, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=paths.SQLMAP_ROOT_PATH.encode(sys.getfilesystemencoding() or UNICODE_ENCODING))
pollProcess(process, True)
stdout, stderr = process.communicate()
success = not process.returncode
except (IOError, OSError), ex:
except (IOError, OSError) as ex:
success = False
stderr = getSafeExString(ex)
+6 -6
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -43,7 +43,7 @@ class Wordlist(object):
if os.path.splitext(self.current)[1].lower() == ".zip":
try:
_ = zipfile.ZipFile(self.current, 'r')
except zipfile.error, ex:
except zipfile.error as ex:
errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it"
@@ -68,15 +68,15 @@ class Wordlist(object):
while True:
self.counter += 1
try:
retVal = self.iter.next().rstrip()
except zipfile.error, ex:
retVal = next(self.iter).rstrip()
except zipfile.error as ex:
errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it"
raise SqlmapInstallationException(errMsg)
except StopIteration:
self.adjust()
retVal = self.iter.next().rstrip()
retVal = next(self.iter).rstrip()
if not self.proc_count or self.counter % self.proc_count == self.proc_id:
break
return retVal
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+62 -32
View File
@@ -1,10 +1,12 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
import os
import re
import shlex
@@ -20,6 +22,7 @@ from lib.core.common import checkSystemEncoding
from lib.core.common import dataToStdout
from lib.core.common import expandMnemonics
from lib.core.common import getUnicode
from lib.core.compat import xrange
from lib.core.data import cmdLineOptions
from lib.core.data import conf
from lib.core.data import logger
@@ -29,6 +32,7 @@ from lib.core.exception import SqlmapShellQuitException
from lib.core.exception import SqlmapSyntaxException
from lib.core.settings import BASIC_HELP_ITEMS
from lib.core.settings import DUMMY_URL
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import IS_WIN
from lib.core.settings import MAX_HELP_OPTION_LENGTH
from lib.core.settings import VERSION_STRING
@@ -99,16 +103,16 @@ def cmdLineParser(argv=None):
help="Force usage of given HTTP method (e.g. PUT)")
request.add_option("--data", dest="data",
help="Data string to be sent through POST")
help="Data string to be sent through POST (e.g. \"id=1\")")
request.add_option("--param-del", dest="paramDel",
help="Character used for splitting parameter values")
help="Character used for splitting parameter values (e.g. &)")
request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header value")
help="HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\")")
request.add_option("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values")
help="Character used for splitting cookie values (e.g. ;)")
request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format")
@@ -144,7 +148,7 @@ def cmdLineParser(argv=None):
help="HTTP authentication PEM cert/private key file")
request.add_option("--ignore-code", dest="ignoreCode", type="int",
help="Ignore HTTP error code (e.g. 401)")
help="Ignore (problematic) HTTP error code (e.g. 401)")
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
help="Ignore system default proxy settings")
@@ -207,17 +211,20 @@ def cmdLineParser(argv=None):
help="Parameter used to hold anti-CSRF token")
request.add_option("--csrf-url", dest="csrfUrl",
help="URL address to visit to extract anti-CSRF token")
help="URL address to visit for extraction of anti-CSRF token")
request.add_option("--force-ssl", dest="forceSSL", action="store_true",
help="Force usage of SSL/HTTPS")
request.add_option("--chunked", dest="chunked", action="store_true",
help="Use HTTP chunked transfer encoded (POST) requests")
request.add_option("--hpp", dest="hpp", action="store_true",
help="Use HTTP parameter pollution method")
request.add_option("--eval", dest="evalCode",
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
# Optimization options
optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap")
@@ -253,13 +260,13 @@ def cmdLineParser(argv=None):
help="Regexp to exclude parameters from testing (e.g. \"ses\")")
injection.add_option("--dbms", dest="dbms",
help="Force back-end DBMS to this value")
help="Force back-end DBMS to provided value")
injection.add_option("--dbms-cred", dest="dbmsCred",
help="DBMS authentication credentials (user:password)")
injection.add_option("--os", dest="os",
help="Force back-end DBMS operating system to this value")
help="Force back-end DBMS operating system to provided value")
injection.add_option("--invalid-bignum", dest="invalidBignum", action="store_true",
help="Use big numbers for invalidating values")
@@ -333,9 +340,12 @@ def cmdLineParser(argv=None):
techniques.add_option("--dns-domain", dest="dnsDomain",
help="Domain name used for DNS exfiltration attack")
techniques.add_option("--second-order", dest="secondOrder",
techniques.add_option("--second-url", dest="secondUrl",
help="Resulting page URL searched for second-order response")
techniques.add_option("--second-req", dest="secondReq",
help="Load second-order HTTP request from file")
# Fingerprint options
fingerprint = OptionGroup(parser, "Fingerprint")
@@ -400,7 +410,7 @@ def cmdLineParser(argv=None):
help="Search column(s), table(s) and/or database name(s)")
enumeration.add_option("--comments", dest="getComments", action="store_true",
help="Retrieve DBMS comments")
help="Check for DBMS comments during enumeration")
enumeration.add_option("-D", dest="db",
help="DBMS database to enumerate")
@@ -468,13 +478,13 @@ def cmdLineParser(argv=None):
# File system options
filesystem = OptionGroup(parser, "File system access", "These options can be used to access the back-end database management system underlying file system")
filesystem.add_option("--file-read", dest="rFile",
filesystem.add_option("--file-read", dest="fileRead",
help="Read a file from the back-end DBMS file system")
filesystem.add_option("--file-write", dest="wFile",
filesystem.add_option("--file-write", dest="fileWrite",
help="Write a local file on the back-end DBMS file system")
filesystem.add_option("--file-dest", dest="dFile",
filesystem.add_option("--file-dest", dest="fileDest",
help="Back-end DBMS absolute filepath to write to")
# Takeover options
@@ -581,7 +591,7 @@ def cmdLineParser(argv=None):
help="Log all HTTP traffic into a HAR file")
general.add_option("--hex", dest="hexConvert", action="store_true",
help="Use DBMS hex function(s) for data retrieval")
help="Use hex conversion during data retrieval")
general.add_option("--output-dir", dest="outputDir", action="store",
help="Custom output directory path")
@@ -589,6 +599,12 @@ def cmdLineParser(argv=None):
general.add_option("--parse-errors", dest="parseErrors", action="store_true",
help="Parse and display DBMS error messages from responses")
general.add_option("--preprocess", dest="preprocess",
help="Use given script(s) for preprocessing of response data")
general.add_option("--repair", dest="repair", action="store_true",
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
general.add_option("--save", dest="saveConfig",
help="Save options to a configuration INI file")
@@ -614,7 +630,7 @@ def cmdLineParser(argv=None):
help="Run host OS command(s) when SQL injection is found")
miscellaneous.add_option("--answers", dest="answers",
help="Set question answers (e.g. \"quit=N,follow=N\")")
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
miscellaneous.add_option("--beep", dest="beep", action="store_true",
help="Beep on question and/or when SQL injection is found")
@@ -623,7 +639,7 @@ def cmdLineParser(argv=None):
help="Clean up the DBMS from sqlmap specific UDF and tables")
miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true",
help="Check for missing (non-core) sqlmap dependencies")
help="Check for missing (optional) sqlmap dependencies")
miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true",
help="Disable console output coloring")
@@ -632,7 +648,10 @@ def cmdLineParser(argv=None):
help="Use Google dork results from specified page number")
miscellaneous.add_option("--identify-waf", dest="identifyWaf", action="store_true",
help="Make a thorough testing for a WAF/IPS/IDS protection")
help="Make a thorough testing for a WAF/IPS protection")
miscellaneous.add_option("--list-tampers", dest="listTampers", action="store_true",
help="Display list of available tamper scripts")
miscellaneous.add_option("--mobile", dest="mobile", action="store_true",
help="Imitate smartphone through HTTP User-Agent header")
@@ -640,11 +659,11 @@ def cmdLineParser(argv=None):
miscellaneous.add_option("--offline", dest="offline", action="store_true",
help="Work in offline mode (only use session data)")
miscellaneous.add_option("--purge-output", dest="purgeOutput", action="store_true",
help="Safely remove all content from output directory")
miscellaneous.add_option("--purge", dest="purge", action="store_true",
help="Safely remove all content from sqlmap data directory")
miscellaneous.add_option("--skip-waf", dest="skipWaf", action="store_true",
help="Skip heuristic detection of WAF/IPS/IDS protection")
help="Skip heuristic detection of WAF/IPS protection")
miscellaneous.add_option("--smart", dest="smart", action="store_true",
help="Conduct thorough tests only if positive heuristic(s)")
@@ -662,6 +681,10 @@ def cmdLineParser(argv=None):
help="Simple wizard interface for beginner users")
# Hidden and/or experimental options
parser.add_option("--crack", dest="hashFile",
help=SUPPRESS_HELP)
# help="Load and crack hashes from a file (standalone)")
parser.add_option("--dummy", dest="dummy", action="store_true",
help=SUPPRESS_HELP)
@@ -747,6 +770,7 @@ def cmdLineParser(argv=None):
prompt = False
advancedHelp = True
extraHeaders = []
tamperIndex = None
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
for arg in argv:
@@ -781,7 +805,7 @@ def cmdLineParser(argv=None):
command = raw_input("sqlmap-shell> ").strip()
command = getUnicode(command, encoding=sys.stdin.encoding)
except (KeyboardInterrupt, EOFError):
print
print()
raise SqlmapShellQuitException
if not command:
@@ -803,7 +827,7 @@ def cmdLineParser(argv=None):
try:
for arg in shlex.split(command):
argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
except ValueError, ex:
except ValueError as ex:
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % ex.message)
for i in xrange(len(argv)):
@@ -818,6 +842,12 @@ def cmdLineParser(argv=None):
elif re.search(r"\A-\w=.+", argv[i]):
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
raise SystemExit
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)
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 ""))
argv[i] = ""
elif argv[i] == "-H":
if i + 1 < len(argv):
extraHeaders.append(argv[i + 1])
@@ -825,7 +855,7 @@ def cmdLineParser(argv=None):
argv[i] = argv[i][:-1]
conf.skipThreadCheck = True
elif argv[i] == "--version":
print VERSION_STRING.split('/')[-1]
print(VERSION_STRING.split('/')[-1])
raise SystemExit
elif argv[i] in ("-h", "--help"):
advancedHelp = False
@@ -849,7 +879,7 @@ def cmdLineParser(argv=None):
try:
(args, _) = parser.parse_args(argv)
except UnicodeEncodeError, ex:
except UnicodeEncodeError as ex:
dataToStdout("\n[!] %s\n" % ex.object.encode("unicode-escape"))
raise SystemExit
except SystemExit:
@@ -871,15 +901,15 @@ 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.liveTest, args.wizard, args.dependencies, args.purgeOutput, args.sitemapUrl)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --wizard, --update, --purge-output or --dependencies), "
errMsg += "use -h for basic or -hh for advanced help\n"
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.liveTest, args.wizard, args.dependencies, args.purge, args.sitemapUrl, args.listTampers, args.hashFile)):
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, -x, --list-tampers, --wizard, --update, --purge or --dependencies). "
errMsg += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg)
return args
except (OptionError, TypeError), e:
parser.error(e)
except (OptionError, TypeError) as ex:
parser.error(ex)
except SystemExit:
# Protection against Windows dummy double clicking
+4 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -39,7 +39,7 @@ def configFileProxy(section, option, datatype):
value = config.getfloat(section, option) if config.get(section, option) else 0.0
else:
value = config.get(section, option)
except ValueError, ex:
except ValueError as ex:
errMsg = "error occurred while processing the option "
errMsg += "'%s' in provided configuration file ('%s')" % (option, getUnicode(ex))
raise SqlmapSyntaxException(errMsg)
@@ -71,7 +71,7 @@ def configFileParser(configFile):
try:
config = UnicodeRawConfigParser()
config.readfp(configFP)
except Exception, ex:
except Exception as ex:
errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex)
raise SqlmapSyntaxException(errMsg)
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -35,7 +35,7 @@ class FingerprintHandler(ContentHandler):
if key == "dbmsVersion":
self._info[key] = value
else:
if key not in self._info.keys():
if key not in self._info:
self._info[key] = set()
for _ in value.split("|"):
+2 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -13,7 +13,6 @@ from lib.core.data import kb
from lib.core.data import paths
from lib.parse.handler import FingerprintHandler
def headersParser(headers):
"""
This function calls a class that parses the input HTTP headers to
+5 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -9,6 +9,7 @@ import re
from xml.sax.handler import ContentHandler
from lib.core.common import urldecode
from lib.core.common import parseXmlFile
from lib.core.data import kb
from lib.core.data import paths
@@ -26,6 +27,7 @@ class HTMLHandler(ContentHandler):
self._dbms = None
self._page = (page or "")
self._lower_page = self._page.lower()
self._urldecoded_page = urldecode(self._page)
self.dbms = None
@@ -47,7 +49,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 and re.search(regexp, self._page, re.I):
if kb.cache.regex[regexp] in self._lower_page and re.search(regexp, self._urldecoded_page, re.I):
self.dbms = self._dbms
self._markAsErrorPage()
+13 -8
View File
@@ -1,15 +1,17 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import os
import re
from xml.etree import ElementTree as et
from lib.core.common import getSafeExString
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import paths
from lib.core.datatype import AttribDict
@@ -17,11 +19,14 @@ from lib.core.exception import SqlmapInstallationException
from lib.core.settings import PAYLOAD_XML_FILES
def cleanupVals(text, tag):
if tag == "clause" and '-' in text:
text = re.sub(r"(\d+)-(\d+)", lambda match: ','.join(str(_) for _ in xrange(int(match.group(1)), int(match.group(2)) + 1)), text)
if tag in ("clause", "where"):
text = text.split(',')
if isinstance(text, basestring):
text = int(text) if text.isdigit() else text
if hasattr(text, "isdigit") and text.isdigit():
text = int(text)
elif isinstance(text, list):
count = 0
@@ -36,7 +41,7 @@ def cleanupVals(text, tag):
return text
def parseXmlNode(node):
for element in node.getiterator('boundary'):
for element in node.getiterator("boundary"):
boundary = AttribDict()
for child in element.getchildren():
@@ -48,7 +53,7 @@ def parseXmlNode(node):
conf.boundaries.append(boundary)
for element in node.getiterator('test'):
for element in node.getiterator("test"):
test = AttribDict()
for child in element.getchildren():
@@ -74,7 +79,7 @@ def parseXmlNode(node):
def loadBoundaries():
try:
doc = et.parse(paths.BOUNDARIES_XML)
except Exception, ex:
except Exception as ex:
errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it"
@@ -89,7 +94,7 @@ def loadPayloads():
try:
doc = et.parse(payloadFilePath)
except Exception, ex:
except Exception as ex:
errMsg = "something appears to be wrong with "
errMsg += "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex))
errMsg += "sure that you haven't made any changes to it"
+6 -6
View File
@@ -1,19 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import httplib
import re
from lib.core.common import readInput
from lib.core.data import kb
from lib.core.data import logger
from lib.core.datatype import OrderedSet
from lib.core.exception import SqlmapSyntaxException
from lib.request.connect import Connect as Request
from thirdparty.oset.pyoset import oset
from thirdparty.six.moves import http_client as _http_client
abortedFlag = None
@@ -26,11 +26,11 @@ def parseSitemap(url, retVal=None):
try:
if retVal is None:
abortedFlag = False
retVal = oset()
retVal = OrderedSet()
try:
content = Request.getPage(url=url, raise404=True)[0] if not abortedFlag else ""
except httplib.InvalidURL:
except _http_client.InvalidURL:
errMsg = "invalid URL given for sitemap ('%s')" % url
raise SqlmapSyntaxException(errMsg)
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
+42 -48
View File
@@ -1,22 +1,24 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import gzip
import io
import logging
import re
import StringIO
import struct
import zlib
from lib.core.common import Backend
from lib.core.common import extractErrorMessage
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import getPublicTypeMembers
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import isListLike
from lib.core.common import randomStr
@@ -35,7 +37,6 @@ from lib.core.enums import PLACE
from lib.core.exception import SqlmapCompressionException
from lib.core.settings import BLOCKED_IP_REGEX
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import EVENTVALIDATION_REGEX
from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE
from lib.core.settings import META_CHARSET_REGEX
@@ -47,7 +48,7 @@ from lib.parse.headers import headersParser
from lib.parse.html import htmlParser
from lib.utils.htmlentities import htmlEntities
from thirdparty.chardet import detect
from thirdparty.odict.odict import OrderedDict
from thirdparty.odict import OrderedDict
def forgeHeaders(items=None, base=None):
"""
@@ -57,7 +58,7 @@ def forgeHeaders(items=None, base=None):
items = items or {}
for _ in items.keys():
for _ in list(items.keys()):
if items[_] is None:
del items[_]
@@ -100,7 +101,7 @@ def forgeHeaders(items=None, base=None):
if ("%s=" % getUnicode(cookie.name)) in getUnicode(headers[HTTP_HEADER.COOKIE]):
if conf.loadCookies:
conf.httpHeaders = filter(None, ((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders))
conf.httpHeaders = filterNone((item if item[0] != HTTP_HEADER.COOKIE else None) for item in conf.httpHeaders)
elif kb.mergeCookies is None:
message = "you provided a HTTP %s header value. " % HTTP_HEADER.COOKIE
message += "The target URL provided its own cookies within "
@@ -220,10 +221,6 @@ def checkCharEncoding(encoding, warn=True):
try:
codecs.lookup(encoding.encode(UNICODE_ENCODING) if isinstance(encoding, unicode) else encoding)
except (LookupError, ValueError):
if warn and ' ' not in encoding:
warnMsg = "unknown web page charset '%s'. " % encoding
warnMsg += "Please report by e-mail to '%s'" % DEV_EMAIL_ADDRESS
singleTimeLogMessage(warnMsg, logging.WARN, encoding)
encoding = None
if encoding:
@@ -261,12 +258,12 @@ def decodePage(page, contentEncoding, contentType):
if not page or (conf.nullConnection and len(page) < 2):
return getUnicode(page)
if isinstance(contentEncoding, basestring) and contentEncoding:
if hasattr(contentEncoding, "lower"):
contentEncoding = contentEncoding.lower()
else:
contentEncoding = ""
if isinstance(contentType, basestring) and contentType:
if hasattr(contentType, "lower"):
contentType = contentType.lower()
else:
contentType = ""
@@ -277,18 +274,18 @@ def decodePage(page, contentEncoding, contentType):
try:
if contentEncoding == "deflate":
data = StringIO.StringIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
data = io.BytesIO(zlib.decompress(page, -15)) # Reference: http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
else:
data = gzip.GzipFile("", "rb", 9, StringIO.StringIO(page))
data = gzip.GzipFile("", "rb", 9, io.BytesIO(page))
size = struct.unpack("<l", page[-4:])[0] # Reference: http://pydoc.org/get.cgi/usr/local/lib/python2.5/gzip.py
if size > MAX_CONNECTION_TOTAL_SIZE:
raise Exception("size too large")
page = data.read()
except Exception, msg:
except Exception as ex:
if "<html" not in page: # in some cases, invalid "Content-Encoding" appears for plain HTML (should be ignored)
errMsg = "detected invalid data for declared content "
errMsg += "encoding '%s' ('%s')" % (contentEncoding, msg)
errMsg += "encoding '%s' ('%s')" % (contentEncoding, getSafeExString(ex))
singleTimeLogMessage(errMsg, logging.ERROR)
warnMsg = "turning off page compression"
@@ -317,43 +314,40 @@ def decodePage(page, contentEncoding, contentType):
# can't do for all responses because we need to support binary files too
if not isinstance(page, unicode) and "text/" in contentType:
if kb.heuristicMode:
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
page = getUnicode(page, kb.pageEncoding)
else:
# e.g. &#195;&#235;&#224;&#226;&#224;
if "&#" in page:
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. &#x9;&#195;&#235;&#224;&#226;&#224;
if "&#" in page:
page = re.sub(r"&#x([0-9a-f]{1,2});", lambda _: (_.group(1) if len(_.group(1)) == 2 else "0%s" % _.group(1)).decode("hex"), page)
page = re.sub(r"&#(\d{1,3});", lambda _: chr(int(_.group(1))) if int(_.group(1)) < 256 else _.group(0), page)
# e.g. %20%28%29
if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
# e.g. %20%28%29
if "%" in page:
page = re.sub(r"%([0-9a-fA-F]{2})", lambda _: _.group(1).decode("hex"), page)
# e.g. &amp;
page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
# e.g. &amp;
page = re.sub(r"&([^;]+);", lambda _: chr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 256) < 256 else _.group(0), page)
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
kb.pageEncoding = kb.pageEncoding or checkCharEncoding(getHeuristicCharEncoding(page))
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)
page = page[3:]
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)
page = page[3:]
page = getUnicode(page, kb.pageEncoding)
page = getUnicode(page, kb.pageEncoding)
# e.g. &#8217;&#8230;&#8482;
if "&#" in page:
def _(match):
retVal = match.group(0)
try:
retVal = unichr(int(match.group(1)))
except ValueError:
pass
return retVal
page = re.sub(r"&#(\d+);", _, page)
# e.g. &#8217;&#8230;&#8482;
if "&#" in page:
def _(match):
retVal = match.group(0)
try:
retVal = unichr(int(match.group(1)))
except (ValueError, OverflowError):
pass
return retVal
page = re.sub(r"&#(\d+);", _, page)
# e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page)
# e.g. &zeta;
page = re.sub(r"&([^;]+);", lambda _: unichr(htmlEntities[_.group(1)]) if htmlEntities.get(_.group(1), 0) > 255 else _.group(0), page)
return page
@@ -390,7 +384,7 @@ def processResponse(page, responseHeaders, status=None):
continue
conf.paramDict[PLACE.POST][name] = value
conf.parameters[PLACE.POST] = re.sub(r"(?i)(%s=)[^&]+" % re.escape(name), r"\g<1>%s" % re.escape(value), conf.parameters[PLACE.POST])
conf.parameters[PLACE.POST] = re.sub(r"(?i)(%s=)[^&]+" % re.escape(name), r"\g<1>%s" % value.replace('\\', r'\\'), conf.parameters[PLACE.POST])
if not kb.browserVerification and re.search(r"(?i)browser.?verification", page or ""):
kb.browserVerification = True
+7 -7
View File
@@ -1,19 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import urllib2
from thirdparty.six.moves import urllib as _urllib
class SmartHTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
class SmartHTTPBasicAuthHandler(_urllib.request.HTTPBasicAuthHandler):
"""
Reference: http://selenic.com/hg/rev/6c51a5056020
Fix for a: http://bugs.python.org/issue8797
"""
def __init__(self, *args, **kwargs):
urllib2.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
_urllib.request.HTTPBasicAuthHandler.__init__(self, *args, **kwargs)
self.retried_req = set()
self.retried_count = 0
@@ -30,8 +30,8 @@ class SmartHTTPBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
self.retried_count = 0
else:
if self.retried_count > 5:
raise urllib2.HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None)
raise _urllib.error.HTTPError(req.get_full_url(), 401, "basic auth failed", headers, None)
else:
self.retried_count += 1
return urllib2.HTTPBasicAuthHandler.http_error_auth_reqed(self, auth_header, host, req, headers)
return _urllib.request.HTTPBasicAuthHandler.http_error_auth_reqed(self, auth_header, host, req, headers)
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python2
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.data import conf
from thirdparty.six.moves import urllib as _urllib
class ChunkedHandler(_urllib.request.HTTPHandler):
"""
Ensures that HTTPHandler is working properly in case of Chunked Transfer-Encoding
"""
def _http_request(self, request):
host = request.get_host()
if not host:
raise _urllib.error.URLError("no host given")
if request.has_data(): # POST
data = request.get_data()
if not request.has_header("Content-type"):
request.add_unredirected_header(
"Content-type",
"application/x-www-form-urlencoded")
if not request.has_header("Content-length") and not conf.chunked:
request.add_unredirected_header(
"Content-length", "%d" % len(data))
sel_host = host
if request.has_proxy():
sel_host = _urllib.parse.urlsplit(request.get_selector()).netloc
if not request.has_header("Host"):
request.add_unredirected_header("Host", sel_host)
for name, value in self.parent.addheaders:
name = name.capitalize()
if not request.has_header(name):
request.add_unredirected_header(name, value)
return request
http_request = _http_request
+7 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -137,10 +137,14 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
seq1 = seq1.replace(REFLECTED_VALUE_MARKER, "")
seq2 = seq2.replace(REFLECTED_VALUE_MARKER, "")
if kb.heavilyDynamic:
seq1 = seq1.split("\n")
seq2 = seq2.split("\n")
seqMatcher.set_seq1(seq1)
seqMatcher.set_seq2(seq2)
ratio = round(seqMatcher.quick_ratio(), 3)
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
# If the url is stable and we did not set yet the match ratio and the
# current injected value changes the url page content
+215 -147
View File
@@ -1,15 +1,11 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import binascii
import compiler
import httplib
import json
import keyword
import logging
import re
import socket
@@ -17,8 +13,6 @@ import string
import struct
import time
import traceback
import urllib2
import urlparse
try:
import websocket
@@ -32,11 +26,13 @@ from lib.core.agent import agent
from lib.core.common import asciifyUrl
from lib.core.common import calculateDeltaSeconds
from lib.core.common import checkSameHost
from lib.core.common import chunkSplitPostData
from lib.core.common import clearConsoleLine
from lib.core.common import dataToStdout
from lib.core.common import escapeJsonValue
from lib.core.common import evaluateCode
from lib.core.common import extractRegexResult
from lib.core.common import filterNone
from lib.core.common import findMultipartPostBoundary
from lib.core.common import getCurrentThreadData
from lib.core.common import getHeader
@@ -44,6 +40,7 @@ from lib.core.common import getHostHeader
from lib.core.common import getRequestHeader
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import isMultiThreadMode
from lib.core.common import logHTTPTraffic
from lib.core.common import pushValue
from lib.core.common import popValue
@@ -61,14 +58,17 @@ from lib.core.common import unicodeencode
from lib.core.common import unsafeVariableNaming
from lib.core.common import urldecode
from lib.core.common import urlencode
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.datatype import AttribDict
from lib.core.decorators import stackedmethod
from lib.core.dicts import POST_HINT_CONTENT_TYPES
from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE
from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import HINT
from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION
@@ -76,7 +76,7 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import POST_HINT
from lib.core.enums import REDIRECTION
from lib.core.enums import WEB_API
from lib.core.enums import WEB_PLATFORM
from lib.core.exception import SqlmapCompressionException
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapGenericException
@@ -88,7 +88,8 @@ from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import DEFAULT_CONTENT_TYPE
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EVALCODE_KEYWORD_SUFFIX
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import EVALCODE_ENCODED_PREFIX
from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
from lib.core.settings import MAX_CONNECTION_CHUNK_SIZE
@@ -98,6 +99,8 @@ from lib.core.settings import MAX_CONSECUTIVE_CONNECTION_ERRORS
from lib.core.settings import MAX_MURPHY_SLEEP_TIME
from lib.core.settings import META_REFRESH_REGEX
from lib.core.settings import MIN_TIME_RESPONSES
from lib.core.settings import MAX_TIME_RESPONSES
from lib.core.settings import IPS_WAF_CHECK_PAYLOAD
from lib.core.settings import IS_WIN
from lib.core.settings import LARGE_CHUNK_TRIM_MARKER
from lib.core.settings import PAYLOAD_DELIMITER
@@ -117,10 +120,12 @@ from lib.request.basic import processResponse
from lib.request.direct import direct
from lib.request.comparison import comparison
from lib.request.methodrequest import MethodRequest
from thirdparty.odict.odict import OrderedDict
from thirdparty import six
from thirdparty.odict import OrderedDict
from thirdparty.six.moves import http_client as _http_client
from thirdparty.six.moves import urllib as _urllib
from thirdparty.socks.socks import ProxyError
class Connect(object):
"""
This class defines methods used to perform HTTP requests
@@ -170,9 +175,11 @@ class Connect(object):
warnMsg += "(e.g. 'https://help.ubuntu.com/community/Tor')"
else:
warnMsg = "if the problem persists please check that the provided "
warnMsg += "target URL is valid. In case that it is, you can try to rerun "
warnMsg += "with the switch '--random-agent' turned on "
warnMsg += "and/or proxy switches ('--ignore-proxy', '--proxy',...)"
warnMsg += "target URL is reachable. In case that it is, "
warnMsg += "you can try to rerun with "
if not conf.randomAgent:
warnMsg += "switch '--random-agent' and/or "
warnMsg += "proxy switches ('--ignore-proxy', '--proxy',...)"
singleTimeWarnMessage(warnMsg)
elif conf.threads > 1:
@@ -264,14 +271,20 @@ class Connect(object):
crawling = kwargs.get("crawling", False)
checking = kwargs.get("checking", False)
skipRead = kwargs.get("skipRead", False)
finalCode = kwargs.get("finalCode", False)
chunked = kwargs.get("chunked", False) or conf.chunked
if multipart:
post = multipart
if chunked and post:
post = _urllib.parse.unquote(post)
post = chunkSplitPostData(post)
websocket_ = url.lower().startswith("ws")
if not urlparse.urlsplit(url).netloc:
url = urlparse.urljoin(conf.url, url)
if not _urllib.parse.urlsplit(url).netloc:
url = _urllib.parse.urljoin(conf.url, url)
# flag to know if we are dealing with the same target host
target = checkSameHost(url, conf.url)
@@ -292,7 +305,7 @@ class Connect(object):
code = None
status = None
_ = urlparse.urlsplit(url)
_ = _urllib.parse.urlsplit(url)
requestMsg = u"HTTP request [#%d]:\r\n%s " % (threadData.lastRequestUID, method or (HTTPMETHOD.POST if post is not None else HTTPMETHOD.GET))
requestMsg += getUnicode(("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else "")) if not any((refreshing, crawling, checking)) else url)
responseMsg = u"HTTP response "
@@ -320,7 +333,7 @@ class Connect(object):
pass
elif target:
if conf.forceSSL and urlparse.urlparse(url).scheme != "https":
if conf.forceSSL and _urllib.parse.urlparse(url).scheme != "https":
url = re.sub(r"(?i)\Ahttp:", "https:", url)
url = re.sub(r"(?i):80/", ":443/", url)
@@ -345,7 +358,7 @@ class Connect(object):
url = "%s?%s" % (url, get)
requestMsg += "?%s" % get
requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str
requestMsg += " %s" % _http_client.HTTPConnection._http_vsn_str
# Prepare HTTP headers
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie, HTTP_HEADER.USER_AGENT: ua, HTTP_HEADER.REFERER: referer, HTTP_HEADER.HOST: host}, base=None if target else {})
@@ -359,14 +372,21 @@ class Connect(object):
if kb.proxyAuthHeader:
headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not conf.requestFile or not target:
if not getHeader(headers, HTTP_HEADER.HOST):
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.HOST) or not target:
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
elif conf.requestFile and getHeader(headers, HTTP_HEADER.USER_AGENT) == DEFAULT_USER_AGENT:
for header in headers:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
del headers[header]
break
if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE):
headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE)
@@ -382,10 +402,9 @@ class Connect(object):
if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive"
# Reset header values to original in case of provided request file
if target and conf.requestFile:
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie})
if chunked:
headers[HTTP_HEADER.TRANSFER_ENCODING] = "chunked"
if auxHeaders:
headers = forgeHeaders(auxHeaders, headers)
@@ -408,13 +427,15 @@ class Connect(object):
page = ws.recv()
ws.close()
code = ws.status
status = httplib.responses[code]
status = _http_client.responses[code]
class _(dict):
pass
responseHeaders = _(ws.getheaders())
responseHeaders.headers = ["%s: %s\r\n" % (_[0].capitalize(), _[1]) for _ in responseHeaders.items()]
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
requestMsg += "\r\n%s" % requestHeaders
if post is not None:
@@ -431,11 +452,11 @@ class Connect(object):
req = MethodRequest(url, post, headers)
req.set_method(method)
elif url is not None:
req = urllib2.Request(url, post, headers)
req = _urllib.request.Request(url, post, headers)
else:
return None, None, None
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in req.header_items()])
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in req.header_items()])
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
conf.cj._policy._now = conf.cj._now = int(time.time())
@@ -443,7 +464,7 @@ class Connect(object):
requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies))
if post is not None:
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH):
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH) and not chunked:
requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
@@ -454,7 +475,8 @@ class Connect(object):
if post is not None:
requestMsg += "\r\n\r\n%s" % getUnicode(post)
requestMsg += "\r\n"
if not chunked:
requestMsg += "\r\n"
if not multipart:
threadData.lastRequestMsg = requestMsg
@@ -469,7 +491,7 @@ class Connect(object):
for char in (r"\r", r"\n"):
cookie.value = re.sub(r"(%s)([^ \t])" % char, r"\g<1>\t\g<2>", cookie.value)
conn = urllib2.urlopen(req)
conn = _urllib.request.urlopen(req)
if not kb.authHeader and getRequestHeader(req, HTTP_HEADER.AUTHORIZATION) and (conf.authType or "").lower() == AUTH_TYPE.BASIC.lower():
kb.authHeader = getRequestHeader(req, HTTP_HEADER.AUTHORIZATION)
@@ -485,14 +507,15 @@ class Connect(object):
if hasattr(conn, "redurl"):
page = (threadData.lastRedirectMsg[1] if kb.redirectChoice == REDIRECTION.NO else Connect._connReadProxy(conn)) if not skipRead else None
skipLogTraffic = kb.redirectChoice == REDIRECTION.NO
code = conn.redcode
code = conn.redcode if not finalCode else code
else:
page = Connect._connReadProxy(conn) if not skipRead else None
if conn:
code = conn.code
code = (code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes)
responseHeaders = conn.info()
responseHeaders[URI_HTTP_HEADER] = conn.geturl()
kb.serverHeader = responseHeaders.get(HTTP_HEADER.SERVER, kb.serverHeader)
else:
code = None
responseHeaders = {}
@@ -524,7 +547,7 @@ class Connect(object):
if re.search(r"\Ahttps?://", refresh, re.I):
url = refresh
else:
url = urlparse.urljoin(url, refresh)
url = _urllib.parse.urljoin(url, refresh)
threadData.lastRedirectMsg = (threadData.lastRequestUID, page)
kwargs["refreshing"] = True
@@ -543,11 +566,11 @@ class Connect(object):
if hasattr(conn.fp, '_sock'):
conn.fp._sock.close()
conn.close()
except Exception, ex:
except Exception as ex:
warnMsg = "problem occurred during connection closing ('%s')" % getSafeExString(ex)
logger.warn(warnMsg)
except SqlmapConnectionException, ex:
except SqlmapConnectionException as ex:
if conf.proxyList and not kb.threadException:
warnMsg = "unable to connect to the target URL ('%s')" % ex
logger.critical(warnMsg)
@@ -556,7 +579,7 @@ class Connect(object):
else:
raise
except urllib2.HTTPError, ex:
except _urllib.error.HTTPError as ex:
page = None
responseHeaders = None
@@ -578,7 +601,7 @@ class Connect(object):
except:
pass
finally:
page = page if isinstance(page, unicode) else getUnicode(page)
page = getUnicode(page)
code = ex.code
status = getSafeExString(ex)
@@ -587,10 +610,10 @@ class Connect(object):
threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
logHeaders = getUnicode("".join(responseHeaders.headers).strip())
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time())
@@ -605,22 +628,22 @@ class Connect(object):
logger.log(CUSTOM_LOGGING.TRAFFIC_IN, responseMsg)
if ex.code != conf.ignoreCode:
if ex.code == httplib.UNAUTHORIZED:
if ex.code == _http_client.UNAUTHORIZED:
errMsg = "not authorized, try to provide right HTTP "
errMsg += "authentication type and valid credentials (%d)" % code
raise SqlmapConnectionException(errMsg)
elif ex.code == httplib.NOT_FOUND:
elif ex.code == _http_client.NOT_FOUND:
if raise404:
errMsg = "page not found (%d)" % code
raise SqlmapConnectionException(errMsg)
else:
debugMsg = "page not found (%d)" % code
singleTimeLogMessage(debugMsg, logging.DEBUG)
elif ex.code == httplib.GATEWAY_TIMEOUT:
elif ex.code == _http_client.GATEWAY_TIMEOUT:
if ignoreTimeout:
return None if not conf.ignoreTimeouts else "", None, None
else:
warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, httplib.responses[ex.code])
warnMsg = "unable to connect to the target URL (%d - %s)" % (ex.code, _http_client.responses[ex.code])
if threadData.retriesCount < conf.retries and not kb.threadException:
warnMsg += ". sqlmap is going to retry the request"
logger.critical(warnMsg)
@@ -634,7 +657,7 @@ class Connect(object):
debugMsg = "got HTTP error code: %d (%s)" % (code, status)
logger.debug(debugMsg)
except (urllib2.URLError, socket.error, socket.timeout, httplib.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError):
except (_urllib.error.URLError, socket.error, socket.timeout, _http_client.HTTPException, struct.error, binascii.Error, ProxyError, SqlmapCompressionException, WebSocketException, TypeError, ValueError, OverflowError):
tbMsg = traceback.format_exc()
if checking:
@@ -645,15 +668,8 @@ class Connect(object):
elif "forcibly closed" in tbMsg or "Connection is already closed" in tbMsg:
warnMsg = "connection was forcibly closed by the target URL"
elif "timed out" in tbMsg:
if not conf.disablePrecon:
singleTimeWarnMessage("turning off pre-connect mechanism because of connection time out(s)")
conf.disablePrecon = True
if kb.testMode and kb.testType not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
kb.responseTimes.clear()
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is dropping 'suspicious' requests")
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is dropping 'suspicious' requests")
kb.droppingRequests = True
warnMsg = "connection timed out to the target URL"
elif "Connection reset" in tbMsg:
@@ -662,7 +678,7 @@ class Connect(object):
conf.disablePrecon = True
if kb.testMode:
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is resetting 'suspicious' requests")
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is resetting 'suspicious' requests")
kb.droppingRequests = True
warnMsg = "connection reset to the target URL"
elif "URLError" in tbMsg or "error" in tbMsg:
@@ -725,38 +741,50 @@ class Connect(object):
else:
logger.debug(warnMsg)
return Connect._retryProxy(**kwargs)
elif kb.testMode or kb.multiThreadMode:
elif kb.testMode or isMultiThreadMode():
logger.critical(warnMsg)
return None, None, None
else:
raise SqlmapConnectionException(warnMsg)
finally:
if isinstance(page, basestring) and not isinstance(page, unicode):
if isinstance(page, six.binary_type):
if HTTP_HEADER.CONTENT_TYPE in (responseHeaders or {}) and not re.search(TEXT_CONTENT_TYPE_REGEX, responseHeaders[HTTP_HEADER.CONTENT_TYPE]):
page = unicode(page, errors="ignore")
page = six.text_type(page, errors="ignore")
else:
page = getUnicode(page)
for function in kb.preprocessFunctions:
try:
page, responseHeaders, code = function(page, responseHeaders, code)
except Exception as ex:
errMsg = "error occurred while running preprocess "
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
raise SqlmapGenericException(errMsg)
threadData.lastPage = page
threadData.lastCode = code
socket.setdefaulttimeout(conf.timeout)
processResponse(page, responseHeaders, status)
if conn and getattr(conn, "redurl", None):
_ = urlparse.urlsplit(conn.redurl)
_ = _urllib.parse.urlsplit(conn.redurl)
_ = ("%s%s" % (_.path or "/", ("?%s" % _.query) if _.query else ""))
requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", "\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"), requestMsg, 1)
requestMsg = re.sub(r"(\n[A-Z]+ ).+?( HTTP/\d)", r"\g<1>%s\g<2>" % getUnicode(_).replace("\\", "\\\\"), requestMsg, 1)
if kb.resendPostOnRedirect is False:
requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", "\g<1>GET ", requestMsg)
requestMsg = re.sub(r"(\[#\d+\]:\n)POST ", r"\g<1>GET ", requestMsg)
requestMsg = re.sub(r"(?i)Content-length: \d+\n", "", requestMsg)
requestMsg = re.sub(r"(?s)\n\n.+", "\n", requestMsg)
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
else:
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
logHeaders = getUnicode("".join(responseHeaders.headers).strip())
if not skipLogTraffic:
logHTTPTraffic(requestMsg, "%s%s\r\n\r\n%s" % (responseMsg, logHeaders, (page or "")[:MAX_CONNECTION_CHUNK_SIZE]), start, time.time())
@@ -811,7 +839,7 @@ class Connect(object):
if conf.httpHeaders:
headers = OrderedDict(conf.httpHeaders)
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers.keys())
contentType = max(headers[_] if _.upper() == HTTP_HEADER.CONTENT_TYPE.upper() else None for _ in headers)
if (kb.postHint or conf.skipUrlEncode) and postUrlEncode:
postUrlEncode = False
@@ -820,22 +848,38 @@ class Connect(object):
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
if payload:
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions:
hints = {}
try:
payload = function(payload=payload, headers=auxHeaders)
except Exception, ex:
payload = function(payload=payload, headers=auxHeaders, delimiter=delimiter, hints=hints)
except Exception as ex:
errMsg = "error occurred while running tamper "
errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex))
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
raise SqlmapGenericException(errMsg)
if not isinstance(payload, basestring):
errMsg = "tamper function '%s' returns " % function.func_name
if not isinstance(payload, six.string_types):
errMsg = "tamper function '%s' returns " % function.__name__
errMsg += "invalid payload type ('%s')" % type(payload)
raise SqlmapValueException(errMsg)
value = agent.replacePayload(value, payload)
if hints:
if HINT.APPEND in hints:
value = "%s%s%s" % (value, delimiter, hints[HINT.APPEND])
if HINT.PREPEND in hints:
if place == PLACE.URI:
match = re.search(r"\w+\s*=\s*%s" % PAYLOAD_DELIMITER, value) or re.search(r"[^?%s/]=\s*%s" % (re.escape(delimiter), PAYLOAD_DELIMITER), value)
if match:
value = value.replace(match.group(0), "%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0)))
else:
value = "%s%s%s" % (hints[HINT.PREPEND], delimiter, value)
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\'))
if place == PLACE.CUSTOM_POST and kb.postHint:
@@ -852,10 +896,10 @@ class Connect(object):
value = agent.replacePayload(value, payload)
else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper()) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper():
if kb.cookieEncodeChoice is None:
msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True)
@@ -870,7 +914,7 @@ class Connect(object):
postUrlEncode = False
if conf.hpp:
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_API.ASP, WEB_API.ASPX)):
if not any(conf.url.lower().endswith(_.lower()) for _ in (WEB_PLATFORM.ASP, WEB_PLATFORM.ASPX)):
warnMsg = "HTTP parameter pollution should work only against "
warnMsg += "ASP(.NET) targets"
singleTimeWarnMessage(warnMsg)
@@ -942,71 +986,92 @@ class Connect(object):
if conf.csrfToken:
def _adjustParameter(paramString, parameter, newValue):
retVal = paramString
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString)
if urlencode(parameter) in paramString:
parameter = urlencode(parameter)
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString, re.I)
if match:
retVal = re.sub(re.escape(match.group(0)), "%s=%s" % (parameter, newValue), paramString)
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
else:
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
if match:
retVal = re.sub(re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
retVal = re.sub("(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
return retVal
token = AttribDict()
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s[\"']?[^>]*\bvalue=(?P<result>(\"([^\"]+)|'([^']+)|([^ >]+)))" % re.escape(conf.csrfToken), page or "")
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
if match:
token.name, token.value = match.group("name"), match.group("value")
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
if match:
token.value = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token:
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=(?P<result>(\"([^\"]+)|'([^']+)|([^ >]+)))[^>]+\bname=[\"']?%s[\"']?" % re.escape(conf.csrfToken), page or "")
if not token:
match = re.search(r"%s[\"']:[\"']([^\"']+)" % re.escape(conf.csrfToken), page or "")
token = match.group(1) if match else None
if not token:
if conf.csrfUrl != conf.url and code == httplib.OK:
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token = page
token.name = conf.csrfToken
token.value = page
if not token and conf.cj and any(_.name == conf.csrfToken for _ in conf.cj):
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
for _ in conf.cj:
if _.name == conf.csrfToken:
token = _.value
if not any(conf.csrfToken in _ for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if re.search(conf.csrfToken, _.name, re.I):
token.name, token.value = _.name, _.value
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, conf.csrfToken, token)
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else:
get = "%s=%s" % (conf.csrfToken, token)
get = "%s=%s" % (token.name, token.value)
break
if not token:
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken, conf.csrfUrl or conf.url)
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
if not conf.csrfUrl:
errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'"
raise SqlmapTokenException(errMsg)
if token:
token = token.strip("'\"")
token.value = token.value.strip("'\"")
for place in (PLACE.GET, PLACE.POST):
if place in conf.parameters:
if place == PLACE.GET and get:
get = _adjustParameter(get, conf.csrfToken, token)
get = _adjustParameter(get, token.name, token.value)
elif place == PLACE.POST and post:
post = _adjustParameter(post, conf.csrfToken, token)
post = _adjustParameter(post, token.name, token.value)
for i in xrange(len(conf.httpHeaders)):
if conf.httpHeaders[i][0].lower() == conf.csrfToken.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token)
if conf.httpHeaders[i][0].lower() == token.name.lower():
conf.httpHeaders[i] = (conf.httpHeaders[i][0], token.value)
if conf.rParam:
def _randomizeParameter(paramString, randomParameter):
retVal = paramString
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]+)" % re.escape(randomParameter), paramString)
match = re.search(r"(\A|\b)%s=(?P<value>[^&;]*)" % re.escape(randomParameter), paramString)
if match:
origValue = match.group("value")
retVal = re.sub(r"(\A|\b)%s=[^&;]+" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
retVal = re.sub(r"(\A|\b)%s=[^&;]*" % re.escape(randomParameter), "%s=%s" % (randomParameter, randomizeParameterValue(origValue)), paramString)
return retVal
for randomParameter in conf.rParam:
@@ -1025,14 +1090,13 @@ class Connect(object):
delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER
variables = {"uri": uri, "lastPage": threadData.lastPage, "_locals": locals()}
originals = {}
keywords = keyword.kwlist
if not get and PLACE.URI in conf.parameters:
query = urlparse.urlsplit(uri).query or ""
query = _urllib.parse.urlsplit(uri).query or ""
else:
query = None
for item in filter(None, (get, post if not kb.postHint else None, query)):
for item in filterNone((get, post if not kb.postHint else None, query)):
for part in item.split(delimiter):
if '=' in part:
name, value = part.split('=', 1)
@@ -1040,8 +1104,6 @@ class Connect(object):
if safeVariableNaming(name) != name:
conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode)
name = safeVariableNaming(name)
elif name in keywords:
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus))
variables[name] = value
@@ -1053,31 +1115,29 @@ class Connect(object):
if safeVariableNaming(name) != name:
conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode)
name = safeVariableNaming(name)
elif name in keywords:
name = "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX)
value = urldecode(value, convall=True)
variables[name] = value
while True:
try:
compiler.parse(unicodeencode(conf.evalCode.replace(';', '\n')))
except SyntaxError, ex:
compile(unicodeencode(conf.evalCode.replace(';', '\n')), "", "exec")
except SyntaxError as ex:
if ex.text:
original = replacement = ex.text.strip()
if '=' in original:
name, value = original.split('=', 1)
name = name.strip()
if safeVariableNaming(name) != name:
replacement = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), replacement)
elif name in keywords:
replacement = re.sub(r"\b%s\b" % re.escape(name), "%s%s" % (name, EVALCODE_KEYWORD_SUFFIX), replacement)
else:
for _ in re.findall(r"[A-Za-z_]+", original)[::-1]:
if _ in keywords:
replacement = replacement.replace(_, "%s%s" % (_, EVALCODE_KEYWORD_SUFFIX))
if safeVariableNaming(_) != _:
replacement = replacement.replace(_, safeVariableNaming(_))
break
if original == replacement:
conf.evalCode = conf.evalCode.replace(EVALCODE_KEYWORD_SUFFIX, "")
conf.evalCode = conf.evalCode.replace(EVALCODE_ENCODED_PREFIX, "")
break
else:
conf.evalCode = conf.evalCode.replace(getUnicode(ex.text.strip(), UNICODE_ENCODING), replacement)
@@ -1089,12 +1149,7 @@ class Connect(object):
originals.update(variables)
evaluateCode(conf.evalCode, variables)
for variable in variables.keys():
if variable.endswith(EVALCODE_KEYWORD_SUFFIX):
value = variables[variable]
del variables[variable]
variables[variable.replace(EVALCODE_KEYWORD_SUFFIX, "")] = value
for variable in list(variables.keys()):
if unsafeVariableNaming(variable) != variable:
value = variables[variable]
del variables[variable]
@@ -1104,7 +1159,7 @@ class Connect(object):
for name, value in variables.items():
if name != "__builtins__" and originals.get(name, "") != value:
if isinstance(value, (basestring, int)):
if isinstance(value, (int, six.string_types)):
found = False
value = getUnicode(value, UNICODE_ENCODING)
@@ -1112,33 +1167,33 @@ class Connect(object):
if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP):
if re.search(r"<%s\b" % re.escape(name), post):
found = True
post = re.sub(r"(?s)(<%s\b[^>]*>)(.*?)(</%s)" % (re.escape(name), re.escape(name)), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
post = re.sub(r"(?s)(<%s\b[^>]*>)(.*?)(</%s)" % (re.escape(name), re.escape(name)), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
elif re.search(r"\b%s>" % re.escape(name), post):
found = True
post = re.sub(r"(?s)(\b%s>)(.*?)(</[^<]*\b%s>)" % (re.escape(name), re.escape(name)), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
post = re.sub(r"(?s)(\b%s>)(.*?)(</[^<]*\b%s>)" % (re.escape(name), re.escape(name)), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
regex = r"\b(%s)\b([^\w]+)(\w+)" % re.escape(name)
if not found and re.search(regex, (post or "")):
found = True
post = re.sub(regex, "\g<1>\g<2>%s" % value.replace('\\', r'\\'), post)
post = re.sub(regex, r"\g<1>\g<2>%s" % value.replace('\\', r'\\'), post)
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), re.escape(name), re.escape(delimiter))
if not found and re.search(regex, (post or "")):
found = True
post = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
post = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), post)
if re.search(regex, (get or "")):
found = True
get = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), get)
get = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), get)
if re.search(regex, (query or "")):
found = True
uri = re.sub(regex.replace(r"\A", r"\?"), "\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri)
uri = re.sub(regex.replace(r"\A", r"\?"), r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), uri)
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER), re.escape(name), re.escape(conf.cookieDel or DEFAULT_COOKIE_DELIMITER))
if re.search(regex, (cookie or "")):
found = True
cookie = re.sub(regex, "\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
cookie = re.sub(regex, r"\g<1>%s\g<3>" % value.replace('\\', r'\\'), cookie)
if not found:
if post is not None:
@@ -1169,7 +1224,7 @@ class Connect(object):
singleTimeWarnMessage(warnMsg)
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "")
warnMsg += "larger statistical model, please wait"
warnMsg += "%s statistical model, please wait" % ("larger" if len(kb.responseTimes) == 1 else "reset of")
dataToStdout(warnMsg)
while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
@@ -1224,14 +1279,17 @@ class Connect(object):
_, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, raise404=raise404, skipRead=(kb.nullConnection == NULLCONNECTION.SKIP_READ))
if headers:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH])
elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE):
pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])
try:
if kb.nullConnection in (NULLCONNECTION.HEAD, NULLCONNECTION.SKIP_READ) and headers.get(HTTP_HEADER.CONTENT_LENGTH):
pageLength = int(headers[HTTP_HEADER.CONTENT_LENGTH].split(',')[0])
elif kb.nullConnection == NULLCONNECTION.RANGE and headers.get(HTTP_HEADER.CONTENT_RANGE):
pageLength = int(headers[HTTP_HEADER.CONTENT_RANGE][headers[HTTP_HEADER.CONTENT_RANGE].find('/') + 1:])
except ValueError:
pass
finally:
kb.pageCompress = popValue()
if not pageLength:
if pageLength is None:
try:
page, headers, code = Connect.getPage(url=uri, get=get, post=post, method=method, cookie=cookie, ua=ua, referer=referer, host=host, silent=silent, auxHeaders=auxHeaders, response=response, raise404=raise404, ignoreTimeout=timeBasedCompare)
except MemoryError:
@@ -1239,17 +1297,25 @@ class Connect(object):
warnMsg = "site returned insanely large response"
if kb.testMode:
warnMsg += " in testing phase. This is a common "
warnMsg += "behavior in custom WAF/IPS/IDS solutions"
warnMsg += "behavior in custom WAF/IPS solutions"
singleTimeWarnMessage(warnMsg)
if conf.secondOrder:
page, headers, code = Connect.getPage(url=conf.secondOrder, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
if conf.secondUrl:
page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
elif kb.secondReq and IPS_WAF_CHECK_PAYLOAD not in _urllib.parse.unquote(value or ""):
def _(value):
if kb.customInjectionMark in (value or ""):
if payload is None:
value = value.replace(kb.customInjectionMark, "")
else:
value = re.sub(r"\w*%s" % re.escape(kb.customInjectionMark), payload, value)
return value
page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]), method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
threadData.lastQueryDuration = calculateDeltaSeconds(start)
threadData.lastPage = page
threadData.lastCode = code
kb.originalCode = kb.originalCode or code
kb.originalCode = code if kb.originalCode is None else kb.originalCode
kb.originalPage = page if kb.originalPage is None else kb.originalPage
if kb.testMode:
kb.testQueryCount += 1
@@ -1259,6 +1325,8 @@ class Connect(object):
elif noteResponseTime:
kb.responseTimes.setdefault(kb.responseTimeMode, [])
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
if len(kb.responseTimes[kb.responseTimeMode]) > MAX_TIME_RESPONSES:
kb.responseTimes[kb.responseTimeMode] = kb.responseTimes[kb.responseTimeMode][-MAX_TIME_RESPONSES // 2:]
if not response and removeReflection:
page = removeReflectiveValues(page, payload)
+4 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#!/usr/bin/env python2
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
@@ -25,6 +25,7 @@ from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import DBMS
from lib.core.enums import EXPECTED
from lib.core.enums import TIMEOUT_STATE
from lib.core.settings import TAKEOVER_TABLE_PREFIX
from lib.core.settings import UNICODE_ENCODING
from lib.utils.timeout import timeout
@@ -53,7 +54,7 @@ def direct(query, content=True):
if not select and "EXEC " not in query.upper():
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
elif not (output and "sqlmapoutput" not in query and "sqlmapfile" not in query):
elif not (output and ("%soutput" % TAKEOVER_TABLE_PREFIX) not in query and ("%sfile" % TAKEOVER_TABLE_PREFIX) not in query):
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
if state == TIMEOUT_STATE.NORMAL:
hashDBWrite(query, output, True)

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