mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-08 13:41:29 +00:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b55644631 | ||
|
|
238ca3ccd8 | ||
|
|
526bec322b | ||
|
|
d5527b3380 | ||
|
|
fde978c4ff | ||
|
|
1d17e2a942 | ||
|
|
79aa315344 | ||
|
|
79f4cfb0a7 | ||
|
|
3192da0acd | ||
|
|
d37db2e7e8 | ||
|
|
f1ac7dc39b | ||
|
|
9a87f47777 | ||
|
|
a79ed52463 | ||
|
|
73a62f9f4e | ||
|
|
c1af880fb8 | ||
|
|
9a48a27593 | ||
|
|
6ae0d0f54e | ||
|
|
cf91046766 | ||
|
|
0b9a8c57d7 | ||
|
|
b256269883 | ||
|
|
ebfafe93e1 | ||
|
|
2b3af64649 | ||
|
|
58c6ca3a60 | ||
|
|
59b3b973c7 | ||
|
|
e3669c0926 | ||
|
|
507c719bef | ||
|
|
3cc19816cc | ||
|
|
74ca0eda56 | ||
|
|
514a1291e4 | ||
|
|
9bbf70790c | ||
|
|
163a5f374a | ||
|
|
46cc0c2941 | ||
|
|
2f01cbf71f | ||
|
|
1e9e33d9c3 | ||
|
|
dce99e0b40 | ||
|
|
b3896f3f8c | ||
|
|
853cb3fa06 |
5
.github/workflows/tests.yml
vendored
5
.github/workflows/tests.yml
vendored
@@ -10,7 +10,10 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
python-version: [ '3.11', 'pypy-2.7', 'pypy-3.7' ]
|
python-version: [ 'pypy-2.7', '3.12' ]
|
||||||
|
exclude:
|
||||||
|
- os: macos-latest
|
||||||
|
python-version: 'pypy-2.7'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ c6be099a5dee34f3a7570715428add2e7419f4e73a7ce9913d3fb76eea78d88e data/udf/postg
|
|||||||
a7eb4d1bcbdfd155383dcd35396e2d9dd40c2e89ce9d5a02e63a95a94f0ab4ea data/xml/banner/sharepoint.xml
|
a7eb4d1bcbdfd155383dcd35396e2d9dd40c2e89ce9d5a02e63a95a94f0ab4ea data/xml/banner/sharepoint.xml
|
||||||
e2febc92f9686eacf17a0054f175917b783cc6638ca570435a5203b03245fc18 data/xml/banner/x-aspnet-version.xml
|
e2febc92f9686eacf17a0054f175917b783cc6638ca570435a5203b03245fc18 data/xml/banner/x-aspnet-version.xml
|
||||||
75672f8faa8053af0df566a48700f2178075f67c593d916313fcff3474da6f82 data/xml/banner/x-powered-by.xml
|
75672f8faa8053af0df566a48700f2178075f67c593d916313fcff3474da6f82 data/xml/banner/x-powered-by.xml
|
||||||
3f9d2b3c929cacd96394d190860adc0997c9c7665020073befc69f65e5deb393 data/xml/boundaries.xml
|
1ac399c49ce3cb8c0812bb246e60c8a6718226efe89ccd1f027f49a18dbeb634 data/xml/boundaries.xml
|
||||||
130eef6c02dc5749f164660aa4210f75b0de35aaf2afef94b329bb1e033851f7 data/xml/errors.xml
|
130eef6c02dc5749f164660aa4210f75b0de35aaf2afef94b329bb1e033851f7 data/xml/errors.xml
|
||||||
cfa1f0557fb71be0631796a4848d17be536e38f94571cf6ef911454fbc6b30d1 data/xml/payloads/boolean_blind.xml
|
cfa1f0557fb71be0631796a4848d17be536e38f94571cf6ef911454fbc6b30d1 data/xml/payloads/boolean_blind.xml
|
||||||
c22d076af9e8518f3b44496aee651932edf590ea4be0b328262314fcb4a52da8 data/xml/payloads/error_based.xml
|
f2b711ea18f20239ba9902732631684b61106d4a4271669125a4cf41401b3eaf data/xml/payloads/error_based.xml
|
||||||
b0f434f64105bd61ab0f6867b3f681b97fa02b4fb809ac538db382d031f0e609 data/xml/payloads/inline_query.xml
|
b0f434f64105bd61ab0f6867b3f681b97fa02b4fb809ac538db382d031f0e609 data/xml/payloads/inline_query.xml
|
||||||
0648264166455010921df1ec431e4c973809f37ef12cbfea75f95029222eb689 data/xml/payloads/stacked_queries.xml
|
0648264166455010921df1ec431e4c973809f37ef12cbfea75f95029222eb689 data/xml/payloads/stacked_queries.xml
|
||||||
997556b6170964a64474a2e053abe33cf2cf029fb1acec660d4651cc67a3c7e1 data/xml/payloads/time_blind.xml
|
997556b6170964a64474a2e053abe33cf2cf029fb1acec660d4651cc67a3c7e1 data/xml/payloads/time_blind.xml
|
||||||
@@ -95,7 +95,7 @@ f7b6cc0d0fdd0aa5550957db9b125a48f3fb4219bba282f49febc32a7e149e74 doc/translatio
|
|||||||
3eac203d3979977b4f4257ed735df6e98ecf6c0dfcd2c42e9fea68137d40f07c doc/translations/README-fr-FR.md
|
3eac203d3979977b4f4257ed735df6e98ecf6c0dfcd2c42e9fea68137d40f07c doc/translations/README-fr-FR.md
|
||||||
26524b18e5c4a1334a6d0de42f174b948a8c36e95f2ec1f0bc6582a14d02e692 doc/translations/README-gr-GR.md
|
26524b18e5c4a1334a6d0de42f174b948a8c36e95f2ec1f0bc6582a14d02e692 doc/translations/README-gr-GR.md
|
||||||
d505142526612a563cc71d6f99e0e3eed779221438047e224d5c36e8750961db doc/translations/README-hr-HR.md
|
d505142526612a563cc71d6f99e0e3eed779221438047e224d5c36e8750961db doc/translations/README-hr-HR.md
|
||||||
cb24e114a58e7f03c37f0f0ace25c6294b61308b0d60402fe5f6b2a490c40606 doc/translations/README-id-ID.md
|
a381ff3047aab611cf1d09b7a15a6733773c7c475c7f402ef89e3afe8f0dd151 doc/translations/README-id-ID.md
|
||||||
e88d3312a2b3891c746f6e6e57fbbd647946e2d45a5e37aab7948e371531a412 doc/translations/README-in-HI.md
|
e88d3312a2b3891c746f6e6e57fbbd647946e2d45a5e37aab7948e371531a412 doc/translations/README-in-HI.md
|
||||||
34a6a3a459dbafef1953a189def2ff798e2663db50f7b18699710d31ac0237f8 doc/translations/README-it-IT.md
|
34a6a3a459dbafef1953a189def2ff798e2663db50f7b18699710d31ac0237f8 doc/translations/README-it-IT.md
|
||||||
2120fd640ae5b255619abae539a4bd4a509518daeff0d758bbd61d996871282f doc/translations/README-ja-JP.md
|
2120fd640ae5b255619abae539a4bd4a509518daeff0d758bbd61d996871282f doc/translations/README-ja-JP.md
|
||||||
@@ -126,7 +126,7 @@ a87035e5923f5b56077dfbd18cda5aa5e2542f0707b7b55f7bbeb1960ae3cc9a extra/icmpsh/i
|
|||||||
12014ddddc09c58ef344659c02fd1614157cfb315575378f2c8cb90843222733 extra/icmpsh/icmpsh_m.py
|
12014ddddc09c58ef344659c02fd1614157cfb315575378f2c8cb90843222733 extra/icmpsh/icmpsh_m.py
|
||||||
1589e5edeaf80590d4d0ce1fd12aa176730d5eba3bfd72a9f28d3a1a9353a9db extra/icmpsh/icmpsh-s.c
|
1589e5edeaf80590d4d0ce1fd12aa176730d5eba3bfd72a9f28d3a1a9353a9db extra/icmpsh/icmpsh-s.c
|
||||||
ab6ee3ee9f8600e39faecfdaa11eaa3bed6f15ccef974bb904b96bf95e980c40 extra/icmpsh/__init__.py
|
ab6ee3ee9f8600e39faecfdaa11eaa3bed6f15ccef974bb904b96bf95e980c40 extra/icmpsh/__init__.py
|
||||||
ce1dd60916a926081ac7e7c57bd3c6856b80c029c4e8687528b18ce47dbec5b4 extra/icmpsh/README.txt
|
27af6b7ec0f689e148875cb62c3acb4399d3814ba79908220b29e354a8eed4b8 extra/icmpsh/README.txt
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 extra/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 extra/__init__.py
|
||||||
191e3e397b83294082022de178f977f2c59fa99c96e5053375f6c16114d6777e extra/runcmd/README.txt
|
191e3e397b83294082022de178f977f2c59fa99c96e5053375f6c16114d6777e extra/runcmd/README.txt
|
||||||
25be5af53911f8c4816c0c8996b5b4932543efd6be247f5e18ce936679e7d1cd extra/runcmd/runcmd.exe_
|
25be5af53911f8c4816c0c8996b5b4932543efd6be247f5e18ce936679e7d1cd extra/runcmd/runcmd.exe_
|
||||||
@@ -153,7 +153,7 @@ dc35b51f5c9347eda8130106ee46bb051474fc0c5ed101f84abf3e546f729ceb extra/shutils/
|
|||||||
fa1a42d189188770e82d536821d694626ca854438dadb9e08e143d3ece8c7e27 extra/shutils/pydiatra.sh
|
fa1a42d189188770e82d536821d694626ca854438dadb9e08e143d3ece8c7e27 extra/shutils/pydiatra.sh
|
||||||
5da7d1c86ca93313477d1deb0d6d4490798a2b63a2dd8729094184625b971e11 extra/shutils/pyflakes.sh
|
5da7d1c86ca93313477d1deb0d6d4490798a2b63a2dd8729094184625b971e11 extra/shutils/pyflakes.sh
|
||||||
c941be05376ba0a99d329e6de60e3b06b3fb261175070da6b1fc073d3afd5281 extra/shutils/pylint.sh
|
c941be05376ba0a99d329e6de60e3b06b3fb261175070da6b1fc073d3afd5281 extra/shutils/pylint.sh
|
||||||
bc2ceff560d11d696329bd976b14fbd8cddf428ad9f95eeb0a8f53e1afdc998b extra/shutils/pypi.sh
|
a19725f10ff9c5d484cffd8f1bd9348918cc3c4bfdd4ba6fffb42aaf0f5c973c extra/shutils/pypi.sh
|
||||||
df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/recloak.sh
|
df768bcb9838dc6c46dab9b4a877056cb4742bd6cfaaf438c4a3712c5cc0d264 extra/shutils/recloak.sh
|
||||||
1972990a67caf2d0231eacf60e211acf545d9d0beeb3c145a49ba33d5d491b3f extra/shutils/strip.sh
|
1972990a67caf2d0231eacf60e211acf545d9d0beeb3c145a49ba33d5d491b3f extra/shutils/strip.sh
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 extra/vulnserver/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 extra/vulnserver/__init__.py
|
||||||
@@ -164,8 +164,8 @@ f9c96cd3fe99578bed9d49a8bdf8d76836d320a7c48c56eb0469f48b36775c35 lib/controller
|
|||||||
46d70b69cc7af0849242da5094a644568d7662a256a63e88ae485985b6dccf12 lib/controller/handler.py
|
46d70b69cc7af0849242da5094a644568d7662a256a63e88ae485985b6dccf12 lib/controller/handler.py
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/controller/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/controller/__init__.py
|
||||||
826c33f1105be4c0985e1bbe1d75bdb009c17815ad6552fc8d9bf39090d3c40f lib/core/agent.py
|
826c33f1105be4c0985e1bbe1d75bdb009c17815ad6552fc8d9bf39090d3c40f lib/core/agent.py
|
||||||
b2d69c99632da5c2acd0c0934e70d55862f1380a3f602cbe7456d617fb9c1fc9 lib/core/bigarray.py
|
c2966ee914b98ba55c0e12b8f76e678245d08ff9b30f63c4456721ec3eff3918 lib/core/bigarray.py
|
||||||
ba3f0002aa93f8f21f06dbea343573c590b9e6ec160fc6668c15e68a970cfb12 lib/core/common.py
|
f43931f5dbabd11de96267b6f9431025ee2e09e65a14b907c360ce029bbed39f lib/core/common.py
|
||||||
5c26b0f308266bc3a9679ef837439e38d1dc7a69eac6bd3422280f49aaf114d2 lib/core/compat.py
|
5c26b0f308266bc3a9679ef837439e38d1dc7a69eac6bd3422280f49aaf114d2 lib/core/compat.py
|
||||||
b60c96780cad4a257f91a0611b08cfcc52f242908c5d5ab2bf9034ef07869602 lib/core/convert.py
|
b60c96780cad4a257f91a0611b08cfcc52f242908c5d5ab2bf9034ef07869602 lib/core/convert.py
|
||||||
5e381515873e71c395c77df00bf1dd8c4592afc6210a2f75cbc20daf384e539f lib/core/data.py
|
5e381515873e71c395c77df00bf1dd8c4592afc6210a2f75cbc20daf384e539f lib/core/data.py
|
||||||
@@ -180,18 +180,18 @@ e8f6f1df8814b7b03c3eba22901837555083f66c99ee93b943911de785736bfa lib/core/dicts
|
|||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/core/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/core/__init__.py
|
||||||
fce3fd4b161ec1c6e9d5bf1dca5bc4083e07d616ed2c14b798e96b60ec67c2b2 lib/core/log.py
|
fce3fd4b161ec1c6e9d5bf1dca5bc4083e07d616ed2c14b798e96b60ec67c2b2 lib/core/log.py
|
||||||
4caebf27d203673b8ad32394937397319f606c4e1f1e1a2a221402d39c644b40 lib/core/optiondict.py
|
4caebf27d203673b8ad32394937397319f606c4e1f1e1a2a221402d39c644b40 lib/core/optiondict.py
|
||||||
33e0ec9ed38ae1ac74f1e2e3a1a246dee44c167723c9df69635793bfdbd971df lib/core/option.py
|
b3d2be01406c3bae1cf46e1b8c0f773264b61a037e6a92e5c0ba190a82afc869 lib/core/option.py
|
||||||
fdce95c552a097bf0dd44e5d6be2204c4c458d490e62c4d9d68fca5e2dc37c48 lib/core/patch.py
|
d2d81ee7520b55571923461a2bdfaa68dda74a89846761338408ab0acf08d3a5 lib/core/patch.py
|
||||||
bf77f9fc4296f239687297aee1fd6113b34f855965a6f690b52e26bd348cb353 lib/core/profiling.py
|
bf77f9fc4296f239687297aee1fd6113b34f855965a6f690b52e26bd348cb353 lib/core/profiling.py
|
||||||
4ccce0d53f467166d4084c9ef53a07f54cc352e75f785454a31c8a820511a84e lib/core/readlineng.py
|
4ccce0d53f467166d4084c9ef53a07f54cc352e75f785454a31c8a820511a84e lib/core/readlineng.py
|
||||||
4eff81c639a72b261c8ba1c876a01246e718e6626e8e77ae9cc6298b20a39355 lib/core/replication.py
|
4eff81c639a72b261c8ba1c876a01246e718e6626e8e77ae9cc6298b20a39355 lib/core/replication.py
|
||||||
bbd1dcda835934728efc6d68686e9b0da72b09b3ee38f3c0ab78e8c18b0ba726 lib/core/revision.py
|
bbd1dcda835934728efc6d68686e9b0da72b09b3ee38f3c0ab78e8c18b0ba726 lib/core/revision.py
|
||||||
eed6b0a21b3e69c5583133346b0639dc89937bd588887968ee85f8389d7c3c96 lib/core/session.py
|
eed6b0a21b3e69c5583133346b0639dc89937bd588887968ee85f8389d7c3c96 lib/core/session.py
|
||||||
8c56685dbca6414a9b3c1dcc45249d41ab4677635edd8a5a68cc8ef5504d39da lib/core/settings.py
|
6bcf5bb000afdaa376b24553dfacdd195fe38063ab2b53c1bb17692277328298 lib/core/settings.py
|
||||||
2bec97d8a950f7b884e31dfe9410467f00d24f21b35672b95f8d68ed59685fd4 lib/core/shell.py
|
2bec97d8a950f7b884e31dfe9410467f00d24f21b35672b95f8d68ed59685fd4 lib/core/shell.py
|
||||||
e90a359b37a55c446c60e70ccd533f87276714d0b09e34f69b0740fd729ddbf8 lib/core/subprocessng.py
|
e90a359b37a55c446c60e70ccd533f87276714d0b09e34f69b0740fd729ddbf8 lib/core/subprocessng.py
|
||||||
54f7c70b4c7a9931f7ff3c1c12030180bde38e35a306d5e343ad6052919974cd lib/core/target.py
|
54f7c70b4c7a9931f7ff3c1c12030180bde38e35a306d5e343ad6052919974cd lib/core/target.py
|
||||||
5941a7a641ea58b1d9e59ab3c9f4e9e40566ba08842e1cadb51ea8df9faf763f lib/core/testing.py
|
970b1c3e59481f11dd185bdde52f697f7d8dfc3152d24e3d336ec3fab59a857c lib/core/testing.py
|
||||||
8cb7424aa9d42d028a6780250effe4e719d9bb35558057f8ebe9e32408a6b80f lib/core/threads.py
|
8cb7424aa9d42d028a6780250effe4e719d9bb35558057f8ebe9e32408a6b80f lib/core/threads.py
|
||||||
ff39235aee7e33498c66132d17e6e86e7b8a29754e3fdecd880ca8356b17f791 lib/core/unescaper.py
|
ff39235aee7e33498c66132d17e6e86e7b8a29754e3fdecd880ca8356b17f791 lib/core/unescaper.py
|
||||||
2984e4973868f586aa932f00da684bf31718c0331817c9f8721acd71fd661f89 lib/core/update.py
|
2984e4973868f586aa932f00da684bf31718c0331817c9f8721acd71fd661f89 lib/core/update.py
|
||||||
@@ -199,7 +199,7 @@ ce65f9e8e1c726de3cec6abf31a2ffdbc16c251f772adcc14f67dee32d0f6b57 lib/core/wordl
|
|||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/__init__.py
|
||||||
ba16fdd71fba31990dc92ff5a7388fb0ebac21ca905c314be6c8c2b868f94ab7 lib/parse/banner.py
|
ba16fdd71fba31990dc92ff5a7388fb0ebac21ca905c314be6c8c2b868f94ab7 lib/parse/banner.py
|
||||||
d757343f241b14e23aefb2177b6c2598f1bc06253fd93b0d8a28d4a55c267100 lib/parse/cmdline.py
|
d757343f241b14e23aefb2177b6c2598f1bc06253fd93b0d8a28d4a55c267100 lib/parse/cmdline.py
|
||||||
bcf0b32a730f1cdf097b00acf220eb216bc8eb4cb5d217a4a0d6ebe9f8086129 lib/parse/configfile.py
|
d1fa3b9457f0e934600519309cbd3d84f9e6158a620866e7b352078c7c136f01 lib/parse/configfile.py
|
||||||
9af4c86e41e50bd6055573a7b76e380a6658b355320c72dd6d2d5ddab14dc082 lib/parse/handler.py
|
9af4c86e41e50bd6055573a7b76e380a6658b355320c72dd6d2d5ddab14dc082 lib/parse/handler.py
|
||||||
13b3ab678a2c422ce1dea9558668c05e562c0ec226f36053259a0be7280ebf92 lib/parse/headers.py
|
13b3ab678a2c422ce1dea9558668c05e562c0ec226f36053259a0be7280ebf92 lib/parse/headers.py
|
||||||
b48edf3f30db127b18419f607894d5de46fc949d14c65fdc85ece524207d6dfd lib/parse/html.py
|
b48edf3f30db127b18419f607894d5de46fc949d14c65fdc85ece524207d6dfd lib/parse/html.py
|
||||||
@@ -207,15 +207,15 @@ b48edf3f30db127b18419f607894d5de46fc949d14c65fdc85ece524207d6dfd lib/parse/html
|
|||||||
8743332261f8b0da52c94ca56510f0f2e856431c2bbe2164efdd3de605c2802b lib/parse/payloads.py
|
8743332261f8b0da52c94ca56510f0f2e856431c2bbe2164efdd3de605c2802b lib/parse/payloads.py
|
||||||
23adb7169e99554708062ff87ae795b90c6a284d1b5159eada974bf9f8d7583f lib/parse/sitemap.py
|
23adb7169e99554708062ff87ae795b90c6a284d1b5159eada974bf9f8d7583f lib/parse/sitemap.py
|
||||||
0acfa7da4b0dbc81652b018c3fdbb42512c8d7d5f01bbf9aef18e5ea7d38107a lib/request/basicauthhandler.py
|
0acfa7da4b0dbc81652b018c3fdbb42512c8d7d5f01bbf9aef18e5ea7d38107a lib/request/basicauthhandler.py
|
||||||
c8446d4a50f06a50d7db18adc04c321e12cd2d0fa8b04bd58306511c89823316 lib/request/basic.py
|
2395d6d28d6a1e342fccd56bb741080468a777b9b2a5ddd5634df65fe9785cef lib/request/basic.py
|
||||||
ead55e936dfc8941e512c8e8a4f644689387f331f4eed97854c558be3e227a91 lib/request/chunkedhandler.py
|
ead55e936dfc8941e512c8e8a4f644689387f331f4eed97854c558be3e227a91 lib/request/chunkedhandler.py
|
||||||
06128c4e3e0e1fe34618de9d1fd5ee21292953dce4a3416567e200d2dfda79f2 lib/request/comparison.py
|
06128c4e3e0e1fe34618de9d1fd5ee21292953dce4a3416567e200d2dfda79f2 lib/request/comparison.py
|
||||||
00b23e22a65889829f4ffe65eea5e2bd5cf6ceab4f9b0f32b05047335b0b4a3e lib/request/connect.py
|
45f365239c48f2f6b8adc605b2f33b3522bda6e3248589dae909380434aaa0ad lib/request/connect.py
|
||||||
470e96857a7037a2d74b2c4b1c8c5d8379b76ea8cbdb1d8dd4367a7a852fa93c lib/request/direct.py
|
470e96857a7037a2d74b2c4b1c8c5d8379b76ea8cbdb1d8dd4367a7a852fa93c lib/request/direct.py
|
||||||
e802cc9099282764da0280172623600b6b9bb9fe1c87f352ade8be7a3f622585 lib/request/dns.py
|
e802cc9099282764da0280172623600b6b9bb9fe1c87f352ade8be7a3f622585 lib/request/dns.py
|
||||||
226226c2b8c906e0d0612ea68404c7f266e7a6685e0bf233e5456e10625b012d lib/request/httpshandler.py
|
9922275d3ca79f00f9b9301f4e4d9f1c444dc7ac38de6d50ef253122abae4833 lib/request/httpshandler.py
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/request/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/request/__init__.py
|
||||||
6944e07e5c061afea30494bcea5198c67b86dda1f291b80e75cb1f121490f1a7 lib/request/inject.py
|
ea8261a5099ca66032ae7606e5392de719827a71750c203e3fc6bb6759757cf3 lib/request/inject.py
|
||||||
ba87a7bc91c1ec99a273284b9d0363358339aab0220651ff1ceddf3737ce2436 lib/request/methodrequest.py
|
ba87a7bc91c1ec99a273284b9d0363358339aab0220651ff1ceddf3737ce2436 lib/request/methodrequest.py
|
||||||
4ba939b6b9a130cd185e749c585afa2c4c8a5dbcbf8216ecc4f3199fe001b3e2 lib/request/pkihandler.py
|
4ba939b6b9a130cd185e749c585afa2c4c8a5dbcbf8216ecc4f3199fe001b3e2 lib/request/pkihandler.py
|
||||||
c6b222c0d34313cdea82fb39c8ead5d658400bf41e56aabd9640bdcf9bedc3a1 lib/request/rangehandler.py
|
c6b222c0d34313cdea82fb39c8ead5d658400bf41e56aabd9640bdcf9bedc3a1 lib/request/rangehandler.py
|
||||||
@@ -224,7 +224,7 @@ c6b222c0d34313cdea82fb39c8ead5d658400bf41e56aabd9640bdcf9bedc3a1 lib/request/ra
|
|||||||
f07a4e40819dc2e7920f9291424761971a9769e4acfd34da223f24717563193c lib/takeover/abstraction.py
|
f07a4e40819dc2e7920f9291424761971a9769e4acfd34da223f24717563193c lib/takeover/abstraction.py
|
||||||
e775a0abe52c1a204c484ef212ff135c857cc8b7e2c94da23b5624c561ec4b9e lib/takeover/icmpsh.py
|
e775a0abe52c1a204c484ef212ff135c857cc8b7e2c94da23b5624c561ec4b9e lib/takeover/icmpsh.py
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/takeover/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 lib/takeover/__init__.py
|
||||||
d7ef25256e5f69b5a54569ad8b87ffa2045b5ed678e5bfbcea75136c0201b034 lib/takeover/metasploit.py
|
c3d8c98a6d44d392f7b8572d3b35804f85838ddbc8e2a2f57af58f8e598af2f4 lib/takeover/metasploit.py
|
||||||
a31b1bf60fcf58b7b735a64d73335212d5089e84051ff7883c14f6c73e055643 lib/takeover/registry.py
|
a31b1bf60fcf58b7b735a64d73335212d5089e84051ff7883c14f6c73e055643 lib/takeover/registry.py
|
||||||
90655344c9968e841eb809845e30da8cc60160390911345ac873be39d270467f lib/takeover/udf.py
|
90655344c9968e841eb809845e30da8cc60160390911345ac873be39d270467f lib/takeover/udf.py
|
||||||
145a9a8b7afb6504700faa1c61ca18eabab3253951788f29e7ee63c3ebff0e48 lib/takeover/web.py
|
145a9a8b7afb6504700faa1c61ca18eabab3253951788f29e7ee63c3ebff0e48 lib/takeover/web.py
|
||||||
@@ -398,7 +398,7 @@ fdc3effe9320197795137dedb58e46c0409f19649889177443a2cbf58787c0dd plugins/dbms/m
|
|||||||
7f0165c085b0cb7d168d86acb790741c7ba12ad01ca9edf7972cfb184adb3ee9 plugins/dbms/mysql/connector.py
|
7f0165c085b0cb7d168d86acb790741c7ba12ad01ca9edf7972cfb184adb3ee9 plugins/dbms/mysql/connector.py
|
||||||
05c4624b2729f13af2dd19286fc9276fc97c0f1ff19a31255785b7581fc232ae plugins/dbms/mysql/enumeration.py
|
05c4624b2729f13af2dd19286fc9276fc97c0f1ff19a31255785b7581fc232ae plugins/dbms/mysql/enumeration.py
|
||||||
9915fd436ea1783724b4fe12ea1d68fc3b838c37684a2c6dd01d53c739a1633f plugins/dbms/mysql/filesystem.py
|
9915fd436ea1783724b4fe12ea1d68fc3b838c37684a2c6dd01d53c739a1633f plugins/dbms/mysql/filesystem.py
|
||||||
ada995d6633ea737e8f12ba4a569ecb1bae9ffe7928c47ed0235f9de2d96f263 plugins/dbms/mysql/fingerprint.py
|
6114337620d824bf061abee8bcfe6e52aea38a54ee437f1cfff92a9a2097c6a7 plugins/dbms/mysql/fingerprint.py
|
||||||
ae824d447c1a59d055367aa9180acb42f7bb10df0006d4f99eeb12e43af563ae plugins/dbms/mysql/__init__.py
|
ae824d447c1a59d055367aa9180acb42f7bb10df0006d4f99eeb12e43af563ae plugins/dbms/mysql/__init__.py
|
||||||
60fc1c647e31df191af2edfd26f99bf739fec53d3a8e1beb3bffdcf335c781fe plugins/dbms/mysql/syntax.py
|
60fc1c647e31df191af2edfd26f99bf739fec53d3a8e1beb3bffdcf335c781fe plugins/dbms/mysql/syntax.py
|
||||||
784c31c2c0e19feb88bf5d21bfc7ae4bf04291922e40830da677577c5d5b4598 plugins/dbms/mysql/takeover.py
|
784c31c2c0e19feb88bf5d21bfc7ae4bf04291922e40830da677577c5d5b4598 plugins/dbms/mysql/takeover.py
|
||||||
@@ -460,8 +460,8 @@ acc41465f146d2611fca5a84bd8896bc0ccd2b032b8938357aea3e5b173a5a10 plugins/dbms/v
|
|||||||
7ac6006e0fc6da229c37fbce39a1406022e5fcc4cac5209814fa20818b8c031a plugins/dbms/virtuoso/takeover.py
|
7ac6006e0fc6da229c37fbce39a1406022e5fcc4cac5209814fa20818b8c031a plugins/dbms/virtuoso/takeover.py
|
||||||
e6dfaab13d9f98ccffdc70dd46800ca2d61519731d10a267bc82f9fb82cd504d plugins/generic/connector.py
|
e6dfaab13d9f98ccffdc70dd46800ca2d61519731d10a267bc82f9fb82cd504d plugins/generic/connector.py
|
||||||
664be8bb4157452f2e40c4f98a359e26b559d7ef4f4148564cb8533b5ebf7d54 plugins/generic/custom.py
|
664be8bb4157452f2e40c4f98a359e26b559d7ef4f4148564cb8533b5ebf7d54 plugins/generic/custom.py
|
||||||
22b85d8b07a5f00a9a0d61093b96accd3c5a3daf50701366feef1b5b58d4042e plugins/generic/databases.py
|
8f4cd6fc48882869203eaa797fea339a5afaf17306a674b384ae18d47839a150 plugins/generic/databases.py
|
||||||
37e83713dbd6564deadb7fe68478129d411de93eaf5c5e0276124248e9373025 plugins/generic/entries.py
|
f8fc1af049d08e7ff87899cad7766f376cc6dfe45baafb86ef13e7252b833e00 plugins/generic/entries.py
|
||||||
a734d74599761cd1cf7d49c88deeb121ea57d80c2f0447e361a4e3a737154c0e plugins/generic/enumeration.py
|
a734d74599761cd1cf7d49c88deeb121ea57d80c2f0447e361a4e3a737154c0e plugins/generic/enumeration.py
|
||||||
1c2e812096015eaef55be45d3a0bcd92b4db27eace47e36577aeff7b4246ad35 plugins/generic/filesystem.py
|
1c2e812096015eaef55be45d3a0bcd92b4db27eace47e36577aeff7b4246ad35 plugins/generic/filesystem.py
|
||||||
05f33c9ba3897e8d75c8cf4be90eb24b08e1d7cd0fc0f74913f052c83bc1a7c1 plugins/generic/fingerprint.py
|
05f33c9ba3897e8d75c8cf4be90eb24b08e1d7cd0fc0f74913f052c83bc1a7c1 plugins/generic/fingerprint.py
|
||||||
@@ -473,10 +473,10 @@ fff84edc86b7d22dc01148fb10bb43d51cb9638dff21436fb94555db2a664766 plugins/generi
|
|||||||
0bc5c150e8cf4f892aba1ff15fc8938c387fb2a173b77329a0dc4cdb8b4bb4e2 plugins/generic/users.py
|
0bc5c150e8cf4f892aba1ff15fc8938c387fb2a173b77329a0dc4cdb8b4bb4e2 plugins/generic/users.py
|
||||||
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 plugins/__init__.py
|
99d0e94dd5fe60137abf48bfa051129fb251f5c40f0f7a270c89fbcb07323730 plugins/__init__.py
|
||||||
d5b3243c2b048aa8074d2d828f74fbf8237286c3d00fd868f1b4090c267b78ef README.md
|
d5b3243c2b048aa8074d2d828f74fbf8237286c3d00fd868f1b4090c267b78ef README.md
|
||||||
6cfaaf6534688cecda09433246d0a8518f98ce5cf6d6a8159f24d70502cfc14f sqlmapapi.py
|
78aafd53980096364f0c995c6283931bff505aed88fed1e7906fb06ee60e9c5b sqlmapapi.py
|
||||||
168309215af7dd5b0b71070e1770e72f1cbb29a3d8025143fb8aa0b88cd56b62 sqlmapapi.yaml
|
168309215af7dd5b0b71070e1770e72f1cbb29a3d8025143fb8aa0b88cd56b62 sqlmapapi.yaml
|
||||||
5e172e315524845fe091aa0b7b29303c92ac8f67594c6d50f026d627e415b7ed sqlmap.conf
|
5e172e315524845fe091aa0b7b29303c92ac8f67594c6d50f026d627e415b7ed sqlmap.conf
|
||||||
7800faa964d1fc06bbca856ca35bf21d68f5e044ae0bd5d7dea16d625d585adb sqlmap.py
|
3a18b78b1aaf7236a35169db20eb21ca7d7fb907cd38dd34650f1da81c010cd6 sqlmap.py
|
||||||
adda508966db26c30b11390d6483c1fa25b092942a29730e739e1e50c403a21f tamper/0eunion.py
|
adda508966db26c30b11390d6483c1fa25b092942a29730e739e1e50c403a21f tamper/0eunion.py
|
||||||
d38fe5ab97b401810612eae049325aa990c55143504b25cc9924810917511dee tamper/apostrophemask.py
|
d38fe5ab97b401810612eae049325aa990c55143504b25cc9924810917511dee tamper/apostrophemask.py
|
||||||
8de713d1534d8cda171db4ceeb9f4324bcc030bbef21ffeaf60396c6bece31e4 tamper/apostrophenullencode.py
|
8de713d1534d8cda171db4ceeb9f4324bcc030bbef21ffeaf60396c6bece31e4 tamper/apostrophenullencode.py
|
||||||
@@ -549,9 +549,9 @@ b4b03668061ba1a1dfc2e3a3db8ba500481da23f22b2bb1ebcbddada7479c3b0 tamper/upperca
|
|||||||
bd0fd06e24c3e05aecaccf5ba4c17d181e6cd35eee82c0efd6df5414fb0cb6f6 tamper/xforwardedfor.py
|
bd0fd06e24c3e05aecaccf5ba4c17d181e6cd35eee82c0efd6df5414fb0cb6f6 tamper/xforwardedfor.py
|
||||||
55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py
|
55eaefc664bd8598329d535370612351ec8443c52465f0a37172ea46a97c458a thirdparty/ansistrm/ansistrm.py
|
||||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/ansistrm/__init__.py
|
||||||
82b6daf563d8c1933a8de655e04d6c8466d3db5c583c952e450d47ccc5c7c662 thirdparty/beautifulsoup/beautifulsoup.py
|
dfb8a36f58a3ae72c34d6a350830857c88ff8938fe256af585d5c9c63040c5b2 thirdparty/beautifulsoup/beautifulsoup.py
|
||||||
bc92179cb2785712951fef05333290abf22e5b595e0a93d0168cc05132bc5f37 thirdparty/beautifulsoup/__init__.py
|
7d62c59f787f987cbce0de5375f604da8de0ba01742842fb2b3d12fcb92fcb63 thirdparty/beautifulsoup/__init__.py
|
||||||
1b0f89e4713cc8cec4e4d824368a4eb9d3bdce7ddfc712326caac4feda1d7f69 thirdparty/bottle/bottle.py
|
0915f7e3d0025f81a2883cd958813470a4be661744d7fffa46848b45506b951a thirdparty/bottle/bottle.py
|
||||||
9f56e761d79bfdb34304a012586cb04d16b435ef6130091a97702e559260a2f2 thirdparty/bottle/__init__.py
|
9f56e761d79bfdb34304a012586cb04d16b435ef6130091a97702e559260a2f2 thirdparty/bottle/__init__.py
|
||||||
0ffccae46cb3a15b117acd0790b2738a5b45417d1b2822ceac57bdff10ef3bff thirdparty/chardet/big5freq.py
|
0ffccae46cb3a15b117acd0790b2738a5b45417d1b2822ceac57bdff10ef3bff thirdparty/chardet/big5freq.py
|
||||||
901c476dd7ad0693deef1ae56fe7bdf748a8b7ae20fde1922dddf6941eff8773 thirdparty/chardet/big5prober.py
|
901c476dd7ad0693deef1ae56fe7bdf748a8b7ae20fde1922dddf6941eff8773 thirdparty/chardet/big5prober.py
|
||||||
@@ -595,7 +595,7 @@ b29dc1d3c9ab0d707ea5fdcaf5fa89ff37831ce08b0bc46b9e04320c56a9ffb8 thirdparty/cha
|
|||||||
1c1ee8a91eb20f8038ace6611610673243d0f71e2b7566111698462182c7efdd thirdparty/clientform/clientform.py
|
1c1ee8a91eb20f8038ace6611610673243d0f71e2b7566111698462182c7efdd thirdparty/clientform/clientform.py
|
||||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/clientform/__init__.py
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/clientform/__init__.py
|
||||||
162d2e9fe40ba919bebfba3f9ca88eab20bc3daa4124aec32d5feaf4b2ad4ced thirdparty/colorama/ansi.py
|
162d2e9fe40ba919bebfba3f9ca88eab20bc3daa4124aec32d5feaf4b2ad4ced thirdparty/colorama/ansi.py
|
||||||
bca8d86f2c754732435b67e9b22de0232b6c57dabeefc8afb24fbe861377a826 thirdparty/colorama/ansitowin32.py
|
a7070aa13221d97e6d2df0f522b41f1876cd46cb1ddb16d44c1f304f7bab03a3 thirdparty/colorama/ansitowin32.py
|
||||||
d7b5750fa3a21295c761a00716543234aefd2aa8250966a6c06de38c50634659 thirdparty/colorama/initialise.py
|
d7b5750fa3a21295c761a00716543234aefd2aa8250966a6c06de38c50634659 thirdparty/colorama/initialise.py
|
||||||
f71072ad3be4f6ea642f934657922dd848dee3e93334bc1aff59463d6a57a0d5 thirdparty/colorama/__init__.py
|
f71072ad3be4f6ea642f934657922dd848dee3e93334bc1aff59463d6a57a0d5 thirdparty/colorama/__init__.py
|
||||||
fd2084a132bf180dad5359e16dac8a29a73ebfd267f7c9423c814e7853060874 thirdparty/colorama/win32.py
|
fd2084a132bf180dad5359e16dac8a29a73ebfd267f7c9423c814e7853060874 thirdparty/colorama/win32.py
|
||||||
@@ -622,7 +622,7 @@ d1d54fc08f80148a4e2ac5eee84c8475617e8c18bfbde0dfe6894c0f868e4659 thirdparty/pyd
|
|||||||
1c61d71502a80f642ff34726aa287ac40c1edd8f9239ce2e094f6fded00d00d4 thirdparty/six/__init__.py
|
1c61d71502a80f642ff34726aa287ac40c1edd8f9239ce2e094f6fded00d00d4 thirdparty/six/__init__.py
|
||||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/socks/__init__.py
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/socks/__init__.py
|
||||||
7027e214e014eb78b7adcc1ceda5aca713a79fc4f6a0c52c9da5b3e707e6ffe9 thirdparty/socks/LICENSE
|
7027e214e014eb78b7adcc1ceda5aca713a79fc4f6a0c52c9da5b3e707e6ffe9 thirdparty/socks/LICENSE
|
||||||
5ac11e932896dfb7d50353dd16f717bd98cb1fb235f28e6fe8880c03655838bb thirdparty/socks/socks.py
|
543217f63a4f0a7e7b4f9063058d2173099d54d010a6a4432e15a97f76456520 thirdparty/socks/socks.py
|
||||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/termcolor/__init__.py
|
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 thirdparty/termcolor/__init__.py
|
||||||
b14474d467c70f5fe6cb8ed624f79d881c04fe6aeb7d406455da624fe8b3c0df thirdparty/termcolor/termcolor.py
|
b14474d467c70f5fe6cb8ed624f79d881c04fe6aeb7d406455da624fe8b3c0df thirdparty/termcolor/termcolor.py
|
||||||
4db695470f664b0d7cd5e6b9f3c94c8d811c4c550f37f17ed7bdab61bc3bdefc thirdparty/wininetpton/__init__.py
|
4db695470f664b0d7cd5e6b9f3c94c8d811c4c550f37f17ed7bdab61bc3bdefc thirdparty/wininetpton/__init__.py
|
||||||
|
|||||||
@@ -554,6 +554,15 @@ Formats:
|
|||||||
</boundary>
|
</boundary>
|
||||||
<!-- End of escaped column name boundaries -->
|
<!-- End of escaped column name boundaries -->
|
||||||
|
|
||||||
|
<boundary>
|
||||||
|
<level>5</level>
|
||||||
|
<clause>7</clause>
|
||||||
|
<where>1</where>
|
||||||
|
<ptype>3</ptype>
|
||||||
|
<prefix> [RANDSTR1],</prefix>
|
||||||
|
<suffix> [RANDSTR2]</suffix>
|
||||||
|
</boundary>
|
||||||
|
|
||||||
<!-- AGAINST boolean full-text search boundaries (http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html) -->
|
<!-- AGAINST boolean full-text search boundaries (http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html) -->
|
||||||
<boundary>
|
<boundary>
|
||||||
<level>4</level>
|
<level>4</level>
|
||||||
|
|||||||
@@ -221,6 +221,26 @@
|
|||||||
</details>
|
</details>
|
||||||
</test>
|
</test>
|
||||||
|
|
||||||
|
<test>
|
||||||
|
<title>MySQL >= 5.0 (inline) error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)</title>
|
||||||
|
<stype>2</stype>
|
||||||
|
<level>5</level>
|
||||||
|
<risk>1</risk>
|
||||||
|
<clause>7</clause>
|
||||||
|
<where>1</where>
|
||||||
|
<vector>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</vector>
|
||||||
|
<request>
|
||||||
|
<payload>(SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (ELT([RANDNUM]=[RANDNUM],1))),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)</payload>
|
||||||
|
</request>
|
||||||
|
<response>
|
||||||
|
<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
|
||||||
|
</response>
|
||||||
|
<details>
|
||||||
|
<dbms>MySQL</dbms>
|
||||||
|
<dbms_version>>= 5.0</dbms_version>
|
||||||
|
</details>
|
||||||
|
</test>
|
||||||
|
|
||||||
<test>
|
<test>
|
||||||
<title>MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)</title>
|
<title>MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)</title>
|
||||||
<stype>2</stype>
|
<stype>2</stype>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
|
[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
|
||||||
|
|
||||||
sqlmap adalah alat bantu proyek sumber terbuka yang digunakan untuk melakukan uji penetrasi, mengotomasi proses deteksi, eksploitasi kelemahan _SQL injection_ serta pengambil-alihan server basis data.
|
sqlmap adalah perangkat lunak sumber terbuka yang digunakan untuk melakukan uji penetrasi, mengotomasi proses deteksi, eksploitasi kelemahan _SQL injection_ serta pengambil-alihan server basis data.
|
||||||
|
|
||||||
sqlmap dilengkapi dengan pendeteksi canggih dan fitur-fitur handal yang berguna bagi _penetration tester_. Alat ini menawarkan berbagai cara untuk mendeteksi basis data bahkan dapat mengakses sistem file dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
|
sqlmap dilengkapi dengan pendeteksi canggih dan fitur-fitur handal yang berguna bagi _penetration tester_. Perangkat lunak ini menawarkan berbagai cara untuk mendeteksi basis data bahkan dapat mengakses sistem file dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
|
||||||
|
|
||||||
Tangkapan Layar
|
Tangkapan Layar
|
||||||
----
|
----
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
icmpsh - simple reverse ICMP shell
|
icmpsh - simple reverse ICMP shell
|
||||||
|
|
||||||
icmpsh is a simple reverse ICMP shell with a win32 slave and a POSIX compatible master in C or Perl.
|
icmpsh is a simple reverse ICMP shell with a win32 slave and a POSIX compatible master in C or Perl.
|
||||||
|
|
||||||
|
|
||||||
--- Running the Master ---
|
--- Running the Master ---
|
||||||
|
|
||||||
The master is straight forward to use. There are no extra libraries required for the C version.
|
The master is straight forward to use. There are no extra libraries required for the C version.
|
||||||
The Perl master however has the following dependencies:
|
The Perl master however has the following dependencies:
|
||||||
|
|
||||||
* IO::Socket
|
* IO::Socket
|
||||||
* NetPacket::IP
|
* NetPacket::IP
|
||||||
* NetPacket::ICMP
|
* NetPacket::ICMP
|
||||||
|
|
||||||
|
|
||||||
When running the master, don't forget to disable ICMP replies by the OS. For example:
|
When running the master, don't forget to disable ICMP replies by the OS. For example:
|
||||||
|
|
||||||
sysctl -w net.ipv4.icmp_echo_ignore_all=1
|
sysctl -w net.ipv4.icmp_echo_ignore_all=1
|
||||||
|
|
||||||
If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
|
If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
|
||||||
commands send from the master.
|
commands send from the master.
|
||||||
|
|
||||||
|
|
||||||
--- Running the Slave ---
|
--- Running the Slave ---
|
||||||
|
|
||||||
The slave comes with a few command line options as outlined below:
|
The slave comes with a few command line options as outlined below:
|
||||||
|
|
||||||
|
|
||||||
-t host host ip address to send ping requests to. This option is mandatory!
|
-t host host ip address to send ping requests to. This option is mandatory!
|
||||||
|
|
||||||
-r send a single test icmp request containing the string "Test1234" and then quit.
|
-r send a single test icmp request containing the string "Test1234" and then quit.
|
||||||
This is for testing the connection.
|
This is for testing the connection.
|
||||||
|
|
||||||
-d milliseconds delay between requests in milliseconds
|
-d milliseconds delay between requests in milliseconds
|
||||||
|
|
||||||
-o milliseconds timeout of responses in milliseconds. If a response has not received in time,
|
-o milliseconds timeout of responses in milliseconds. If a response has not received in time,
|
||||||
the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
|
the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
|
||||||
The counter is set back to 0 if a response was received.
|
The counter is set back to 0 if a response was received.
|
||||||
|
|
||||||
-b num limit of blanks (unanswered icmp requests before quitting
|
-b num limit of blanks (unanswered icmp requests before quitting
|
||||||
|
|
||||||
-s bytes maximal data buffer size in bytes
|
-s bytes maximal data buffer size in bytes
|
||||||
|
|
||||||
|
|
||||||
In order to improve the speed, lower the delay (-d) between requests or increase the size (-s) of the data buffer.
|
In order to improve the speed, lower the delay (-d) between requests or increase the size (-s) of the data buffer.
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ setup(
|
|||||||
},
|
},
|
||||||
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
|
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
|
||||||
license='GNU General Public License v2 (GPLv2)',
|
license='GNU General Public License v2 (GPLv2)',
|
||||||
packages=find_packages(),
|
packages=['sqlmap'],
|
||||||
|
package_dir={'sqlmap':'sqlmap'},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||||
@@ -176,5 +177,7 @@ EOF
|
|||||||
sed -i "s/^VERSION =.*/VERSION = \"$VERSION\"/g" sqlmap/lib/core/settings.py
|
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/^TYPE =.*/TYPE = \"$TYPE\"/g" sqlmap/lib/core/settings.py
|
||||||
for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
|
for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
|
||||||
python setup.py sdist upload
|
python setup.py sdist bdist_wheel
|
||||||
|
twine check dist/*
|
||||||
|
twine upload --config-file=~/.pypirc dist/*
|
||||||
rm -rf $TMP_DIR
|
rm -rf $TMP_DIR
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class BigArray(list):
|
|||||||
>>> _ = _ + [1]
|
>>> _ = _ + [1]
|
||||||
>>> _[-1]
|
>>> _[-1]
|
||||||
1
|
1
|
||||||
|
>>> len([_ for _ in BigArray(xrange(100000))])
|
||||||
|
100000
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, items=None):
|
def __init__(self, items=None):
|
||||||
@@ -198,7 +200,10 @@ class BigArray(list):
|
|||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for i in xrange(len(self)):
|
for i in xrange(len(self)):
|
||||||
yield self[i]
|
try:
|
||||||
|
yield self[i]
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * self.chunk_length + len(self.chunks[-1])
|
return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * self.chunk_length + len(self.chunks[-1])
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ from lib.core.settings import HTTP_CHUNKED_SPLIT_KEYWORDS
|
|||||||
from lib.core.settings import IGNORE_PARAMETERS
|
from lib.core.settings import IGNORE_PARAMETERS
|
||||||
from lib.core.settings import IGNORE_SAVE_OPTIONS
|
from lib.core.settings import IGNORE_SAVE_OPTIONS
|
||||||
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
||||||
|
from lib.core.settings import INJECT_HERE_REGEX
|
||||||
from lib.core.settings import IP_ADDRESS_REGEX
|
from lib.core.settings import IP_ADDRESS_REGEX
|
||||||
from lib.core.settings import ISSUES_PAGE
|
from lib.core.settings import ISSUES_PAGE
|
||||||
from lib.core.settings import IS_TTY
|
from lib.core.settings import IS_TTY
|
||||||
@@ -1333,7 +1334,10 @@ def isZipFile(filename):
|
|||||||
|
|
||||||
checkFile(filename)
|
checkFile(filename)
|
||||||
|
|
||||||
return openFile(filename, "rb", encoding=None).read(len(ZIP_HEADER)) == ZIP_HEADER
|
with openFile(filename, "rb", encoding=None) as f:
|
||||||
|
header = f.read(len(ZIP_HEADER))
|
||||||
|
|
||||||
|
return header == ZIP_HEADER
|
||||||
|
|
||||||
def isDigit(value):
|
def isDigit(value):
|
||||||
"""
|
"""
|
||||||
@@ -2533,21 +2537,22 @@ def initCommonOutputs():
|
|||||||
kb.commonOutputs = {}
|
kb.commonOutputs = {}
|
||||||
key = None
|
key = None
|
||||||
|
|
||||||
for line in openFile(paths.COMMON_OUTPUTS, 'r'):
|
with openFile(paths.COMMON_OUTPUTS, 'r') as f:
|
||||||
if line.find('#') != -1:
|
for line in f:
|
||||||
line = line[:line.find('#')]
|
if line.find('#') != -1:
|
||||||
|
line = line[:line.find('#')]
|
||||||
|
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
|
|
||||||
if len(line) > 1:
|
if len(line) > 1:
|
||||||
if line.startswith('[') and line.endswith(']'):
|
if line.startswith('[') and line.endswith(']'):
|
||||||
key = line[1:-1]
|
key = line[1:-1]
|
||||||
elif key:
|
elif key:
|
||||||
if key not in kb.commonOutputs:
|
if key not in kb.commonOutputs:
|
||||||
kb.commonOutputs[key] = set()
|
kb.commonOutputs[key] = set()
|
||||||
|
|
||||||
if line not in kb.commonOutputs[key]:
|
if line not in kb.commonOutputs[key]:
|
||||||
kb.commonOutputs[key].add(line)
|
kb.commonOutputs[key].add(line)
|
||||||
|
|
||||||
def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
|
def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
|
||||||
"""
|
"""
|
||||||
@@ -4643,7 +4648,7 @@ def isAdminFromPrivileges(privileges):
|
|||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def findPageForms(content, url, raise_=False, addToTargets=False):
|
def findPageForms(content, url, raiseException=False, addToTargets=False):
|
||||||
"""
|
"""
|
||||||
Parses given page content for possible forms (Note: still not implemented for Python3)
|
Parses given page content for possible forms (Note: still not implemented for Python3)
|
||||||
|
|
||||||
@@ -4661,7 +4666,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
|
|
||||||
if not content:
|
if not content:
|
||||||
errMsg = "can't parse forms as the page content appears to be blank"
|
errMsg = "can't parse forms as the page content appears to be blank"
|
||||||
if raise_:
|
if raiseException:
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.debug(errMsg)
|
logger.debug(errMsg)
|
||||||
@@ -4683,7 +4688,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
forms = ParseResponse(filtered, backwards_compat=False)
|
forms = ParseResponse(filtered, backwards_compat=False)
|
||||||
except:
|
except:
|
||||||
errMsg = "no success"
|
errMsg = "no success"
|
||||||
if raise_:
|
if raiseException:
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.debug(errMsg)
|
logger.debug(errMsg)
|
||||||
@@ -4710,7 +4715,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
except (ValueError, TypeError) as ex:
|
except (ValueError, TypeError) as ex:
|
||||||
errMsg = "there has been a problem while "
|
errMsg = "there has been a problem while "
|
||||||
errMsg += "processing page forms ('%s')" % getSafeExString(ex)
|
errMsg += "processing page forms ('%s')" % getSafeExString(ex)
|
||||||
if raise_:
|
if raiseException:
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.debug(errMsg)
|
logger.debug(errMsg)
|
||||||
@@ -4762,7 +4767,7 @@ def findPageForms(content, url, raise_=False, addToTargets=False):
|
|||||||
|
|
||||||
if not retVal and not conf.crawlDepth:
|
if not retVal and not conf.crawlDepth:
|
||||||
errMsg = "there were no forms found at the given target URL"
|
errMsg = "there were no forms found at the given target URL"
|
||||||
if raise_:
|
if raiseException:
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
else:
|
else:
|
||||||
logger.debug(errMsg)
|
logger.debug(errMsg)
|
||||||
@@ -5271,6 +5276,9 @@ def parseRequestFile(reqFile, checkParams=True):
|
|||||||
Parses WebScarab logs (POST method not supported)
|
Parses WebScarab logs (POST method not supported)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if WEBSCARAB_SPLITTER not in content:
|
||||||
|
return
|
||||||
|
|
||||||
reqResList = content.split(WEBSCARAB_SPLITTER)
|
reqResList = content.split(WEBSCARAB_SPLITTER)
|
||||||
|
|
||||||
for request in reqResList:
|
for request in reqResList:
|
||||||
@@ -5354,6 +5362,8 @@ def parseRequestFile(reqFile, checkParams=True):
|
|||||||
if not line.strip() and index == len(lines) - 1:
|
if not line.strip() and index == len(lines) - 1:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
line = re.sub(INJECT_HERE_REGEX, CUSTOM_INJECTION_MARK_CHAR, line)
|
||||||
|
|
||||||
newline = "\r\n" if line.endswith('\r') else '\n'
|
newline = "\r\n" if line.endswith('\r') else '\n'
|
||||||
line = line.strip('\r')
|
line = line.strip('\r')
|
||||||
match = re.search(r"\A([A-Z]+) (.+) HTTP/[\d.]+\Z", line) if not method else None
|
match = re.search(r"\A([A-Z]+) (.+) HTTP/[\d.]+\Z", line) if not method else None
|
||||||
@@ -5398,9 +5408,9 @@ def parseRequestFile(reqFile, checkParams=True):
|
|||||||
|
|
||||||
port = extractRegexResult(r":(?P<result>\d+)\Z", value)
|
port = extractRegexResult(r":(?P<result>\d+)\Z", value)
|
||||||
if port:
|
if port:
|
||||||
value = value[:-(1 + len(port))]
|
host = value[:-(1 + len(port))]
|
||||||
|
else:
|
||||||
host = value
|
host = value
|
||||||
|
|
||||||
# Avoid to add a static content length header to
|
# Avoid to add a static content length header to
|
||||||
# headers and consider the following lines as
|
# headers and consider the following lines as
|
||||||
@@ -5594,7 +5604,9 @@ def checkSums():
|
|||||||
expected, filename = match.groups()
|
expected, filename = match.groups()
|
||||||
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, filename).replace('/', os.path.sep)
|
filepath = os.path.join(paths.SQLMAP_ROOT_PATH, filename).replace('/', os.path.sep)
|
||||||
checkFile(filepath)
|
checkFile(filepath)
|
||||||
if not hashlib.sha256(open(filepath, "rb").read()).hexdigest() == expected:
|
with open(filepath, "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
if not hashlib.sha256(content).hexdigest() == expected:
|
||||||
retVal &= False
|
retVal &= False
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|||||||
@@ -1360,7 +1360,7 @@ def _setHTTPAuthentication():
|
|||||||
errMsg += "be in format 'DOMAIN\\username:password'"
|
errMsg += "be in format 'DOMAIN\\username:password'"
|
||||||
elif authType == AUTH_TYPE.PKI:
|
elif authType == AUTH_TYPE.PKI:
|
||||||
errMsg = "HTTP PKI authentication require "
|
errMsg = "HTTP PKI authentication require "
|
||||||
errMsg += "usage of option `--auth-pki`"
|
errMsg += "usage of option `--auth-file`"
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
aCredRegExp = re.search(regExp, conf.authCred)
|
aCredRegExp = re.search(regExp, conf.authCred)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
|
|||||||
import codecs
|
import codecs
|
||||||
import collections
|
import collections
|
||||||
import inspect
|
import inspect
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
@@ -37,9 +38,12 @@ from lib.core.data import conf
|
|||||||
from lib.core.enums import PLACE
|
from lib.core.enums import PLACE
|
||||||
from lib.core.option import _setHTTPHandlers
|
from lib.core.option import _setHTTPHandlers
|
||||||
from lib.core.option import setVerbosity
|
from lib.core.option import setVerbosity
|
||||||
|
from lib.core.settings import INVALID_UNICODE_PRIVATE_AREA
|
||||||
|
from lib.core.settings import INVALID_UNICODE_CHAR_FORMAT
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.request.templates import getPageTemplate
|
from lib.request.templates import getPageTemplate
|
||||||
from thirdparty import six
|
from thirdparty import six
|
||||||
|
from thirdparty.six import unichr as _unichr
|
||||||
from thirdparty.six.moves import http_client as _http_client
|
from thirdparty.six.moves import http_client as _http_client
|
||||||
|
|
||||||
_rand = 0
|
_rand = 0
|
||||||
@@ -86,7 +90,7 @@ def dirtyPatches():
|
|||||||
if match and match.group(1).upper() != PLACE.POST:
|
if match and match.group(1).upper() != PLACE.POST:
|
||||||
PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))
|
PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))
|
||||||
|
|
||||||
# https://github.com/sqlmapproject/sqlmap/issues/4314
|
# Reference: https://github.com/sqlmapproject/sqlmap/issues/4314
|
||||||
try:
|
try:
|
||||||
os.urandom(1)
|
os.urandom(1)
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
@@ -95,6 +99,14 @@ def dirtyPatches():
|
|||||||
else:
|
else:
|
||||||
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
|
os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))
|
||||||
|
|
||||||
|
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5727
|
||||||
|
# Reference: https://stackoverflow.com/a/14076841
|
||||||
|
try:
|
||||||
|
import pymysql
|
||||||
|
pymysql.install_as_MySQLdb()
|
||||||
|
except (ImportError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
# Reference: https://github.com/bottlepy/bottle/blob/df67999584a0e51ec5b691146c7fa4f3c87f5aac/bottle.py
|
# Reference: https://github.com/bottlepy/bottle/blob/df67999584a0e51ec5b691146c7fa4f3c87f5aac/bottle.py
|
||||||
# Reference: https://python.readthedocs.io/en/v2.7.2/library/inspect.html#inspect.getargspec
|
# Reference: https://python.readthedocs.io/en/v2.7.2/library/inspect.html#inspect.getargspec
|
||||||
if not hasattr(inspect, "getargspec") and hasattr(inspect, "getfullargspec"):
|
if not hasattr(inspect, "getargspec") and hasattr(inspect, "getfullargspec"):
|
||||||
@@ -115,6 +127,30 @@ def dirtyPatches():
|
|||||||
|
|
||||||
inspect.getargspec = getargspec
|
inspect.getargspec = getargspec
|
||||||
|
|
||||||
|
# Installing "reversible" unicode (decoding) error handler
|
||||||
|
def _reversible(ex):
|
||||||
|
if INVALID_UNICODE_PRIVATE_AREA:
|
||||||
|
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||||
|
else:
|
||||||
|
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
||||||
|
|
||||||
|
codecs.register_error("reversible", _reversible)
|
||||||
|
|
||||||
|
# Reference: https://github.com/sqlmapproject/sqlmap/issues/5731
|
||||||
|
if not hasattr(logging, "_acquireLock"):
|
||||||
|
def _acquireLock():
|
||||||
|
if logging._lock:
|
||||||
|
logging._lock.acquire()
|
||||||
|
|
||||||
|
logging._acquireLock = _acquireLock
|
||||||
|
|
||||||
|
if not hasattr(logging, "_releaseLock"):
|
||||||
|
def _releaseLock():
|
||||||
|
if logging._lock:
|
||||||
|
logging._lock.release()
|
||||||
|
|
||||||
|
logging._releaseLock = _releaseLock
|
||||||
|
|
||||||
def resolveCrossReferences():
|
def resolveCrossReferences():
|
||||||
"""
|
"""
|
||||||
Place for cross-reference resolution
|
Place for cross-reference resolution
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ from lib.core.enums import DBMS
|
|||||||
from lib.core.enums import DBMS_DIRECTORY_NAME
|
from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
from thirdparty import six
|
from thirdparty import six
|
||||||
from thirdparty.six import unichr as _unichr
|
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.8.4.0"
|
VERSION = "1.8.8.0"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
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)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
@@ -443,7 +442,7 @@ COMMON_PASSWORD_SUFFIXES += ("!", ".", "*", "!!", "?", ";", "..", "!!!", ", ", "
|
|||||||
WEBSCARAB_SPLITTER = "### Conversation"
|
WEBSCARAB_SPLITTER = "### Conversation"
|
||||||
|
|
||||||
# Splitter used between requests in BURP log files
|
# Splitter used between requests in BURP log files
|
||||||
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+={10,}"
|
BURP_REQUEST_REGEX = r"={10,}\s+([A-Z]{3,} .+?)\s+(={10,}|\Z)"
|
||||||
|
|
||||||
# Regex used for parsing XML Burp saved history items
|
# Regex used for parsing XML Burp saved history items
|
||||||
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.*?<request base64="true"><!\[CDATA\[([^]]+)'
|
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.*?<request base64="true"><!\[CDATA\[([^]]+)'
|
||||||
@@ -461,7 +460,7 @@ URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
|
|||||||
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*\b%s\b[^\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)
|
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
|
||||||
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred", "sqlQuery", "requestFile")
|
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred", "sqlQuery", "requestFile", "csrfToken", "csrfData", "csrfUrl", "testParameter")
|
||||||
|
|
||||||
# Maximum number of threads (avoiding connection issues and/or DoS)
|
# Maximum number of threads (avoiding connection issues and/or DoS)
|
||||||
MAX_NUMBER_OF_THREADS = 10
|
MAX_NUMBER_OF_THREADS = 10
|
||||||
@@ -908,6 +907,9 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
|
|||||||
# Letters of lower frequency used in kb.chars
|
# Letters of lower frequency used in kb.chars
|
||||||
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
|
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
|
||||||
|
|
||||||
|
# For filling in case of dumb push updates
|
||||||
|
DUMMY_JUNK = "Rie3Shie"
|
||||||
|
|
||||||
# Printable bytes
|
# Printable bytes
|
||||||
PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable)
|
PRINTABLE_BYTES = set(bytes(string.printable, "ascii") if six.PY3 else string.printable)
|
||||||
|
|
||||||
@@ -956,12 +958,3 @@ for key, value in os.environ.items():
|
|||||||
globals()[_] = [__.strip() for __ in _.split(',')]
|
globals()[_] = [__.strip() for __ in _.split(',')]
|
||||||
else:
|
else:
|
||||||
globals()[_] = value
|
globals()[_] = value
|
||||||
|
|
||||||
# Installing "reversible" unicode (decoding) error handler
|
|
||||||
def _reversible(ex):
|
|
||||||
if INVALID_UNICODE_PRIVATE_AREA:
|
|
||||||
return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
|
||||||
else:
|
|
||||||
return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
|
|
||||||
|
|
||||||
codecs.register_error("reversible", _reversible)
|
|
||||||
|
|||||||
@@ -162,7 +162,9 @@ def vulnTest():
|
|||||||
direct = "sqlite3://%s" % database
|
direct = "sqlite3://%s" % database
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
|
||||||
content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url)
|
with open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))) as f:
|
||||||
|
content = f.read().replace("url =", "url = %s" % url)
|
||||||
|
|
||||||
with open(config, "w+") as f:
|
with open(config, "w+") as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
f.flush()
|
f.flush()
|
||||||
@@ -214,7 +216,9 @@ def smokeTest():
|
|||||||
|
|
||||||
unisonRandom()
|
unisonRandom()
|
||||||
|
|
||||||
content = open(paths.ERRORS_XML, "r").read()
|
with open(paths.ERRORS_XML, "r") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
for regex in re.findall(r'<error regexp="(.+?)"/>', content):
|
||||||
try:
|
try:
|
||||||
re.compile(regex)
|
re.compile(regex)
|
||||||
|
|||||||
@@ -68,7 +68,10 @@ def configFileParser(configFile):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
config = UnicodeRawConfigParser()
|
config = UnicodeRawConfigParser()
|
||||||
config.readfp(configFP)
|
if hasattr(config, "read_file"):
|
||||||
|
config.read_file(configFP)
|
||||||
|
else:
|
||||||
|
config.readfp(configFP)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex)
|
errMsg = "you have provided an invalid and/or unreadable configuration file ('%s')" % getSafeExString(ex)
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|||||||
@@ -282,15 +282,8 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
|
|||||||
if not page or (conf.nullConnection and len(page) < 2):
|
if not page or (conf.nullConnection and len(page) < 2):
|
||||||
return getUnicode(page)
|
return getUnicode(page)
|
||||||
|
|
||||||
if hasattr(contentEncoding, "lower"):
|
contentEncoding = contentEncoding.lower() if hasattr(contentEncoding, "lower") else ""
|
||||||
contentEncoding = contentEncoding.lower()
|
contentType = contentType.lower() if hasattr(contentType, "lower") else ""
|
||||||
else:
|
|
||||||
contentEncoding = ""
|
|
||||||
|
|
||||||
if hasattr(contentType, "lower"):
|
|
||||||
contentType = contentType.lower()
|
|
||||||
else:
|
|
||||||
contentType = ""
|
|
||||||
|
|
||||||
if contentEncoding in ("gzip", "x-gzip", "deflate"):
|
if contentEncoding in ("gzip", "x-gzip", "deflate"):
|
||||||
if not kb.pageCompress:
|
if not kb.pageCompress:
|
||||||
@@ -382,7 +375,6 @@ def decodePage(page, contentEncoding, contentType, percentDecode=True):
|
|||||||
|
|
||||||
def processResponse(page, responseHeaders, code=None, status=None):
|
def processResponse(page, responseHeaders, code=None, status=None):
|
||||||
kb.processResponseCounter += 1
|
kb.processResponseCounter += 1
|
||||||
|
|
||||||
page = page or ""
|
page = page or ""
|
||||||
|
|
||||||
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)
|
parseResponse(page, responseHeaders if kb.processResponseCounter < PARSE_HEADERS_LIMIT else None, status)
|
||||||
|
|||||||
@@ -914,12 +914,6 @@ class Connect(object):
|
|||||||
raise SqlmapConnectionException(warnMsg)
|
raise SqlmapConnectionException(warnMsg)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
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 = six.text_type(page, errors="ignore")
|
|
||||||
else:
|
|
||||||
page = getUnicode(page)
|
|
||||||
|
|
||||||
for function in kb.postprocessFunctions:
|
for function in kb.postprocessFunctions:
|
||||||
try:
|
try:
|
||||||
page, responseHeaders, code = function(page, responseHeaders, code)
|
page, responseHeaders, code = function(page, responseHeaders, code)
|
||||||
@@ -928,6 +922,12 @@ class Connect(object):
|
|||||||
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
|
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
|
||||||
|
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 = six.text_type(page, errors="ignore")
|
||||||
|
else:
|
||||||
|
page = getUnicode(page)
|
||||||
|
|
||||||
for _ in (getattr(conn, "redcode", None), code):
|
for _ in (getattr(conn, "redcode", None), code):
|
||||||
if _ is not None and _ in conf.abortCode:
|
if _ is not None and _ in conf.abortCode:
|
||||||
errMsg = "aborting due to detected HTTP code '%d'" % _
|
errMsg = "aborting due to detected HTTP code '%d'" % _
|
||||||
@@ -1183,7 +1183,7 @@ class Connect(object):
|
|||||||
if match:
|
if match:
|
||||||
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
|
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
|
||||||
else:
|
else:
|
||||||
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString, re.I)
|
match = re.search(r"(%s[\"']\s*:\s*[\"'])([^\"']*)" % re.escape(parameter), paramString, re.I)
|
||||||
if match:
|
if match:
|
||||||
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
|
retVal = re.sub(r"(?i)%s" % re.escape(match.group(0)), "%s%s" % (match.group(1), newValue), paramString)
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class HTTPSConnection(_http_client.HTTPSConnection):
|
|||||||
# Reference(s): https://askubuntu.com/a/1263098
|
# Reference(s): https://askubuntu.com/a/1263098
|
||||||
# https://askubuntu.com/a/1250807
|
# https://askubuntu.com/a/1250807
|
||||||
_contexts[protocol].set_ciphers("DEFAULT@SECLEVEL=1")
|
_contexts[protocol].set_ciphers("DEFAULT@SECLEVEL=1")
|
||||||
except ssl.SSLError:
|
except (ssl.SSLError, AttributeError):
|
||||||
pass
|
pass
|
||||||
result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host if re.search(r"\A[\d.]+\Z", self.host or "") is None else None)
|
result = _contexts[protocol].wrap_socket(sock, do_handshake_on_connect=True, server_hostname=self.host if re.search(r"\A[\d.]+\Z", self.host or "") is None else None)
|
||||||
if result:
|
if result:
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ def _goInferenceProxy(expression, fromUser=False, batch=False, unpack=True, char
|
|||||||
if limitCond:
|
if limitCond:
|
||||||
test = True
|
test = True
|
||||||
|
|
||||||
if not stopLimit or stopLimit <= 1:
|
if stopLimit is None or stopLimit <= 1:
|
||||||
if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
|
if Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]):
|
||||||
test = False
|
test = False
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ class Metasploit(object):
|
|||||||
|
|
||||||
if Backend.isDbms(DBMS.MYSQL):
|
if Backend.isDbms(DBMS.MYSQL):
|
||||||
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
debugMsg = "by default MySQL on Windows runs as SYSTEM "
|
||||||
debugMsg += "user, it is likely that the the VNC "
|
debugMsg += "user, it is likely that the VNC "
|
||||||
debugMsg += "injection will be successful"
|
debugMsg += "injection will be successful"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -45,10 +45,12 @@ class Fingerprint(GenericFingerprint):
|
|||||||
# Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/
|
# Reference: https://dev.mysql.com/doc/relnotes/mysql/<major>.<minor>/en/
|
||||||
|
|
||||||
versions = (
|
versions = (
|
||||||
|
(80300, 80302), # MySQL 8.3
|
||||||
|
(80200, 80202), # MySQL 8.2
|
||||||
(80100, 80102), # MySQL 8.1
|
(80100, 80102), # MySQL 8.1
|
||||||
(80000, 80035), # MySQL 8.0
|
(80000, 80037), # MySQL 8.0
|
||||||
(60000, 60014), # MySQL 6.0
|
(60000, 60014), # MySQL 6.0
|
||||||
(50700, 50744), # MySQL 5.7
|
(50700, 50745), # MySQL 5.7
|
||||||
(50600, 50652), # MySQL 5.6
|
(50600, 50652), # MySQL 5.6
|
||||||
(50500, 50563), # MySQL 5.5
|
(50500, 50563), # MySQL 5.5
|
||||||
(50400, 50404), # MySQL 5.4
|
(50400, 50404), # MySQL 5.4
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ class Databases(object):
|
|||||||
|
|
||||||
if not isNoneValue(table):
|
if not isNoneValue(table):
|
||||||
db = safeSQLIdentificatorNaming(db)
|
db = safeSQLIdentificatorNaming(db)
|
||||||
table = safeSQLIdentificatorNaming(table, True)
|
table = safeSQLIdentificatorNaming(table, True).strip()
|
||||||
|
|
||||||
if conf.getComments:
|
if conf.getComments:
|
||||||
_ = queries[Backend.getIdentifiedDbms()].table_comment
|
_ = queries[Backend.getIdentifiedDbms()].table_comment
|
||||||
|
|||||||
@@ -134,12 +134,14 @@ class Entries(object):
|
|||||||
kb.dumpTable = "%s:%s" % (conf.db, tbl)
|
kb.dumpTable = "%s:%s" % (conf.db, tbl)
|
||||||
elif Backend.isDbms(DBMS.SQLITE):
|
elif Backend.isDbms(DBMS.SQLITE):
|
||||||
kb.dumpTable = tbl
|
kb.dumpTable = tbl
|
||||||
|
elif METADB_SUFFIX.upper() in conf.db.upper():
|
||||||
|
kb.dumpTable = tbl
|
||||||
else:
|
else:
|
||||||
kb.dumpTable = "%s.%s" % (conf.db, tbl)
|
kb.dumpTable = "%s.%s" % (conf.db, tbl)
|
||||||
|
|
||||||
if safeSQLIdentificatorNaming(conf.db) not in kb.data.cachedColumns or safeSQLIdentificatorNaming(tbl, True) not in kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
|
if safeSQLIdentificatorNaming(conf.db) not in kb.data.cachedColumns or safeSQLIdentificatorNaming(tbl, True) not in kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
|
||||||
warnMsg = "unable to enumerate the columns for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
warnMsg = "unable to enumerate the columns for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
if METADB_SUFFIX not in conf.db:
|
if METADB_SUFFIX.upper() not in conf.db.upper():
|
||||||
warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
warnMsg += ", skipping" if len(tblList) > 1 else ""
|
warnMsg += ", skipping" if len(tblList) > 1 else ""
|
||||||
logger.warning(warnMsg)
|
logger.warning(warnMsg)
|
||||||
@@ -154,7 +156,7 @@ class Entries(object):
|
|||||||
|
|
||||||
if not colList:
|
if not colList:
|
||||||
warnMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
warnMsg = "skipping table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
if METADB_SUFFIX not in conf.db:
|
if METADB_SUFFIX.upper() not in conf.db.upper():
|
||||||
warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
warnMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
warnMsg += " (no usable column names)"
|
warnMsg += " (no usable column names)"
|
||||||
logger.warning(warnMsg)
|
logger.warning(warnMsg)
|
||||||
@@ -168,7 +170,7 @@ class Entries(object):
|
|||||||
if conf.col:
|
if conf.col:
|
||||||
infoMsg += " of column(s) '%s'" % colNames
|
infoMsg += " of column(s) '%s'" % colNames
|
||||||
infoMsg += " for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
infoMsg += " for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
|
||||||
if METADB_SUFFIX not in conf.db:
|
if METADB_SUFFIX.upper() not in conf.db.upper():
|
||||||
infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|||||||
@@ -437,7 +437,7 @@ def main():
|
|||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
elif any(_ in errMsg for _ in (": 9.9.9#",)):
|
elif any(_ in errMsg for _ in (": 9.9.9#",)):
|
||||||
errMsg = "LOL :)"
|
errMsg = "LOL xD"
|
||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ def main():
|
|||||||
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true")
|
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true")
|
||||||
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true")
|
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true")
|
||||||
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS)
|
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS)
|
||||||
apiparser.add_argument("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int)
|
apiparser.add_argument("-p", "--port", help="Port of the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int)
|
||||||
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER)
|
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER)
|
||||||
apiparser.add_argument("--database", help="Set IPC database filepath (optional)")
|
apiparser.add_argument("--database", help="Set IPC database filepath (optional)")
|
||||||
apiparser.add_argument("--username", help="Basic authentication username (optional)")
|
apiparser.add_argument("--username", help="Basic authentication username (optional)")
|
||||||
|
|||||||
2
thirdparty/beautifulsoup/__init__.py
vendored
2
thirdparty/beautifulsoup/__init__.py
vendored
@@ -16,7 +16,7 @@
|
|||||||
# disclaimer in the documentation and/or other materials provided
|
# disclaimer in the documentation and/or other materials provided
|
||||||
# with the distribution.
|
# with the distribution.
|
||||||
#
|
#
|
||||||
# * Neither the name of the the Beautiful Soup Consortium and All
|
# * Neither the name of the Beautiful Soup Consortium and All
|
||||||
# Night Kosher Bakery nor the names of its contributors may be
|
# Night Kosher Bakery nor the names of its contributors may be
|
||||||
# used to endorse or promote products derived from this software
|
# used to endorse or promote products derived from this software
|
||||||
# without specific prior written permission.
|
# without specific prior written permission.
|
||||||
|
|||||||
10
thirdparty/beautifulsoup/beautifulsoup.py
vendored
10
thirdparty/beautifulsoup/beautifulsoup.py
vendored
@@ -58,7 +58,7 @@ met:
|
|||||||
disclaimer in the documentation and/or other materials provided
|
disclaimer in the documentation and/or other materials provided
|
||||||
with the distribution.
|
with the distribution.
|
||||||
|
|
||||||
* Neither the name of the the Beautiful Soup Consortium and All
|
* Neither the name of the Beautiful Soup Consortium and All
|
||||||
Night Kosher Bakery nor the names of its contributors may be
|
Night Kosher Bakery nor the names of its contributors may be
|
||||||
used to endorse or promote products derived from this software
|
used to endorse or promote products derived from this software
|
||||||
without specific prior written permission.
|
without specific prior written permission.
|
||||||
@@ -80,7 +80,7 @@ from __future__ import generators
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
__author__ = "Leonard Richardson (leonardr@segfault.org)"
|
__author__ = "Leonard Richardson (leonardr@segfault.org)"
|
||||||
__version__ = "3.2.1"
|
__version__ = "3.2.1b"
|
||||||
__copyright__ = "Copyright (c) 2004-2012 Leonard Richardson"
|
__copyright__ = "Copyright (c) 2004-2012 Leonard Richardson"
|
||||||
__license__ = "New-style BSD"
|
__license__ = "New-style BSD"
|
||||||
|
|
||||||
@@ -93,14 +93,16 @@ if sys.version_info >= (3, 0):
|
|||||||
text_type = str
|
text_type = str
|
||||||
binary_type = bytes
|
binary_type = bytes
|
||||||
basestring = str
|
basestring = str
|
||||||
|
unichr = chr
|
||||||
else:
|
else:
|
||||||
text_type = unicode
|
text_type = unicode
|
||||||
binary_type = str
|
binary_type = str
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from htmlentitydefs import name2codepoint
|
from html.entities import name2codepoint
|
||||||
except ImportError:
|
except ImportError:
|
||||||
name2codepoint = {}
|
from htmlentitydefs import name2codepoint
|
||||||
|
|
||||||
try:
|
try:
|
||||||
set
|
set
|
||||||
except NameError:
|
except NameError:
|
||||||
|
|||||||
424
thirdparty/bottle/bottle.py
vendored
424
thirdparty/bottle/bottle.py
vendored
@@ -69,7 +69,7 @@ if __name__ == '__main__':
|
|||||||
# Imports and Python 2/3 unification ##########################################
|
# Imports and Python 2/3 unification ##########################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import base64, calendar, cgi, email.utils, functools, hmac, itertools,\
|
import base64, calendar, email.utils, functools, hmac, itertools,\
|
||||||
mimetypes, os, re, tempfile, threading, time, warnings, weakref, hashlib
|
mimetypes, os, re, tempfile, threading, time, warnings, weakref, hashlib
|
||||||
|
|
||||||
from types import FunctionType
|
from types import FunctionType
|
||||||
@@ -94,6 +94,7 @@ if py3k:
|
|||||||
from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
|
from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
|
||||||
urlunquote = functools.partial(urlunquote, encoding='latin1')
|
urlunquote = functools.partial(urlunquote, encoding='latin1')
|
||||||
from http.cookies import SimpleCookie, Morsel, CookieError
|
from http.cookies import SimpleCookie, Morsel, CookieError
|
||||||
|
from collections import defaultdict
|
||||||
from collections.abc import MutableMapping as DictMixin
|
from collections.abc import MutableMapping as DictMixin
|
||||||
from types import ModuleType as new_module
|
from types import ModuleType as new_module
|
||||||
import pickle
|
import pickle
|
||||||
@@ -126,7 +127,7 @@ else: # 2.x
|
|||||||
from imp import new_module
|
from imp import new_module
|
||||||
from StringIO import StringIO as BytesIO
|
from StringIO import StringIO as BytesIO
|
||||||
import ConfigParser as configparser
|
import ConfigParser as configparser
|
||||||
from collections import MutableMapping as DictMixin
|
from collections import MutableMapping as DictMixin, defaultdict
|
||||||
from inspect import getargspec
|
from inspect import getargspec
|
||||||
|
|
||||||
unicode = unicode
|
unicode = unicode
|
||||||
@@ -1137,6 +1138,399 @@ class Bottle(object):
|
|||||||
# HTTP and WSGI Tools ##########################################################
|
# HTTP and WSGI Tools ##########################################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
# Multipart parsing stuff
|
||||||
|
|
||||||
|
class StopMarkupException(BottleException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
HYPHEN = tob('-')
|
||||||
|
CR = tob('\r')
|
||||||
|
LF = tob('\n')
|
||||||
|
CRLF = CR + LF
|
||||||
|
LFCRLF = LF + CR + LF
|
||||||
|
HYPHENx2 = HYPHEN * 2
|
||||||
|
CRLFx2 = CRLF * 2
|
||||||
|
CRLF_LEN = len(CRLF)
|
||||||
|
CRLFx2_LEN = len(CRLFx2)
|
||||||
|
|
||||||
|
MULTIPART_BOUNDARY_PATT = re.compile(r'^multipart/.+?boundary=(.+?)(;|$)')
|
||||||
|
|
||||||
|
class MPHeadersEaeter:
|
||||||
|
end_headers_patt = re.compile(tob(r'(\r\n\r\n)|(\r(\n\r?)?)$'))
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.headers_end_expected = None
|
||||||
|
self.eat_meth = self._eat_first_crlf_or_last_hyphens
|
||||||
|
self._meth_map = {
|
||||||
|
CR: self._eat_lf,
|
||||||
|
HYPHEN: self._eat_last_hyphen
|
||||||
|
}
|
||||||
|
self.stopped = False
|
||||||
|
|
||||||
|
def eat(self, chunk, base):
|
||||||
|
pos = self.eat_meth(chunk, base)
|
||||||
|
if pos is None: return
|
||||||
|
if self.eat_meth != self._eat_headers:
|
||||||
|
if self.stopped:
|
||||||
|
raise StopMarkupException()
|
||||||
|
base = pos
|
||||||
|
self.eat_meth = self._eat_headers
|
||||||
|
return self.eat(chunk, base)
|
||||||
|
# found headers section end, reset eater
|
||||||
|
self.eat_meth = self._eat_first_crlf_or_last_hyphens
|
||||||
|
return pos
|
||||||
|
|
||||||
|
def _eat_last_hyphen(self, chunk, base):
|
||||||
|
chunk_start = chunk[base: base + 2]
|
||||||
|
if not chunk_start: return
|
||||||
|
if chunk_start == HYPHEN:
|
||||||
|
self.stopped = True
|
||||||
|
return base + 1
|
||||||
|
raise HTTPError(422, 'Last hyphen was expected, got (first 2 symbols slice): %s' % chunk_start)
|
||||||
|
|
||||||
|
def _eat_lf(self, chunk, base):
|
||||||
|
chunk_start = chunk[base: base + 1]
|
||||||
|
if not chunk_start: return
|
||||||
|
if chunk_start == LF: return base + 1
|
||||||
|
invalid_sequence = CR + chunk_start
|
||||||
|
raise HTTPError(422, 'Malformed headers, found invalid sequence: %s' % invalid_sequence)
|
||||||
|
|
||||||
|
def _eat_first_crlf_or_last_hyphens(self, chunk, base):
|
||||||
|
chunk_start = chunk[base: base + 2]
|
||||||
|
if not chunk_start: return
|
||||||
|
if chunk_start == CRLF: return base + 2
|
||||||
|
if len(chunk_start) == 1:
|
||||||
|
self.eat_meth = self._meth_map.get(chunk_start)
|
||||||
|
elif chunk_start == HYPHENx2:
|
||||||
|
self.stopped = True
|
||||||
|
return base + 2
|
||||||
|
if self.eat_meth is None:
|
||||||
|
raise HTTPError(422, 'Malformed headers, invalid section start: %s' % chunk_start)
|
||||||
|
|
||||||
|
def _eat_headers(self, chunk, base):
|
||||||
|
expected = self.headers_end_expected
|
||||||
|
if expected is not None:
|
||||||
|
expected_len = len(expected)
|
||||||
|
chunk_start = chunk[base:expected_len]
|
||||||
|
if chunk_start == expected:
|
||||||
|
self.headers_end_expected = None
|
||||||
|
return base + expected_len - CRLFx2_LEN
|
||||||
|
chunk_start_len = len(chunk_start)
|
||||||
|
if not chunk_start_len: return
|
||||||
|
if chunk_start_len < expected_len:
|
||||||
|
if expected.startswith(chunk_start):
|
||||||
|
self.headers_end_expected = expected[chunk_start_len:]
|
||||||
|
return
|
||||||
|
self.headers_end_expected = None
|
||||||
|
if expected == LF: # we saw CRLFCR
|
||||||
|
invalid_sequence = CR + chunk_start[0:1]
|
||||||
|
# NOTE we don not catch all CRLF-malformed errors, but only obvious ones
|
||||||
|
# to stop doing useless work
|
||||||
|
raise HTTPError(422, 'Malformed headers, found invalid sequence: %s' % invalid_sequence)
|
||||||
|
else:
|
||||||
|
assert expected_len >= 2 # (CR)LFCRLF or (CRLF)CRLF
|
||||||
|
self.headers_end_expected = None
|
||||||
|
assert self.headers_end_expected is None
|
||||||
|
s = self.end_headers_patt.search(chunk, base)
|
||||||
|
if s is None: return
|
||||||
|
end_found = s.start(1)
|
||||||
|
if end_found >= 0: return end_found
|
||||||
|
end_head = s.group(2)
|
||||||
|
if end_head is not None:
|
||||||
|
self.headers_end_expected = CRLFx2[len(end_head):]
|
||||||
|
|
||||||
|
|
||||||
|
class MPBodyMarkup:
|
||||||
|
def __init__(self, boundary):
|
||||||
|
self.markups = []
|
||||||
|
self.error = None
|
||||||
|
if CR in boundary:
|
||||||
|
raise HTTPError(422, 'The `CR` must not be in the boundary: %s' % boundary)
|
||||||
|
boundary = HYPHENx2 + boundary
|
||||||
|
self.boundary = boundary
|
||||||
|
token = CRLF + boundary
|
||||||
|
self.tlen = len(token)
|
||||||
|
self.token = token
|
||||||
|
self.trest = self.trest_len = None
|
||||||
|
self.abspos = 0
|
||||||
|
self.abs_start_section = 0
|
||||||
|
self.headers_eater = MPHeadersEaeter()
|
||||||
|
self.cur_meth = self._eat_start_boundary
|
||||||
|
self._eat_headers = self.headers_eater.eat
|
||||||
|
self.stopped = False
|
||||||
|
self.idx = idx = defaultdict(list) # 1-based indices for each token symbol
|
||||||
|
for i, c in enumerate(token, start=1):
|
||||||
|
idx[c].append([i, token[:i]])
|
||||||
|
|
||||||
|
def _match_tail(self, s, start, end):
|
||||||
|
idxs = self.idx.get(s[end - 1])
|
||||||
|
if idxs is None: return
|
||||||
|
slen = end - start
|
||||||
|
assert slen <= self.tlen
|
||||||
|
for i, thead in idxs: # idxs is 1-based index
|
||||||
|
search_pos = slen - i
|
||||||
|
if search_pos < 0: return
|
||||||
|
if s[start + search_pos:end] == thead: return i # if s_tail == token_head
|
||||||
|
|
||||||
|
def _iter_markup(self, chunk):
|
||||||
|
if self.stopped:
|
||||||
|
raise StopMarkupException()
|
||||||
|
cur_meth = self.cur_meth
|
||||||
|
abs_start_section = self.abs_start_section
|
||||||
|
start_next_sec = 0
|
||||||
|
skip_start = 0
|
||||||
|
tlen = self.tlen
|
||||||
|
eat_data, eat_headers = self._eat_data, self._eat_headers
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
end_section = cur_meth(chunk, start_next_sec)
|
||||||
|
except StopMarkupException:
|
||||||
|
self.stopped = True
|
||||||
|
return
|
||||||
|
if end_section is None: break
|
||||||
|
if cur_meth == eat_headers:
|
||||||
|
sec_name = 'headers'
|
||||||
|
start_next_sec = end_section + CRLFx2_LEN
|
||||||
|
cur_meth = eat_data
|
||||||
|
skip_start = 0
|
||||||
|
elif cur_meth == eat_data:
|
||||||
|
sec_name = 'data'
|
||||||
|
start_next_sec = end_section + tlen
|
||||||
|
skip_start = CRLF_LEN
|
||||||
|
cur_meth = eat_headers
|
||||||
|
else:
|
||||||
|
assert cur_meth == self._eat_start_boundary
|
||||||
|
sec_name = 'data'
|
||||||
|
start_next_sec = end_section + tlen
|
||||||
|
skip_start = CRLF_LEN
|
||||||
|
cur_meth = eat_headers
|
||||||
|
|
||||||
|
# if the body starts with a hyphen,
|
||||||
|
# we will have a negative abs_end_section equal to the length of the CRLF
|
||||||
|
abs_end_section = self.abspos + end_section
|
||||||
|
if abs_end_section < 0:
|
||||||
|
assert abs_end_section == -CRLF_LEN
|
||||||
|
end_section = -self.abspos
|
||||||
|
yield sec_name, (abs_start_section, self.abspos + end_section)
|
||||||
|
abs_start_section = self.abspos + start_next_sec + skip_start
|
||||||
|
self.abspos += len(chunk)
|
||||||
|
self.cur_meth = cur_meth
|
||||||
|
self.abs_start_section = abs_start_section
|
||||||
|
|
||||||
|
def _eat_start_boundary(self, chunk, base):
|
||||||
|
if self.trest is None:
|
||||||
|
chunk_start = chunk[base: base + 1]
|
||||||
|
if not chunk_start: return
|
||||||
|
if chunk_start == CR: return self._eat_data(chunk, base)
|
||||||
|
boundary = self.boundary
|
||||||
|
if chunk.startswith(boundary): return base - CRLF_LEN
|
||||||
|
if chunk_start != boundary[:1]:
|
||||||
|
raise HTTPError(
|
||||||
|
422, 'Invalid multipart/formdata body start, expected hyphen or CR, got: %s' % chunk_start)
|
||||||
|
self.trest = boundary
|
||||||
|
self.trest_len = len(boundary)
|
||||||
|
end_section = self._eat_data(chunk, base)
|
||||||
|
if end_section is not None: return end_section
|
||||||
|
|
||||||
|
def _eat_data(self, chunk, base):
|
||||||
|
chunk_len = len(chunk)
|
||||||
|
token, tlen, trest, trest_len = self.token, self.tlen, self.trest, self.trest_len
|
||||||
|
start = base
|
||||||
|
match_tail = self._match_tail
|
||||||
|
part = None
|
||||||
|
while True:
|
||||||
|
end = start + tlen
|
||||||
|
if end > chunk_len:
|
||||||
|
part = chunk[start:]
|
||||||
|
break
|
||||||
|
if trest is not None:
|
||||||
|
if chunk[start:start + trest_len] == trest:
|
||||||
|
data_end = start + trest_len - tlen
|
||||||
|
self.trest_len = self.trest = None
|
||||||
|
return data_end
|
||||||
|
else:
|
||||||
|
trest_len = trest = None
|
||||||
|
matched_len = match_tail(chunk, start, end)
|
||||||
|
if matched_len is not None:
|
||||||
|
if matched_len == tlen:
|
||||||
|
self.trest_len = self.trest = None
|
||||||
|
return start
|
||||||
|
else:
|
||||||
|
trest_len, trest = tlen - matched_len, token[matched_len:]
|
||||||
|
start += tlen
|
||||||
|
# process the tail of the chunk
|
||||||
|
if part:
|
||||||
|
part_len = len(part)
|
||||||
|
if trest is not None:
|
||||||
|
if part_len < trest_len:
|
||||||
|
if trest.startswith(part):
|
||||||
|
trest_len -= part_len
|
||||||
|
trest = trest[part_len:]
|
||||||
|
part = None
|
||||||
|
else:
|
||||||
|
trest_len = trest = None
|
||||||
|
else:
|
||||||
|
if part.startswith(trest):
|
||||||
|
data_end = start + trest_len - tlen
|
||||||
|
self.trest_len = self.trest = None
|
||||||
|
return data_end
|
||||||
|
trest_len = trest = None
|
||||||
|
|
||||||
|
if part is not None:
|
||||||
|
assert trest is None
|
||||||
|
matched_len = match_tail(part, 0, part_len)
|
||||||
|
if matched_len is not None:
|
||||||
|
trest_len, trest = tlen - matched_len, token[matched_len:]
|
||||||
|
self.trest_len, self.trest = trest_len, trest
|
||||||
|
|
||||||
|
def _parse(self, chunk):
|
||||||
|
for name, start_end in self._iter_markup(chunk):
|
||||||
|
self.markups.append([name, start_end])
|
||||||
|
|
||||||
|
def parse(self, chunk):
|
||||||
|
if self.error is not None: return
|
||||||
|
try:
|
||||||
|
self._parse(chunk)
|
||||||
|
except Exception as exc:
|
||||||
|
self.error = exc
|
||||||
|
|
||||||
|
|
||||||
|
class MPBytesIOProxy:
|
||||||
|
def __init__(self, src, start, end):
|
||||||
|
self._src = src
|
||||||
|
self._st = start
|
||||||
|
self._end = end
|
||||||
|
self._pos = start
|
||||||
|
|
||||||
|
def tell(self):
|
||||||
|
return self._pos - self._st
|
||||||
|
|
||||||
|
def seek(self, pos):
|
||||||
|
if pos < 0: pos = 0
|
||||||
|
self._pos = min(self._st + pos, self._end)
|
||||||
|
|
||||||
|
def read(self, sz=None):
|
||||||
|
max_sz = self._end - self._pos
|
||||||
|
if max_sz <= 0:
|
||||||
|
return tob('')
|
||||||
|
if sz is not None and sz > 0:
|
||||||
|
sz = min(sz, max_sz)
|
||||||
|
else:
|
||||||
|
sz = max_sz
|
||||||
|
self._src.seek(self._pos)
|
||||||
|
self._pos += sz
|
||||||
|
return self._src.read(sz)
|
||||||
|
|
||||||
|
def writable(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def fileno(self):
|
||||||
|
raise OSError('Not supported')
|
||||||
|
|
||||||
|
def closed(self):
|
||||||
|
return self._src.closed()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MPHeader:
|
||||||
|
def __init__(self, name, value, options):
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
self.options = options
|
||||||
|
|
||||||
|
|
||||||
|
class MPFieldStorage:
|
||||||
|
|
||||||
|
_patt = re.compile(tonat('(.+?)(=(.+?))?(;|$)'))
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.name = None
|
||||||
|
self.value = None
|
||||||
|
self.filename = None
|
||||||
|
self.file = None
|
||||||
|
self.ctype = None
|
||||||
|
self.headers = {}
|
||||||
|
|
||||||
|
def read(self, src, headers_section, data_section, max_read):
|
||||||
|
start, end = headers_section
|
||||||
|
sz = end - start
|
||||||
|
has_read = sz
|
||||||
|
if has_read > max_read:
|
||||||
|
raise HTTPError(413, 'Request entity too large')
|
||||||
|
src.seek(start)
|
||||||
|
headers_raw = tonat(src.read(sz))
|
||||||
|
for header_raw in headers_raw.splitlines():
|
||||||
|
header = self.parse_header(header_raw)
|
||||||
|
self.headers[header.name] = header
|
||||||
|
if header.name == 'Content-Disposition':
|
||||||
|
self.name = header.options['name']
|
||||||
|
self.filename = header.options.get('filename')
|
||||||
|
elif header.name == 'Content-Type':
|
||||||
|
self.ctype = header.value
|
||||||
|
if self.name is None:
|
||||||
|
raise HTTPError(422, 'Noname field found while parsing multipart/formdata body: %s' % header_raw)
|
||||||
|
if self.filename is not None:
|
||||||
|
self.file = MPBytesIOProxy(src, *data_section)
|
||||||
|
else:
|
||||||
|
start, end = data_section
|
||||||
|
sz = end - start
|
||||||
|
if sz:
|
||||||
|
has_read += sz
|
||||||
|
if has_read > max_read:
|
||||||
|
raise HTTPError(413, 'Request entity too large')
|
||||||
|
src.seek(start)
|
||||||
|
self.value = tonat(src.read(sz))
|
||||||
|
else:
|
||||||
|
self.value = ''
|
||||||
|
return has_read
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse_header(cls, s):
|
||||||
|
htype, rest = s.split(':', 1)
|
||||||
|
opt_iter = cls._patt.finditer(rest)
|
||||||
|
hvalue = next(opt_iter).group(1).strip()
|
||||||
|
dct = {}
|
||||||
|
for it in opt_iter:
|
||||||
|
k = it.group(1).strip()
|
||||||
|
v = it.group(3)
|
||||||
|
if v is not None:
|
||||||
|
v = v.strip('"')
|
||||||
|
dct[k.lower()] = v
|
||||||
|
return MPHeader(name=htype, value=hvalue, options=dct)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def iter_items(cls, src, markup, max_read):
|
||||||
|
iter_markup = iter(markup)
|
||||||
|
# check & skip empty data (body should start from empty data)
|
||||||
|
null_data = next(iter_markup, None)
|
||||||
|
if null_data is None: return
|
||||||
|
sec_name, [start, end] = null_data
|
||||||
|
assert sec_name == 'data'
|
||||||
|
if end > 0:
|
||||||
|
raise HTTPError(
|
||||||
|
422, 'Malformed multipart/formdata, unexpected data before the first boundary at: [%d:%d]'
|
||||||
|
% (start, end))
|
||||||
|
headers = next(iter_markup, None)
|
||||||
|
data = next(iter_markup, None)
|
||||||
|
while headers:
|
||||||
|
sec_name, headers_slice = headers
|
||||||
|
assert sec_name == 'headers'
|
||||||
|
if not data:
|
||||||
|
raise HTTPError(
|
||||||
|
422, 'Malformed multipart/formdata, no data found for the field at: [%d:%d]'
|
||||||
|
% tuple(headers_slice))
|
||||||
|
sec_name, data_slice = data
|
||||||
|
assert sec_name == 'data'
|
||||||
|
field = cls()
|
||||||
|
has_read = field.read(src, headers_slice, data_slice, max_read=max_read)
|
||||||
|
max_read -= has_read
|
||||||
|
yield field
|
||||||
|
headers = next(iter_markup, None)
|
||||||
|
data = next(iter_markup, None)
|
||||||
|
|
||||||
|
|
||||||
class BaseRequest(object):
|
class BaseRequest(object):
|
||||||
""" A wrapper for WSGI environment dictionaries that adds a lot of
|
""" A wrapper for WSGI environment dictionaries that adds a lot of
|
||||||
@@ -1326,6 +1720,10 @@ class BaseRequest(object):
|
|||||||
|
|
||||||
@DictProperty('environ', 'bottle.request.body', read_only=True)
|
@DictProperty('environ', 'bottle.request.body', read_only=True)
|
||||||
def _body(self):
|
def _body(self):
|
||||||
|
mp_markup = None
|
||||||
|
mp_boundary_match = MULTIPART_BOUNDARY_PATT.match(self.environ.get('CONTENT_TYPE', ''))
|
||||||
|
if mp_boundary_match is not None:
|
||||||
|
mp_markup = MPBodyMarkup(tob(mp_boundary_match.group(1)))
|
||||||
try:
|
try:
|
||||||
read_func = self.environ['wsgi.input'].read
|
read_func = self.environ['wsgi.input'].read
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@@ -1335,12 +1733,15 @@ class BaseRequest(object):
|
|||||||
body, body_size, is_temp_file = BytesIO(), 0, False
|
body, body_size, is_temp_file = BytesIO(), 0, False
|
||||||
for part in body_iter(read_func, self.MEMFILE_MAX):
|
for part in body_iter(read_func, self.MEMFILE_MAX):
|
||||||
body.write(part)
|
body.write(part)
|
||||||
|
if mp_markup is not None:
|
||||||
|
mp_markup.parse(part)
|
||||||
body_size += len(part)
|
body_size += len(part)
|
||||||
if not is_temp_file and body_size > self.MEMFILE_MAX:
|
if not is_temp_file and body_size > self.MEMFILE_MAX:
|
||||||
body, tmp = NamedTemporaryFile(mode='w+b'), body
|
body, tmp = NamedTemporaryFile(mode='w+b'), body
|
||||||
body.write(tmp.getvalue())
|
body.write(tmp.getvalue())
|
||||||
del tmp
|
del tmp
|
||||||
is_temp_file = True
|
is_temp_file = True
|
||||||
|
body.multipart_markup = mp_markup
|
||||||
self.environ['wsgi.input'] = body
|
self.environ['wsgi.input'] = body
|
||||||
body.seek(0)
|
body.seek(0)
|
||||||
return body
|
return body
|
||||||
@@ -1378,7 +1779,7 @@ class BaseRequest(object):
|
|||||||
def POST(self):
|
def POST(self):
|
||||||
""" The values of :attr:`forms` and :attr:`files` combined into a single
|
""" The values of :attr:`forms` and :attr:`files` combined into a single
|
||||||
:class:`FormsDict`. Values are either strings (form values) or
|
:class:`FormsDict`. Values are either strings (form values) or
|
||||||
instances of :class:`cgi.FieldStorage` (file uploads).
|
instances of :class:`MPBytesIOProxy` (file uploads).
|
||||||
"""
|
"""
|
||||||
post = FormsDict()
|
post = FormsDict()
|
||||||
# We default to application/x-www-form-urlencoded for everything that
|
# We default to application/x-www-form-urlencoded for everything that
|
||||||
@@ -1389,18 +1790,15 @@ class BaseRequest(object):
|
|||||||
post[key] = value
|
post[key] = value
|
||||||
return post
|
return post
|
||||||
|
|
||||||
safe_env = {'QUERY_STRING': ''} # Build a safe environment for cgi
|
|
||||||
for key in ('REQUEST_METHOD', 'CONTENT_TYPE', 'CONTENT_LENGTH'):
|
|
||||||
if key in self.environ: safe_env[key] = self.environ[key]
|
|
||||||
args = dict(fp=self.body, environ=safe_env, keep_blank_values=True)
|
|
||||||
|
|
||||||
if py3k:
|
if py3k:
|
||||||
args['encoding'] = 'utf8'
|
|
||||||
post.recode_unicode = False
|
post.recode_unicode = False
|
||||||
data = cgi.FieldStorage(**args)
|
body = self.body
|
||||||
self['_cgi.FieldStorage'] = data #http://bugs.python.org/issue18394
|
markup = body.multipart_markup
|
||||||
data = data.list or []
|
if markup is None:
|
||||||
for item in data:
|
raise HTTPError(400, '`boundary` required for mutlipart content')
|
||||||
|
elif markup.error is not None:
|
||||||
|
raise markup.error
|
||||||
|
for item in MPFieldStorage.iter_items(body, markup.markups, self.MEMFILE_MAX):
|
||||||
if item.filename is None:
|
if item.filename is None:
|
||||||
post[item.name] = item.value
|
post[item.name] = item.value
|
||||||
else:
|
else:
|
||||||
|
|||||||
4
thirdparty/colorama/ansitowin32.py
vendored
4
thirdparty/colorama/ansitowin32.py
vendored
@@ -243,6 +243,6 @@ class AnsiToWin32(object):
|
|||||||
# 0 - change title and icon (we will only change title)
|
# 0 - change title and icon (we will only change title)
|
||||||
# 1 - change icon (we don't support this)
|
# 1 - change icon (we don't support this)
|
||||||
# 2 - change title
|
# 2 - change title
|
||||||
if params[0] in '02':
|
# if params[0] in '02':
|
||||||
winterm.set_title(params[1])
|
# winterm.set_title(params[1])
|
||||||
return text
|
return text
|
||||||
|
|||||||
16
thirdparty/socks/socks.py
vendored
16
thirdparty/socks/socks.py
vendored
@@ -185,23 +185,23 @@ class socksocket(socket.socket):
|
|||||||
# We'll receive the server's response to determine which
|
# We'll receive the server's response to determine which
|
||||||
# method was selected
|
# method was selected
|
||||||
chosenauth = self.__recvall(2)
|
chosenauth = self.__recvall(2)
|
||||||
if chosenauth[0:1] != chr(0x05).encode():
|
if chosenauth[0:1] != b'\x05':
|
||||||
self.close()
|
self.close()
|
||||||
raise GeneralProxyError((1, _generalerrors[1]))
|
raise GeneralProxyError((1, _generalerrors[1]))
|
||||||
# Check the chosen authentication method
|
# Check the chosen authentication method
|
||||||
if chosenauth[1:2] == chr(0x00).encode():
|
if chosenauth[1:2] == b'\x00':
|
||||||
# No authentication is required
|
# No authentication is required
|
||||||
pass
|
pass
|
||||||
elif chosenauth[1:2] == chr(0x02).encode():
|
elif chosenauth[1:2] == b'\x02':
|
||||||
# Okay, we need to perform a basic username/password
|
# Okay, we need to perform a basic username/password
|
||||||
# authentication.
|
# authentication.
|
||||||
self.sendall(chr(0x01).encode() + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr(len(self.__proxy[5])).encode() + self.__proxy[5].encode())
|
self.sendall(b'\x01' + chr(len(self.__proxy[4])).encode() + self.__proxy[4].encode() + chr(len(self.__proxy[5])).encode() + self.__proxy[5].encode())
|
||||||
authstat = self.__recvall(2)
|
authstat = self.__recvall(2)
|
||||||
if authstat[0:1] != chr(0x01).encode():
|
if authstat[0:1] != b'\x01':
|
||||||
# Bad response
|
# Bad response
|
||||||
self.close()
|
self.close()
|
||||||
raise GeneralProxyError((1, _generalerrors[1]))
|
raise GeneralProxyError((1, _generalerrors[1]))
|
||||||
if authstat[1:2] != chr(0x00).encode():
|
if authstat[1:2] != b'\x00':
|
||||||
# Authentication failed
|
# Authentication failed
|
||||||
self.close()
|
self.close()
|
||||||
raise Socks5AuthError((3, _socks5autherrors[3]))
|
raise Socks5AuthError((3, _socks5autherrors[3]))
|
||||||
@@ -209,7 +209,7 @@ class socksocket(socket.socket):
|
|||||||
else:
|
else:
|
||||||
# Reaching here is always bad
|
# Reaching here is always bad
|
||||||
self.close()
|
self.close()
|
||||||
if chosenauth[1] == chr(0xFF).encode():
|
if chosenauth[1:2] == b'\xff':
|
||||||
raise Socks5AuthError((2, _socks5autherrors[2]))
|
raise Socks5AuthError((2, _socks5autherrors[2]))
|
||||||
else:
|
else:
|
||||||
raise GeneralProxyError((1, _generalerrors[1]))
|
raise GeneralProxyError((1, _generalerrors[1]))
|
||||||
@@ -219,7 +219,7 @@ class socksocket(socket.socket):
|
|||||||
# use the IPv4 address request even if remote resolving was specified.
|
# use the IPv4 address request even if remote resolving was specified.
|
||||||
try:
|
try:
|
||||||
ipaddr = socket.inet_aton(destaddr)
|
ipaddr = socket.inet_aton(destaddr)
|
||||||
req = req + chr(0x01).encode() + ipaddr
|
req = req + b'\x01' + ipaddr
|
||||||
except socket.error:
|
except socket.error:
|
||||||
# Well it's not an IP number, so it's probably a DNS name.
|
# Well it's not an IP number, so it's probably a DNS name.
|
||||||
if self.__proxy[3]:
|
if self.__proxy[3]:
|
||||||
|
|||||||
Reference in New Issue
Block a user